Are ordinary functions blocking in meteor?

Are ordinary functions blocking in meteor? Consider the function below. If two users access at around the same time, I get

E11000 duplicate key error collection: srs-3_meteor_com.users index: username_1 dup key

That led me to think that, both users checked Meteor.users.findOne at same time, both returning undefined/null, thus user not existing yet. Then both go through and have a race for Meteor.users.insert, in which case, an error is going to occur, whoever is first. Probably, the fibre only guarantees blocking for db ops.

function insert_or_update_moodle_user(login_request) {
check(login_request.lms_id, String);
check(login_request.lms_role, String);
check(login_request.lms_course_id, String);

let username = `moodle-${login_request.lms_id}`;
let user = Meteor.users.findOne({username: username, 'profile.type': 'moodle'});


// todo: if someohow moodle-<username> was used already, append an incrementor on it based on number of duplicates.

 * If user does not exist, create that user. Otherwise,
 * update the user's current course and lms_role.
if (!user) {
        username: username,
        password: Meteor.uuid(),  // Generate random password. Not to be used for logging, but Meteor requires this.

        // LMS specific data.
        profile: {
            type: 'moodle',
            lms_id: login_request.lms_id,
            lms_role: login_request.lms_role,
            lms_current_course: login_request.lms_course_id

    console.log(username + ' inserted');
} else {
        username: username,
        'profile.type': 'moodle'
    }, {
        $set: {
            'profile.lms_current_course': login_request.lms_course_id,
            'profile.lms_role': login_request.lms_role

// Get the created/updated user.
return Meteor.users.findOne({username: username, 'profile.type': 'moodle'});


Nothing is blocking in Meteor. Fibers are actually a way of making synchronous code non-blocking. Methods from two different clients can easily execute in parallel.

So how can I “place mutex” around it? Will wrapping in Meteor.methods solve it? I’m confused.

This is a very similar thread, I’d suggest reading it:

Basically, since you’re going to be running multiple servers of your application and MongoDB doesn’t have transactions, it’s hard to guarantee a lock, but it can be done with some clever programming.

1 Like

My code is running in, so that is multiple servers? One more thing, that function is not being executed via ddp call, but rather via server side route from another web app. After creating/updating user, I then redirect the client, where there I do loginWithToken.

Nevermind, I got it. I was just staring at the method in meteor/livedata_server.js line 627, in which the transaction was wrapped in DDPServer._WriteFence. For the life of me, I was searching in github on the point of this code, I can’t find it. I asked the question if wrapping in in Meteor.methods/call, cause I thought this code was related to that, but it seems like its not.

On the other hand, is not wrapped by this DDPServer._WriteFence at all, which seems like a shame.

Anywayz, I’ve looked at account-pasword, and in there, discovered that Account.insertUserDoc (or something), wrap the insert in a try/catch, proving further that interlacing between these can occur.

In conclusion, I have stolen the CREATE USER section in account-password package.

Edit: After reading further:

DDPServer._WriteFence is established inside Session.method call, in which is created for every user transaction. Thus,

(Client) =>
(Server) new Session => This creates a queue of messages (methods), wrapped in Fiber. =>
Each execution of messages are establish DDPServer._WriteFence, also setting Meteor.Environment DDPServer._WriteFence instance =>
Any transaction to mongo db transaction check if this Meteor.Environment is set, if so, DDPServer._WriteFence’s will be utilized to lock the transaction.

In my NEW CONCLUSION, from client is guaranteed to be race free. Server on the other hand just directly calls (which I assume is the same as Since no DDPServer._WriteFence in that code, race condition could occur.

1 Like