Async functions in meteor server


#1

I’m using vpulim:node-soap to have a soap server running.

My meteor server startup contains this amongst various other code:

 authRequestOperation: function(args,cb,headers,req) {
          console.log(args);
          var authResponceObject = {};
          var futureAuthResponse = new Future();
          Fiber(function(){
            if(collectorUsers.findOne({username: args.username})){
              console.log("Found User");
              authResponceObject = {
                username: args.username,
                nonce: Random.id()
              };
              console.log("authResponceObject is: " + JSON.stringify(authResponceObject,null,4));
              console.log("futureAuthResponse returning...");
              futureAuthResponse.return(authResponceObject);
            }
            // console.log("futureAuthResponse waiting...");
            // return futureAuthResponse.wait();


          }).run();
          console.log("authResponceObject after fiber is: " + JSON.stringify(authResponceObject,null,4));
          return authResponceObject;
      },

What I’m trying to do is:

  1. I receive a user object from client.
  2. I check if the user is present in the mongodb
  3. If user is present, prepare response object
  4. Respond to the client with the response object.

I have 1. working. However, the dute it being async call, the order of 2,3,4 is messed up.

Right now what’s happening is:

  1. receive client object
  2. return response object (which is empty)
  3. Check mongo
  4. Prepare response object.

I’m not using Meteor.methods for the above.
How do I make this work in the right manner? I’ve tried juggling around wrapAsync and fiber/future but hitting dead ends.

SO Quesion here…


#2

Have you considered

  • using the Meteor zardak:soap package which wraps (a slightly earlier version of) node-soap, or
  • cloning and updating that package (if there are features in the later releases you need),
  • or looking at how node-soap is wrapped in that package if you prefer to use the canonical npm package?

#3

Thanks rob. The current node package works. There is nothing really wrong with it as such. I’m having trouble with the whole async function stuff. I’m not sure how to make it the function wait until the response object is actually created.

What’s happening is that the function calls upon the mongo and simply moves forward to the next line and returns an empty object. I’m just trying to find a way to make the async function calls work in a synchronous manner.


#4

Yeah - the point I was trying to make was that presumably the meteor package solves that problem.

However, if this is in a listen callback, the answer is likely to just wrap that and then forget about trying to use Fibers/futures in your code as it will already be in a fiber:

authRequestOperation: function(args, cb, headers, req) {
  var authResponceObject = {};
  var futureAuthResponse = new Future();
  if (collectorUsers.findOne({ username: args.username })) {
    authResponceObject = {
      username: args.username,
      nonce: Random.id()
    };
  }
  return authResponceObject;
},

#5

It didn’t work. Here’s what happened when I tried:


          authRequestOperation: function(args, cb, headers, req) {
            var authResponceObject = {};
            var futureAuthResponse = new Future();
            console.log("Before mongo");
            if (collectorUsers.findOne({ username: args.username })) {
              authResponceObject = {
                username: args.username,
                nonce: Random.id()
              };
            }
            console.log("After mongo");
            return authResponceObject;
          },

Output: Before mongo.

Nothing proceeded after that.

Here is my current implementation, however I still am getting it run in an async fashion:

     authRequestOperation: function(args, cb, headers, req) {
                  console.log(args);
                  var authResponceObject = {};
                  var futureCheck = new Future();

                  Fiber( function(){
                  if (collectorUsers.findOne({username: args.username})) {
                    console.log("Found User");
                    authResponceObject = {
                      username: args.username,
                      nonce: Random.id()
                    };
                    console.log("authResponceObject is: " + JSON.stringify(authResponceObject, null, 4));
                    futureCheck.return(authResponceObject);
                  }else {
                    return futureCheck.wait();
                    // futureCheck.return("ERROR");
                  }

                }).run();

                  console.log("authResponceObject after Fiber run is : " + JSON.stringify(authResponceObject,null,4));
                  return authResponceObject;

                },

Result of this being:

I20161201-15:09:12.389(5.5)? { username: 'admin' }
I20161201-15:09:12.390(5.5)? authResponceObject after Fiber run is : {}
I20161201-15:09:12.391(5.5)? Found User
I20161201-15:09:12.392(5.5)? authResponceObject is: {
I20161201-15:09:12.393(5.5)?     "username": "admin",
I20161201-15:09:12.393(5.5)?     "nonce": "r8HoENAC5tuCLWwow"
I20161201-15:09:12.393(5.5)? }

#6

Did you wrap the listen in a Meteor.wrapAsync?