Meteor server method hangs on mongo db update

We have seen a problem after upgrading meteor from version 1.3 -> 1.4 and 1.5.

The application breaks/hangs when calling Meteor.call(). We have tracked down the problem to a write in the mongodb that never completes.

So we have seen that the DDP stream from the client is received on the server. However, when its in some place should write to the db it never finishes.

We found the following explanation of Meteor methods:

Method calls can affect data that the client is subscribed to. Once the server has finished sending the client all the relevant data messages based on this procedure call, the server should send an updated message to the client with this method’s ID.

So what is happening here is that the server never send the ‘updated’ message and the application gets stuck,

Any ideas what this problem could be caused by? It was introduced on the upgrade when both upgrading the mongo db to 3.2 with WiredTiger and lifting to meteor 1.4 (and we also test 1.5 and problem occurs there as well)

Could you post the method where the DB update is not working?

Hi the method is quite long so it would not be possible not post the entire method but what it basically does is the following. It spawns a child_process, attaches stdin/stdout/sterr streams to log to the database using vsivsi:file-collection@1.3.8. It also attached an event for ‘onExit’ which will handle the result when the child process is finished. Note, the method itself is asynchronous since when it has spawned the child process it will return. The code can be seen below but I have tried to make a summary of it so bear in mind that this is not the complete code:

Meteor.methods({
startMyChildProcess: function(requestId) {
let fence = DDPServer._CurrentWriteFence.get(); // Track the DDP outstanding writes to find where it locks
console.log("OUTSTANDING WRITES ON METHOD START: " + fence.outstanding_writes);

const MyObj = {};
const childProcess = ChildProcess.spawn(getCommand().executable, getCommand().args);

//Store stdout/stderr
MyObj.stdout = “”;
childProcess.stdout.on(‘data’, (chunk) =>MyObj.stdout += chunk.toString());
MyObj.stderr = “”;
childProcess.stderr.on(‘data’, (chunk) => MyObj.stderr += chunk.toString());

//Create ways to wait for data
this.waitForStdout = new Future();
this.waitForStderr = new Future();
childProcess.stdout.on(‘end’, () => self.waitForStdout.return());
childProcess.stderr.on(‘end’, () => self.waitForStderr.return());
childProcess.stdout.on(‘error’, () => self.waitForStdout.throw());
childProcess.stderr.on(‘error’, () => self.waitForStderr.throw());

let fence = DDPServer._CurrentWriteFence.get();
//Pipe stdin, stdout and stderr to mongodb
childProcess.stderr.pipe(this.getMongoDbStderrStream(requestId)); // Using the filecollection
childProcess.stdout.pipe(this.getMongoDbStdoutStream(requestId)); // Using the filecollection
childProcess.stdin.pipe(this.getMongoDbStdinStream(requestId)); // Using the filecollection

getInputStream.pipe(childProcess.stdin);
//Attach process exit callback
childProcess.on(‘exit’, Meteor.bindEnvironment(function (code, signal) {
self.waitForStdout.wait();
self.waitForStderr.wait();

//handle result
}

console.log("OUTSTANDING WRITES ON METHOD END: " + fence.outstanding_writes);

} // method end

Sometimes, and it is very random when since happens. The server never sends back the “updated” DDP message. As you can see I inserted debugging to get the current write fence and outputting the outstanding_writes. If the method has returned and outstanding_writes is 0, then the server should send the “updated” message. BUT it never does which leaves the client hanging waiting for the method to fully return.

Always when this happens. The method has returned with fence.outstanding_writed = 0. BUT if I call the method again from the client console I can see that it has ONE outstanding_writes when entering the method.