4

I'm trying to deploy my meteor app onto the server but it always has this error on my meteor server log

Fri Jun 21 2013 11:39:31 GMT+0000 (UTC)] INFO HIT /img/bg.png
183.90.41.21 [Fri Jun 21 2013 11:39:32 GMT+0000 (UTC)] INFO HIT /favicon.ico 183.90.41.21 [Fri Jun 21 2013 11:39:41 GMT+0000 (UTC)] INFO HIT /form 183.90.41.21 [Fri Jun 21 2013 11:39:42 GMT+0000 (UTC)] INFO HIT /favicon.ico 183.90.41.21 [Fri Jun 21 2013 11:39:49 GMT+0000 (UTC)] WARNING           }).run();
             ^ [Fri Jun 21 2013 11:39:49 GMT+0000 (UTC)] WARNING app/server/server.js:53 [Fri Jun 21 2013 11:39:49 GMT+0000 (UTC)] WARNING Error: Meteor code must always run within a Fiber
    at _.extend.get (app/packages/meteor/dynamics_nodejs.js:14:13)
    at _.extend.apply (app/packages/livedata/livedata_server.js:1268:57)
    at _.extend.call (app/packages/livedata/livedata_server.js:1229:17)
    at Meteor.startup.Meteor.methods.streamTwit (app/server/server.js:51:22)

but I have already wrapped it within Fiber and it works well locally. I really do not know what could be the problem. Appreciate if anyone can help.

//server.js

Meteor.startup(function () {
    var require = Npm.require;
    var fs = require('fs');
    var path = require('path');
    var base = path.resolve('.');
    var isBundle = fs.existsSync(base + '/bundle');
    var modulePath = base + (isBundle ? '/bundle/static' : '/public') + '/node_modules';

    var ntwitter = require(modulePath + '/ntwitter');
    var Fiber = require(modulePath + '/fibers');

    var twit = new ntwitter({
      consumer_key: 'my key',
      consumer_secret: 'my key',
      access_token_key: 'my key',
      access_token_secret: 'my key'
    });

  Meteor.methods({
      postText : function(questionText){
        twit.verifyCredentials(function (err, data) {
        if (err) {
          console.log("Error verifying credentials: " + err);
          process.exit(1);
        }
      }).updateStatus(questionText,
        function (err, data) {
          if (err) {
            console.log('Tweeting failed: ' + err);
            return false;
          }
          else {
            console.log('Success!');
            return true;
          }
        }
      );
    },

    streamTwit: function (twit){
      var userid = '1527228696';
    twit.stream(
    'statuses/filter',
    { follow: userid},
      function(stream) {
          stream.on('data', function(tweet) {

          Fiber(function(){
            if(tweet.user.id_str === userid)
            {
              Meteor.call('addQn', tweet);
            }
          }).run();
          console.log('----------------------tracking tweet-----------------');
              console.log(tweet);
              console.log('---------------------------------------------------------');
              console.log(tweet.user.screen_name);
              console.log(tweet.user.name);
              console.log(tweet.text);
          });
        }
      );
    },

    addQn:function(tweet){
      questionDB.insert({'tweet': tweet, 'date': new Date()});
    }
  });
Fiber(function(){
  Meteor.call('streamTwit', twit);
}).run();
});

PS:I've replace my OAuth key. Thanks in advance

You Hock Tan
  • 995
  • 2
  • 9
  • 18

1 Answers1

9

i think you should wrap your callbacks with Meteor.bindEnvironment rather than use fibers directly - see here https://gist.github.com/possibilities/3443021

i use this quite extensively and it works well because you stay within the fiber rather than leaving and having to re-enter

normal callback style

someMethod({OPTIONS}, function(callbackReturnArgs){
    //this is the normal callback
));

bind environment wrapped callback

someMethod({OPTIONS}, Meteor.bindEnvironment(
  function(callbackReturnArgs){
    //this is the normal callback
  },
  function(e){
    console.log('bind failure');
  }
));

if you consistently wrap async callbacks like this, meteor is always accessbile


for this bit here

Fiber(function(){
  Meteor.call('streamTwit', twit);
}).run();

you do not need to fiber wrap this, you are already in the Meteor.startup context, so this is redundant - just the Meteor.call(...); will do the trick

nate-strauser
  • 2,763
  • 1
  • 16
  • 16
  • Sorry, I'm new to meteor, and I couldn't understand the Meteor.bindEnvironment. Is it possible for you to provide an example? Thanks! – You Hock Tan Jun 21 '13 at 15:22
  • already was a bindenvironment example - i added the 'normal' example so you can clearly see the difference – nate-strauser Jun 21 '13 at 18:50
  • what I don't understand is how can I change this to your example above. my functions were written on Meteor.methods, functions were declared as methodname: function(params){}, if so, what exactly is someMethod and whether is {OPTIONS} params? thanks – You Hock Tan Jun 22 '13 at 00:38
  • Why call back functions are not wrapped by it in default? Does it effect performance? – user3218743 Aug 30 '15 at 14:57