vsivsi / meteor-job-collection

A persistent and reactive job queue for Meteor, supporting distributed workers that can run anywhere.
https://atmospherejs.com/vsivsi/job-collection
Other
389 stars 67 forks source link

Mongodb record insert job #174

Closed openqubit closed 8 years ago

openqubit commented 8 years ago

Would it be possible to create a job that inserts data to minimongo?.I have a collections schools which i am trying to insert data into using this worker

///////////////////
// node.js Worker
var DDP = require('ddp');
var DDPlogin = require('ddp-login');
var Job = require('meteor-job');

// `Job` here has essentially the same API as JobCollection on Meteor.
// In fact, job-collection is built on top of the 'meteor-job' npm package!

// Setup the DDP connection
var ddp = new DDP({
  host: "localhost",
  port: 3000,
  use_ejson: true
});

// Connect Job with this DDP session
Job.setDDP(ddp);

// Open the DDP connection
ddp.connect(function (err) {
  if (err) throw err;
  // Call below will prompt for email/password if an
  // authToken isn't available in the process environment
  DDPlogin(ddp, function (err, token) {
    if (err) throw err;
    // We're in!
    // Create a worker to get sendMail jobs from 'myJobQueue'
    // This will keep running indefinitely, obtaining new work
    // from the server whenever it is available.
    // Note: If this worker was running within the Meteor environment,
    // Then only the call below is necessary to setup a worker!
    // However in that case processJobs is a method on the JobCollection
    // object, and not Job.
    var workers = Job.processJobs('myJobQueue', 'sendEmail',
      function (job, cb) {
        // This will only be called if a
        // 'sendEmail' job is obtained
        var email = job.data; // Only one email per job
        var subject = email.subject;
        var address = email.address;
        var message = email.message;

        schools.insert({
          schoolname: subject,
          schooldescription: address,
          schoollocation: message
      });
      console.log(subject);
      // job.done(); // when done successfully

    // Be sure to invoke the callback
    // when work on this job has finished
    cb();
      }
    );
  });
});

No data is inserted hen i run this simple job.I have successfully authenticated so it can't be because i am not authenticated.

vsivsi commented 8 years ago

Is this running as a plain node.js worker? Based on all of the DDP setup that's what I'm assuming. In that case you are not running in the Meteor environment, so there simply is no minimongo... Where in your code is the schools collection defined? You can use the DDP npm package to subscribe to a published record set on the server, but those records are not held in a minimongo collection (at least not by default). They are just stored as attributes in a plain old JS object. I'm sure somebody has broken minimongo out of Meteor and into an npm package, but I've not seen anyone tightly integrate that with the DDP package.

vsivsi commented 8 years ago

There appear to be many npm minimongo packages from which to choose. I haven't used any of them... https://www.npmjs.com/search?q=minimongo

vsivsi commented 8 years ago

Just in case you meant Mongo (like the actual DB that the server is using...), then yes you can using the internal method calls defined for the server-side collection, using the DDP connection you have established. This is the same mechanism that Meteor clients use to insert/update/remove documents from a collection on the server.

Of course, if you don't want to delve into calls to internally defined methods on the server, you can simply write your own method(s) on the server to do whatever you want, and then invoke them using DDP from the worker.

openqubit commented 8 years ago

Yes,its the mongo meteor is using.I have gone ahead and defined an insert method in the server/methods.js

 'sendEmail': function(){

      Schools.insert({
          schoolname: 'jamesbond',
          schooldescription: 'wacky',
          schoollocation: 'london'
      });
}

in my nodeworker.js,i have this code


///////////////////
// node.js Worker
var DDP = require('ddp');
var DDPlogin = require('ddp-login');
var Job = require('meteor-job');

// `Job` here has essentially the same API as JobCollection on Meteor.
// In fact, job-collection is built on top of the 'meteor-job' npm package!

// Setup the DDP connection
var ddp = new DDP({
  host: "localhost",
  port: 3000,
  use_ejson: true
});

// Connect Job with this DDP session
Job.setDDP(ddp);

// Open the DDP connection
ddp.connect(function (err) {
  if (err) throw err;
  // Call below will prompt for email/password if an
  // authToken isn't available in the process environment
  DDPlogin(ddp, function (err, token) {
    if (err) throw err;
    // We're in!
    // Create a worker to get sendMail jobs from 'myJobQueue'
    // This will keep running indefinitely, obtaining new work
    // from the server whenever it is available.
    // Note: If this worker was running within the Meteor environment,
    // Then only the call below is necessary to setup a worker!
    // However in that case processJobs is a method on the JobCollection
    // object, and not Job.
    var workers = Job.processJobs('myJobQueue', 'sendEmail',
      function (job, cb) {
        // This will only be called if a
        // 'sendEmail' job is obtained
        var email = job.data; // Only one email per job
        console.log(email.subject);
        Meteor.call('sendEmail');
      }
    );
  });
});

