Skip to content

Commit

Permalink
Add fix + feature
Browse files Browse the repository at this point in the history
  • Loading branch information
darkterra committed Jan 4, 2018
1 parent b6e2b4d commit 9b30402
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 129 deletions.
99 changes: 79 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mongo-scheduler [![Build Status](https://travis-ci.org/jamplify/mongo-scheduler.png)](https://travis-ci.org/jamplify/mongo-scheduler)
mongo-scheduler
==================

Persistent event scheduler using mongodb as storage
Expand All @@ -16,17 +16,17 @@ Usage
### Initialization

```javascript
var Scheduler = require('mongo-scheduler')
var Scheduler = require('mongo-scheduer')
var scheduler = new Scheduler(connection, options)
```

__Arguments__
* connectionString <String or Object> - mongodb connections string (i.e.: "mongodb://localhost:27017/scheduler-db") or a mongoose connection object
* options <Object> - Options object
* connectionString \<String or Object> - mongodb connections string (i.e.: "mongodb://localhost:27017/scheduler-db") or a mongoose connection object
* options \<Object> - Options object

__Valid Options__
* pollInterval <Number> - Frequency in ms that the scheduler should poll the db. Default: 60000 (1 minute)
* doNotFire <bool> - If set to true, this instance will only schedule events, not fire them. Default: false
* pollInterval \<Number> - Frequency in ms that the scheduler should poll the db. Default: 60000 (1 minute)
* doNotFire \<bool> - If set to true, this instance will only schedule events, not fire them. Default: false

---------------------------------------

Expand All @@ -40,23 +40,22 @@ scheduler.schedule(event)
```

__Arguments__
* event <Object> - Event details
* [callback] <Function>
* event\<Object> - Event details
* [callback] \Function> - callabck

__Event Fields__
* name <String> - Name of event that should be fired
* [cron] <String> - A cron string representing a frequency this should fire on
* [collection] <Object> - Info about the documents this event corresponds to
* [id] <ObjectId> - Value of the _id field of the document this event corresponds to
* [after] <Date> - Time that the event should be triggered at, if left blank it will trigger the next time the scheduler polls
* [query] <Object> - a MongoDB query expression to select records that this event should be triggered for
* [data] <Object|Primitive> - Extra data to attach to the event

* name \<String> - Name of event that should be fired
* [cron] \<String> - A cron string representing a frequency this should fire on
* [collection] \<Object> - Info about the documents this event corresponds to
* [id] \<ObjectId> - Value of the _id field of the document this event corresponds to
* [after] \<Date> - Time that the event should be triggered at, if left blank it will trigger the next time the scheduler polls
* [query] \<Object> - a MongoDB query expression to select records that this event should be triggered for
* [data] \<Object|Primitive\> - Extra data to attach to the event


---------------------------------------

### on
### scheduler.on

Event handler.

Expand All @@ -68,14 +67,74 @@ scheduler.on('breakfast', function(meal, event) {
})
```
__Arguments__
* eventName <String> - Name of event
* handler <Function> - handler
* eventName \<String> - Name of event
* handler \<Function> - handler

---------------------------------------

### scheduler.list

List all events.

```javascript
scheduler.list('breakfast', function(err, events) {
// Do something with events
})
```

__Arguments__
* handler \<Function> - handler

---------------------------------------

### scheduler.find

Find an event.

```javascript
scheduler.find('breakfast', function(err, event) {
// Do something with event
})
```

__Arguments__
* eventName \<String> - Name of event
* handler \<Function> - handler

---------------------------------------

### scheduler.remove

Remove an event.

```javascript
scheduler.remove('breakfast', function(err, event) {
// Event has been removed
})
```

__Arguments__
* eventName \<String> - Name of event
* handler \<Function> - handler

---------------------------------------

### scheduler.enable

Enable scheduler.

---------------------------------------

### scheduler.disable

Disable scheduler.

---------------------------------------

#### Error handling
If the scheduler encounters an error it will emit an 'error' event. In this case the handler, will receive two arguments: the Error object, and the event doc (if applicable).

License
-------

MIT License
MIT License
99 changes: 57 additions & 42 deletions lib/helper.js
Original file line number Diff line number Diff line change
@@ -1,71 +1,86 @@
var _ = require('lodash'),
parser = require('cron-parser')
'use strict';

const _ = require('lodash');
const parser = require('cron-parser');

function SchedulerError(message) {
this.name = "SchedulerError"
this.message = message || "Unexpected Scheduler Error"
this.name = "SchedulerError";
this.message = message || "Unexpected Scheduler Error";
}
SchedulerError.prototype = new Error()

SchedulerError.prototype = new Error();
SchedulerError.prototype.constructor = SchedulerError;

function translateQueryfields(queryfields) {
return _.map(queryfields.split(' '), function(field) {
if(field === 'collection' || field === 'id')
return 'storage.' + field
else if(field === 'query' || field === 'after')
return 'conditions.' + field
else if(field === 'name') return 'event'
else return field
})
return _.map(queryfields.split(' '), (field) => {
if(field === 'collection' || field === 'id') {
return 'storage.' + field;
}
else if(field === 'query' || field === 'after') {
return 'conditions.' + field;
}
else if(field === 'name') {
return 'event';
}
else {
return field;
}
});
}

module.exports = {
buildSchedule: function(details) {
var storage = _.extend({}, _.pick(details, 'collection', 'id'))
var conditions = _.extend({}, _.pick(details, 'query', 'after'))
var options = _.defaults(details.options || {}, {
buildSchedule: (details) => {
const storage = _.extend({}, _.pick(details, 'collection', 'id'));
const conditions = _.extend({}, _.pick(details, 'query', 'after'));
const options = _.defaults(details.options || {}, {
emitPerDoc: false,
queryFields: 'name collection id'
})
queryFields: 'name collection id after'
});

var doc = {
const doc = {
status: details.status || 'ready',
event: details.name,
storage: storage,
conditions: conditions,
storage,
conditions,
data: details.data,
options: options
}
options
};

var queryFields = translateQueryfields(options.queryFields)
var query = _.transform(queryFields, function(memo, f) {
memo[f] = _.get(doc, f)
}, {})
const queryFields = translateQueryfields(options.queryFields);
const query = _.transform(queryFields, function(memo, f) {
memo[f] = _.get(doc, f);
}, {});

if (!!details.cron) {
doc.cron = details.cron
doc.conditions.after = parser.parseExpression(details.cron).next()
doc.cron = details.cron;
doc.conditions.after = parser.parseExpression(details.cron).next();
}

return { doc: doc, query: query }
return { doc, query };
},

buildEvent: function(doc) {
if (!doc) return;
buildEvent: (doc) => {
if (!doc) {
return;
}

doc.conditions.query = doc.conditions.query || {}
if (typeof doc.conditions.query === 'string')
doc.conditions.query = JSON.parse(doc.conditions.query)
if(doc.storage && doc.storage.id)
_.extend(doc.conditions.query, {_id: doc.storage.id})
return doc
doc.conditions.query = doc.conditions.query || {};

if (typeof doc.conditions.query === 'string') {
doc.conditions.query = JSON.parse(doc.conditions.query);
}
if(doc.storage && doc.storage.id) {
_.extend(doc.conditions.query, {_id: doc.storage.id});
}

return doc;
},

shouldExit: function(err, result) {
return !!err || !!(result.lastErrorObject && result.lastErrorObject.err)
return !!err || !!(result.lastErrorObject && result.lastErrorObject.err);
},

buildError: function(err, result) {
return err || new SchedulerError(result.lastErrorObject.err)
return err || new SchedulerError(result.lastErrorObject.err);
}
}
};
Loading

0 comments on commit 9b30402

Please sign in to comment.