WIP
darkterra / mongo-scheduler Goto Github PK
View Code? Open in Web Editor NEWThis project forked from jespinoza711/mongo-scheduler
Persistent event schedule for node.js using mongo as storage
License: MIT License
This project forked from jespinoza711/mongo-scheduler
Persistent event schedule for node.js using mongo as storage
License: MIT License
WIP
I've noticed when using scheduler.list()
the filter is not working, instead of the events that match the filter everything is returned. I've tested filters that should've worked with mongoDB.
my passed options object looks like this.
{
bySchedule: true,
{
'data.text':
'sampleText'
}
}
Can you check if query filtering works for you? I'm using the latest version 2.1.3
.
When I setup an event using a CRON setting of '0 */5 * * * *' it only fires one time. The statement says, "Fire every 5 minutes." However, it only seems to fire once.
After it fires the first time, the "conditions: {after: }" gets mangled. It gets set as:
"after": {
"_date": {
"_isAMomentObject": true,
"_isUTC": false,
"_pf": {
"empty": false,
"unusedTokens": [],
"unusedInput": [],
"overflow": -2,
"charsLeftOver": 0,
"nullInput": false,
"invalidMonth": null,
"invalidFormat": false,
"userInvalidated": false,
"iso": false,
"parsedDateParts": [],
"meridiem": null,
"rfc2822": false,
"weekdayMismatch": false
},
"_locale": {
"_calendar": {
"sameDay": "[Today at] LT",
"nextDay": "[Tomorrow at] LT",
"nextWeek": "dddd [at] LT",
"lastDay": "[Yesterday at] LT",
"lastWeek": "[Last] dddd [at] LT",
"sameElse": "L"
},
"_longDateFormat": {
"LTS": "h:mm:ss A",
"LT": "h:mm A",
"L": "MM/DD/YYYY",
"LL": "MMMM D, YYYY",
"LLL": "MMMM D, YYYY h:mm A",
"LLLL": "dddd, MMMM D, YYYY h:mm A"
},
"_invalidDate": "Invalid date",
"_dayOfMonthOrdinalParse": {},
"_relativeTime": {
"future": "in %s",
"past": "%s ago",
"s": "a few seconds",
"ss": "%d seconds",
"m": "a minute",
"mm": "%d minutes",
"h": "an hour",
"hh": "%d hours",
"d": "a day",
"dd": "%d days",
"M": "a month",
"MM": "%d months",
"y": "a year",
"yy": "%d years"
},
"_months": [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
"_monthsShort": [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
],
"_week": {
"dow": 0,
"doy": 6
},
"_weekdays": [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
],
"_weekdaysMin": [
"Su",
"Mo",
"Tu",
"We",
"Th",
"Fr",
"Sa"
],
"_weekdaysShort": [
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
],
"_meridiemParse": {},
"_abbr": "en",
"_config": {
"calendar": {
"sameDay": "[Today at] LT",
"nextDay": "[Tomorrow at] LT",
"nextWeek": "dddd [at] LT",
"lastDay": "[Yesterday at] LT",
"lastWeek": "[Last] dddd [at] LT",
"sameElse": "L"
},
"longDateFormat": {
"LTS": "h:mm:ss A",
"LT": "h:mm A",
"L": "MM/DD/YYYY",
"LL": "MMMM D, YYYY",
"LLL": "MMMM D, YYYY h:mm A",
"LLLL": "dddd, MMMM D, YYYY h:mm A"
},
"invalidDate": "Invalid date",
"dayOfMonthOrdinalParse": {},
"relativeTime": {
"future": "in %s",
"past": "%s ago",
"s": "a few seconds",
"ss": "%d seconds",
"m": "a minute",
"mm": "%d minutes",
"h": "an hour",
"hh": "%d hours",
"d": "a day",
"dd": "%d days",
"M": "a month",
"MM": "%d months",
"y": "a year",
"yy": "%d years"
},
"months": [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
"monthsShort": [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
],
"week": {
"dow": 0,
"doy": 6
},
"weekdays": [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
],
"weekdaysMin": [
"Su",
"Mo",
"Tu",
"We",
"Th",
"Fr",
"Sa"
],
"weekdaysShort": [
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
],
"meridiemParse": {},
"abbr": "en"
},
"_dayOfMonthOrdinalParseLenient": {}
},
"_z": null,
"_d": "2019-06-09T08:40:00.000Z",
"_isValid": true
}
}
Hi,
This is a beautiful piece of code. However, when I try using it against MongoAtlas I get the strangest error: MongoError: user is not allowed to do action [find] on [CompetitionScheduler.scheduled_events]
I've given my user an untold number of privileges with no resolution. Any idea?
Full error stack:
MongoError: user is not allowed to do action [find] on [CompetitionScheduler.scheduled_events]
at Connection. (/Users/dashby/Workarea/backend/CompetitionServicesAPI/node_modules/mongodb-core/lib/connection/pool.js:443:61)
at emitTwo (events.js:126:13)
at Connection.emit (events.js:214:7)
at processMessage (/Users/dashby/Workarea/backend/CompetitionServicesAPI/node_modules/mongodb-core/lib/connection/connection.js:364:10)
at TLSSocket. (/Users/dashby/Workarea/backend/CompetitionServicesAPI/node_modules/mongodb-core/lib/connection/connection.js:533:15)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at TLSSocket.Readable.push (_stream_readable.js:208:10)
at TLSWrap.onread [as _originalOnread] (net.js:601:20)
at TLSWrap.onread (/Users/dashby/Workarea//backend/CompetitionServicesAPI/node_modules/async-listener/glue.js:188:31)
I'm using this code to schedule new events to my mongodb.
const event = {
name: 'post',
after: new Date(Number(data.uploadDate)),
data: data,
};
scheduler.schedule(event);
data.uploadDate
is a point in the future.
But when I add a new event before the current one ran, the old one gets overriden by the new one.
I always only have one event at a time in the database.
I've checked by looking into the mongodb using mongo shell command db.scheduled_events.find( {} )
.
I'm using the latest version of this package and as far as I remember this didn't happen with the old one.
Also I'm running Mongodb Server version 4.0.6 and Ubuntu 18.04.
Hi @darkterra
Thanks for you efforts and good work. I found that findByStorageId and remove documentation states:
The id searched (remember, this id is not the event itself id)
but on code remove is doing
if (objectId.isValid(id)) {
query._id = objectId(id);
}
and findByStorageId
const lookup = { 'storage.id': id.toString() };
When fixing, doc or functionality, please consider comments on #4
If I attempt to use a query operator when creating a schedule, I receive this error:
/mnt/c/projects/ideoxan/marina/node_modules/mongodb/lib/cmap/connection.js:268
callback(new MongoError(document));
^
MongoError: The dollar ($) prefixed field '$gt' in 'storage.query.expires.$gt' is not valid for storage.
MongoDB (and other MongoDB drivers to an extent) support Query Operators. This is particularly helpful for querying large databases. For instance, the below code returns all documents from the dates
collection that have a date greater than 2021 February 8th.
db.dates.find({
time: {
$gt: new Date('2021-02-08')
}
})
Once again, this is really useful for large data queries. See https://docs.mongodb.com/manual/reference/method/db.collection.find/#query-using-operators for usage. It would be great if this is added as a feature. 👍
I've been trying to delete a single event by providing an eventName
as well as an id
to scheduler.remove()
but it doesn't remove anything and just results
{
"n": 0,
"ok": 1
}
I've used an ID returned by scheduler.list()
Also the usage of collection.remove
with mongodb seems to be deprecated but I guess it should work anyways.
I'm using version 1.2.1
scheduler.list() method not returning any error or result.
let response = await scheduler.list()
Hello There :)
Hi @darkterra
I found that some cron event's are being fired twice.
I think that the issue is here:
mongo-scheduler/lib/scheduler.js
Line 108 in 04dfb87
You are rescheduling in the next second and maybe the parser.next may return that it's the same minute. Not sure the best way to solve it but maybe you can pass the parser currentDate as the next time you will poll ...but should think better what can happen with expressions that repeat by seconds.
Here you have an example that reproduce this:
const moment = require('moment');
const msm = require('mongo-scheduler-more');
const scheduler = new msm('mongodb://localhost:27017/test');
scheduler.purge({ force: true }, ()=> {
scheduler.on('test', (e)=> console.log('Test Event', e));
const now = moment();
const time = now.clone().add(1,'minutes');
const expr = `* ${time.minutes()} ${time.hours()} * * ${time.day()}`;
console.log('Now:',now.toDate());
console.log('Setting to fire in next minute', time.toDate(), expr);
scheduler.schedule({
name: 'test',
cron: expr
})
});
This was the output after waiting for 2 minutes or 2 polls
Now: 2019-06-19T21:40:48.795Z
Setting to fire in next minute 2019-06-19T21:41:48.795Z * 41 18 * * 3
Test Event { _id: 5d0aabe0cce03f4230927821,
status: 'ready',
name: 'test',
storage: { collection: null, query: null, id: null },
conditions: { after: 2019-06-19T21:41:00.000Z, endDate: null },
cron: '* 41 18 * * 3',
data: null,
options: { emitPerDoc: false } }
Test Event { _id: 5d0aabe0cce03f4230927821,
status: 'ready',
name: 'test',
storage: { collection: null, query: null, id: null },
conditions: { after: 2019-06-19T21:41:50.000Z, endDate: null },
cron: '* 41 18 * * 3',
data: null,
options: { emitPerDoc: false } }
I found a nice feature that is not documented. event.options.emitPerDoc
Currently scheduler.list()
returns the events by the date and time they were added to the db. A nice addition would be to sort them by the schedule time either ascending or descending.
Currently there can't be two Events with the same time scheduled. Adding a new one is always overriding the old one if both have the same execution time.
Whenever I provide the doNotFire
option I get the following console log
the options [doNotFire] is not supported
like this
const scheduler = new Scheduler('mongodb://localhost:27017/schedule-test', { doNotFire: false });
When I don't provide an options object though it crashes with the following message.
Cannot read property 'doNotFire' of undefined
I've worked around this by hardcoding true
instead of !opts.doNotFire
inside of scheduler.js
if(true) whenReady(initialize)();
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.