When i run node nodeworker.js,i get this error

Account: hidden@gmail.com
Password: 
Critical rainbow hair shortage

/home/qubit/nodeworkers/nodeworker.js:41
        Meteor.call('sendEmail');
        ^
ReferenceError: Meteor is not defined
    at JobQueue.worker (/home/qubit/nodeworkers/nodeworker.js:41:3)
    at JobQueue._process (/home/qubit/nodeworkers/node_modules/meteor-job/lib/job_class.js:264:21)
    at processImmediate [as _immediateCallback] (timers.js:330:15)
openqubit commented 8 years ago

I am looking at this project https://github.com/oortcloud/node-ddp-client and i am trying to call my method this way

ddp.call('sendEmail');

but there is a problem.There are undone jobs in mongo,but hen i try running the job worker

qubit@qubit-HP-EliteBook-2540p:~/nodeworkers$ node nodeworker.js
Account: hidden@gmail.com
Password: 

I only get a blinking cursor and no indication from console log that any work is being done.Its only when i suspend the computer for like 30 minutes,that i can node nodeworker.js successfully.

Question,i am on ubuntu and does the job server or job worker run on a specific port and can i refresh the worker or the server by switching them off or restarting them?.

openqubit commented 8 years ago

Update

After replacing Meteor with ddp in method call, likeddp.call('sendEmail'); , i am able to insert the record and my queue looks like this now

meteor:PRIMARY> db.myJobQueue.jobs.find()
{
    "_id" : "DpjdAiMgw825itNan",
    "runId" : "rJynxdPJAKztBZm3A",
    "type" : "sendEmail",
    "data" : {
        "address" : "bozo@clowns.com",
        "subject" : "Critical rainbow hair shortage",
        "message" : "LOL; JK, KThxBye."
    },
    "status" : "running",
    "updated" : ISODate("2016-04-16T14:01:39.102Z"),
    "created" : ISODate("2016-04-16T11:30:08.861Z"),
    "priority" : 0,
    "retries" : 5,
    "retryWait" : 900000,
    "retried" : 1,
    "retryBackoff" : "constant",
    "retryUntil" : ISODate("275760-09-13T00:00:00Z"),
    "repeats" : 0,
    "repeatWait" : 300000,
    "repeated" : 0,
    "repeatUntil" : ISODate("275760-09-13T00:00:00Z"),
    "after" : ISODate("2016-04-16T12:30:08.835Z"),
    "progress" : {
        "completed" : 0,
        "total" : 1,
        "percent" : 0
    },
    "depends" : [ ],
    "resolved" : [ ],
    "log" : [
        {
            "time" : ISODate("2016-04-16T11:30:08.835Z"),
            "runId" : null,
            "level" : "info",
            "message" : "Constructed"
        },
        {
            "time" : ISODate("2016-04-16T11:30:08.861Z"),
            "runId" : null,
            "message" : "Job Submitted",
            "level" : "info"
        },
        {
            "time" : ISODate("2016-04-16T14:01:22.976Z"),
            "runId" : null,
            "message" : "Promoted to ready",
            "level" : "info"
        },
        {
            "time" : ISODate("2016-04-16T14:01:39.103Z"),
            "runId" : "rJynxdPJAKztBZm3A",
            "message" : "Job Running",
            "level" : "info"
        }
    ]
}
meteor:PRIMARY> 

The only remaining issue i am facing now is https://github.com/vsivsi/meteor-job-collection/issues/174#issuecomment-210791733

Since my last attempt,i waited three hours to be able to execute the task i have of inserting data in mongo. I exit meteor using Control-C and also exit mongo and nodeworker using Control-C?.

vsivsi commented 8 years ago

The job server and workers run on whatever port you configure them to. In development mode, Meteor servers default to port 3000. I really can't help you debug your prototype via github issue messages. I recommend that you look at the sample apps I have created for just this purpose: https://github.com/vsivsi/meteor-job-collection-playground https://github.com/vsivsi/meteor-job-collection-playground-worker

If you get truly stuck, the best way forward is for you to create a github project with all of your code in it, and post a description how to reproduce the issue using that code. If you follow those steps, I'm happy to help, but otherwise I really can't interactively assist you in writing your app in an issue thread like this. It's time consuming and not very productive. Thanks for understanding.

openqubit commented 8 years ago

I am very grateful for your help and understanding.I have finally solved all the issues i was having since i was using iron-cli and iron-router. Many thanks.