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" | |
} | |
} |