Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meteor code must always run within a Fiber... #229

Open
mklueh opened this issue Apr 15, 2017 · 1 comment
Open

Meteor code must always run within a Fiber... #229

mklueh opened this issue Apr 15, 2017 · 1 comment

Comments

@mklueh
Copy link

mklueh commented Apr 15, 2017

Hello, I´m struggeling for days now to get the async stuff working with Meteor.

My usecase:

I want to spin up multiple processes, where each one has to do a certain number of exec calls to other programs, file operations and if possible MongoDB queries. Those processes should run within my meteor application. I don´t want to have extra servers for that.

I´ve tried using "child_process", but as Meteor builds the app and wraps files together, I cannot reference my worker file like in plain node.

meteor-job-collection looks like the best choice so far, but I cannot get the simplest implementation working.

Here is the code of my initializing script


import MyJob from '/server/services/myJob';

let jobs= JobCollection('app.jobs');

if (Meteor.isServer) {
    Meteor.startup(function () {
        return jobs.startJobServer();
    });

    let job = new MyJob(jobs, 'sendEmail',
        {
            address: '[email protected]',
            subject: 'Critical rainbow hair shortage',
            message: 'LOL; JK, KThxBye.'
         }
      );
     job.priority('normal').retry({retries: 10}).save();
}

And here my worker script

const exec = require('exec');
const DDP = require('ddp');
const DDPlogin = require('ddp-login');
const Job = require('meteor-job');

if (Meteor.isServer) {
    let ddp = new DDP({
        host: "localhost",
        port: 3000,
        method: 'account',
        retry: 5,
        account: null,
        pass: null,
        use_ejson: true
    });
    Job.setDDP(ddp);
    ddp.connect(function (err) {

        console.log("connected");
        if (err) throw err;

        DDPlogin(ddp, function () {
            console.log("login");

            let workers = Job.processJobs('app.jobs', 'sendEmail',
                function (job, cb) {
                    console.log(job);
                }
            );
        })

    });
}

First of all, the DDPLogin callback does basically nothing. It doesn´t get fired at all, so I´ve decided to remove it for now.

Then I get this error:

packages\meteor.js:1075
W20170415-19:16:25.187(2)? (STDERR)     throw new Error("Meteor code must always run within a Fiber. " +
W20170415-19:16:25.187(2)? (STDERR)     ^
W20170415-19:16:25.188(2)? (STDERR) 
W20170415-19:16:25.188(2)? (STDERR) Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.
W20170415-19:16:25.188(2)? (STDERR)     at Object.Meteor._nodeCodeMustBeInFiber (packages\meteor.js:1075:11)
W20170415-19:16:25.189(2)? (STDERR)     at [object Object]._.extend.get (packages\meteor.js:1087:12)
W20170415-19:16:25.189(2)? (STDERR)     at withoutInvocation (packages\meteor.js:443:28)
W20170415-19:16:25.189(2)? (STDERR)     at bindAndCatch (packages\meteor.js:452:33)
W20170415-19:16:25.190(2)? (STDERR)     at Object._.extend.setTimeout (packages\meteor.js:468:23)
W20170415-19:16:25.190(2)? (STDERR)     at _setImmediate (C:\Users\MyPC\Documents\Workspaces\Application\node_modules\meteor-job\lib\job_class.js:118:32)
W20170415-19:16:25.191(2)? (STDERR)     at JobQueue.resume (C:\Users\MyPC\Documents\Workspaces\Application\node_modules\meteor-job\lib\job_class.js:390:7)
W20170415-19:16:25.191(2)? (STDERR)     at new JobQueue (C:\Users\MyPC\Documents\Workspaces\Application\node_modules\meteor-job\lib\job_class.js:191:12)
W20170415-19:16:25.191(2)? (STDERR)     at C:\Users\MyPC\Documents\Workspaces\Application\node_modules\meteor-job\lib\job_class.js:154:47
W20170415-19:16:25.192(2)? (STDERR)     at Function.JobQueue [as processJobs] (C:\Users\MyPC\Documents\Workspaces\Application\node_modules\meteor-job\lib\job_class.js:156:11)
=> Exited with code: 1

I haven´t seen anything with fibers in your examples or in the documentation, so I think it should work without them at all until I call some external APIs or whatever.

Another weird thing is I´m getting the collection "app.jobs.jobs" instead of what I´ve specified "app.jobs" - not important, but weird.

What is wrong with my implementation and why do I get the fiber error with the example code?

@vsivsi
Copy link
Owner

vsivsi commented Apr 17, 2017

The main problem I see above is that in the Meteor server environment, most of that code above is not necessary and probably won't even work. e.g. You don't need the npm DDP library, or the DDPLogin or anything, because on a Meteor server you are already running in the Meteor environment and implicitly connected and authenticated by virtue of being in Meteor server code.

The example code you grabbed is for use in a pure node.js environment (no Meteor APIs, no Fibers, etc), not within Meteor the way you are trying to use it.

One other thing is if your workers will be calling non-Fiber aware async code (using callbacks or promises) then you will need to become acquainted with Meteor.bindEnvironment() and relatives. Google it, there are a lot of resources out there that explain this stuff.

Hope that helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants