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
388 stars 68 forks source link

Documentation's use of globals makes it hard to read, add simple example #253

Open Floriferous opened 7 years ago

Floriferous commented 7 years ago

Edit: The documentation on this package is really extensive, it's great, but it's a bit complex at first, and it seems there are lots of ways to accomplish the same things. I think it'd be great to add a more simple example that only involves Meteor and can get people up and running really fast.

Since this package appears to use a mix of atmosphere and npm, it would be great for readability to clearly import variables (at least once) at the top of examples.

Namely, JobCollection, Job, (and sendEmail, but I understand that is an example function) are all used as globals, when the documentation mentions that this package only exports JobCollection as a global.

I'd actually like to see a super simple example of this package, to help people wrap their heads around the way it works, using only meteor. I'd be happy to submit a PR if this makes sense.

Here's an example:

// jobs.js
import { Meteor } from 'meteor/meteor';
import { JobCollection } from 'meteor/vsivsi:job-collection';

const jc = new JobCollection('myJobs');

const myJobs = [
  {
    type: 'sum',
    options: {
      pollInterval: 10000,
    },
    run: data => {
      console.log(data.value + data.value);
    },
  },
  {
    type: 'multiply',
    options: {
      pollInterval: 2000,
    },
    run: data => {
      console.log(data.value * data.value);
    },
  },
];

// Not sure this is a best-practice
myJobs.forEach(myJob => {
  jc.processJobs(myJob.type, myJob.options, (job, callback) => {
    try {
      myJob.run(job.data);
      job.done();
      callback();
    } catch (error) {
      job.fail(error);
    }
  });
});

Meteor.startup(() => {
  jc.startJobServer();
});

export default jc;

// Somewhere in your code, create a job
import { Meteor } from 'meteor/meteor';
import { Job } from 'meteor/vsivsi:job-collection';
import jc from './jobs.js';

Meteor.methods({
  createJob(type, value) {
    new Job(jc, type, { value }).save();
  },
});

// Create a job from anywhere
import { Meteor } from 'meteor/meteor';

Meteor.call('createJob', 'multiply', 7, (error, result) => {});

This could help set up best practices in some way, here's another example of the processJobs part I think is easy to understand:

const sum = data => console.log(data.value + data.value);
const multiply = data => console.log(data.value * data.value);

const defaultOptions = {
  concurrency: 1,
  payload: 1,
  pollInterval: 5000,
  workTimeout: 10000,
  callbackStrict: false,
  errorCallback: console.error,
};

jc.processJobs(['sum', 'multiply'], defaultOptions, (job, callback) => {
  const { data, type, done, fail } = job;

  switch (type) {
    case 'sum': {
      sum(data);
      done();
      break;
    }
    case 'multiply': {
      multiply(data);
      done();
      break;
    }
    default: {
      fail('job type not found');
      break;
    }
  }

  callback();
});
vsivsi commented 7 years ago

Hi, thanks for sharing your comments/insights. Agreed the code examples for this package do not follow well the current best practices. Keep in mind that this is all nearly 4 years old now, developed and written long before Meteor adopted/supported ES6.

I'm always happy to accept quality PRs, especially for documentation. Absent that, it is unlikely that I will personally find the time to implement your suggestions for this project; given where it is in the natural software life-cycle (maintenance mode, with deprecation visible on the horizon out there somewhere...)

vsivsi commented 7 years ago

Also, note that Job is also exported, see: https://github.com/vsivsi/meteor-job-collection/blob/master/package.js#L25

If the documentation suggests otherwise, that should be corrected.

janat08 commented 6 years ago

Mongo is planning to adopt observables at DB level in next release, so this may as well become goto worker package.

janat08 commented 6 years ago

forEach part will likely replicate listeners, observables, or wtv; type argument for process jobs will take array. There's also classy jobs by mitar that is entirely straightforward and just for meteor, except that it appears to restrict workers to doing a single instance of a job type (no sending 100 api calls a second).

vsivsi commented 6 years ago

@janat08 FYI, Classy jobs is built on top on this package... As for Mongo observables, that's interesting. Seems like they may be catching up with RethinkDB in that respect.

janat08 commented 6 years ago

https://github.com/peerlibrary/meteor-classy-job/issues/1. Otherwise the package basically answers the issue demands, may as well just suggest it. *issue in fact only about doing different types of job, with option for concurrency.

vsivsi commented 6 years ago

With job collection you can gain parallelism by running as many worker processes on as many cores/machines as you want. processJobs can also have multiple asynchronous jobs in flight at the same time (which can fork new processes) and can provide multiple jobs for each call to the worker function (for workers invoking other tools that can handle parallel work). In short, there are many ways to parallelize work using job-collection...

vsivsi commented 6 years ago

Above edited because I'm not sure about parallelism in classy job...