Skip to content

Instantly share code, notes, and snippets.

@jwalton
Created September 16, 2013 01:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jwalton/6575901 to your computer and use it in GitHub Desktop.
Save jwalton/6575901 to your computer and use it in GitHub Desktop.
Demonstration of mongoose streaming + longjohn causing sadness

To reproduce:

  • Copy the files below
  • npm install
  • ./node_modules/.bin/coffee app.coffee

Set "repoProblem" to true to make the problem happen, and to false to make the app run WAY faster and not run out of memory. :)

repoProblem = false
if repoProblem
longjohn = require 'longjohn'
ProgressBar = require 'progress'
mongoose = require 'mongoose'
Schema = mongoose.Schema
ObjectId = Schema.ObjectId
OBJECTS_TO_CREATE = 40000
# Define our schemas
ASchema = new Schema
_id: false
d: { type: ObjectId }
e: { type: String }
BSchema = new Schema
a: { type: String }
b: { type: String, enum: ['a','b'] }
date: { type: Date, default: Date.now }
date2: { type: Date }
k: [ ASchema ]
# Connect to mongo
mongoose.connect 'mongodb://localhost/mongooseProblem'
mongoose.connection.on 'error', (err) ->
console.log 'Error: unable to connect to mongodb', err
process.exit 1
connection = mongoose.createConnection 'mongodb://localhost/mongooseProblem'
B = connection.model "b", BSchema
progressBar = new ProgressBar ':bar (:current/:total) :percent eta: :eta', {total: OBJECTS_TO_CREATE, width: 30}
lastObjects = []
# Create some objects
createObject = (index) ->
if index is 0
console.log "Creating objects"
k = []
for lastObject in lastObjects
k.push {
d: lastObject._id
e: "e-#{index}"
}
b = new B {
a: "Object: #{index}"
b: "b"
date: Date.now()
date2: Date.now() - (1000 * 60 * 4)
k: k
}
b.save (err, result) ->
progressBar.tick()
lastObjects.push result
while lastObjects.length > 3
lastObjects.shift()
if err
console.log "Error creating object", err
process.exit 1
else
if index < OBJECTS_TO_CREATE
process.nextTick () -> createObject index + 1
else
readObjects()
# Kick things off
createObject 0
# Stream the objects back from the db
readObjects = () ->
B.count {}, (countErr, totalObjects) ->
if countErr
console.log "Error counting objects", countErr
process.exit 1
progressBar = new ProgressBar ':bar (:current/:total) :percent eta: :eta', {total: totalObjects, width: 30}
console.log "Found #{totalObjects} objects"
# Line X
cursor = B.find()
stream = cursor.stream()
objectIndex = 0
err = null
collectionName = B.collection.name
stream.on 'data', (object) ->
# Line Y
stream.pause()
process.nextTick ->
# Here's where we'd do something useful with the object. Lalala...
progressBar.tick()
stream.resume()
stream.on 'error', (streamError) ->
err = streamError
stream.destroy()
stream.on 'close', ->
if err
console.log err
console.log "All done!"
process.exit 0
{
"name": "jwalton-mongoose-problem",
"version": "0.1.1",
"private": true,
"dependencies": {
"progress": "1.0.1",
"mongoose": "3.6.19",
"mongodb": "1.3.19",
"coffee-script": "1.6.3",
"longjohn": "0.2.1"
},
"engines": {
"node": "0.8.16",
"npm": "1.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment