├── .gitignore
├── .npm
└── package
│ ├── .gitignore
│ ├── README
│ └── npm-shrinkwrap.json
├── .versions
├── LICENSE
├── README.md
├── example
├── .meteor
│ ├── .finished-upgraders
│ ├── .gitignore
│ ├── .id
│ ├── packages
│ ├── platforms
│ ├── release
│ └── versions
├── example.css
├── example.html
└── example.js
├── package.js
├── synced-cron-server.js
├── synced-cron-tests.js
└── versions.json
/.gitignore:
--------------------------------------------------------------------------------
1 | .build*
2 |
3 | .idea/
4 |
--------------------------------------------------------------------------------
/.npm/package/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/.npm/package/README:
--------------------------------------------------------------------------------
1 | This directory and the files immediately inside it are automatically generated
2 | when you change this package's NPM dependencies. Commit the files in this
3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control
4 | so that others run the same versions of sub-dependencies.
5 |
6 | You should NOT check in the node_modules directory that Meteor automatically
7 | creates; if you are using git, the .gitignore file tells git to ignore it.
8 |
--------------------------------------------------------------------------------
/.npm/package/npm-shrinkwrap.json:
--------------------------------------------------------------------------------
1 | {
2 | "lockfileVersion": 1,
3 | "dependencies": {
4 | "later": {
5 | "version": "1.1.6",
6 | "resolved": "https://registry.npmjs.org/later/-/later-1.1.6.tgz",
7 | "integrity": "sha1-Wvg61IJjk8VvEO4u4ekQlkRb5Os="
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.versions:
--------------------------------------------------------------------------------
1 | allow-deny@1.1.1
2 | babel-compiler@7.10.4
3 | babel-runtime@1.5.1
4 | base64@1.0.12
5 | binary-heap@1.0.11
6 | boilerplate-generator@1.7.1
7 | callback-hook@1.5.1
8 | check@1.3.2
9 | ddp@1.4.1
10 | ddp-client@2.6.1
11 | ddp-common@1.4.0
12 | ddp-server@2.6.2
13 | diff-sequence@1.1.2
14 | dynamic-import@0.7.3
15 | ecmascript@0.16.7
16 | ecmascript-runtime@0.8.1
17 | ecmascript-runtime-client@0.12.1
18 | ecmascript-runtime-server@0.11.0
19 | ejson@1.1.3
20 | fetch@0.1.3
21 | geojson-utils@1.0.11
22 | id-map@1.1.1
23 | inter-process-messaging@0.1.1
24 | local-test:percolate:synced-cron@1.5.2
25 | logging@1.3.2
26 | meteor@1.11.3
27 | minimongo@1.9.3
28 | modern-browsers@0.1.9
29 | modules@0.19.0
30 | modules-runtime@0.13.1
31 | mongo@1.16.7
32 | mongo-decimal@0.1.3
33 | mongo-dev-server@1.1.0
34 | mongo-id@1.0.8
35 | npm-mongo@4.16.0
36 | ordered-dict@1.1.0
37 | percolate:synced-cron@1.5.2
38 | promise@0.12.2
39 | random@1.2.1
40 | react-fast-refresh@0.2.7
41 | reload@1.3.1
42 | retry@1.1.0
43 | routepolicy@1.1.1
44 | socket-stream-client@0.5.1
45 | tinytest@1.2.2
46 | tracker@1.3.2
47 | underscore@1.0.13
48 | webapp@1.13.5
49 | webapp-hashing@1.1.1
50 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Percolate Studio
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # percolate:synced-cron
2 |
3 | A simple cron system for [Meteor](http://meteor.com). It supports syncronizing jobs between multiple processes. In other words, if you add a job that runs every hour and your deployment consists of multiple app servers, only one of the app servers will execute the job each time (whichever tries first).
4 |
5 | ## Migrated from percolate:synced-cron littledata:synced-cron
6 |
7 | Since the original creator of the project could no longer maintain it, we had to migrate the package to another organisation to allow further maintenance and updates.
8 |
9 | To migrate you can simply run
10 |
11 | ``` sh
12 | $ meteor remove percolate:synced-cron && meteor add littledata:synced-cron
13 | ```
14 |
15 | ## Installation
16 |
17 | ``` sh
18 | $ meteor add littledata:synced-cron
19 | ```
20 |
21 | ## API
22 |
23 | ### Basics
24 |
25 | To write a cron job, give it a unique name, a schedule and a function to run like below. SyncedCron uses the fantastic [later.js](http://bunkat.github.io/later/) library behind the scenes. A Later.js `parse` object is passed into the schedule call that gives you a huge amount of flexibility for scheduling your jobs, see the [documentation](http://bunkat.github.io/later/parsers.html#overview).
26 |
27 | ``` js
28 | SyncedCron.add({
29 | name: 'Crunch some important numbers for the marketing department',
30 | schedule: function(parser) {
31 | // parser is a later.parse object
32 | return parser.text('every 2 hours');
33 | },
34 | job: function() {
35 | var numbersCrunched = CrushSomeNumbers();
36 | return numbersCrunched;
37 | }
38 | });
39 | ```
40 |
41 | To start processing your jobs, somewhere in your project add:
42 |
43 | ``` js
44 | SyncedCron.start();
45 | ```
46 |
47 | ### Advanced
48 |
49 | SyncedCron uses a collection called `cronHistory` to syncronize between processes. This also serves as a useful log of when jobs ran along with their output or error. A sample item looks like:
50 |
51 | ``` js
52 | { _id: 'wdYLPBZp5zzbwdfYj',
53 | intendedAt: Sun Apr 13 2014 17:34:00 GMT-0700 (MST),
54 | finishedAt: Sun Apr 13 2014 17:34:01 GMT-0700 (MST),
55 | name: 'Crunch some important numbers for the marketing department',
56 | startedAt: Sun Apr 13 2014 17:34:00 GMT-0700 (MST),
57 | result: '1982 numbers crunched'
58 | }
59 | ```
60 |
61 | Call `SyncedCron.nextScheduledAtDate(jobName)` to find the date that the job
62 | referenced by `jobName` will run next.
63 |
64 | Call `SyncedCron.remove(jobName)` to remove and stop running the job referenced by jobName.
65 |
66 | Call `SyncedCron.stop()` to remove and stop all jobs.
67 |
68 | Call `SyncedCron.pause()` to stop all jobs without removing them. The existing jobs can be rescheduled (i.e. restarted) with `SyncedCron.start()`.
69 |
70 | To schedule a once off (i.e not recurring) event, create a job with a schedule like this `parser.recur().on(date).fullDate();`
71 |
72 | ### Configuration
73 |
74 | You can configure SyncedCron with the `config` method. Defaults are:
75 |
76 | ``` js
77 | SyncedCron.config({
78 | // Log job run details to console
79 | log: true,
80 |
81 | // Use a custom logger function (defaults to Meteor's logging package)
82 | logger: null,
83 |
84 | // Name of collection to use for synchronisation and logging
85 | collectionName: 'cronHistory',
86 |
87 | // Default to using localTime
88 | utc: false,
89 |
90 | /*
91 | TTL in seconds for history records in collection to expire
92 | NOTE: Unset to remove expiry but ensure you remove the index from
93 | mongo by hand
94 |
95 | ALSO: SyncedCron can't use the `_ensureIndex` command to modify
96 | the TTL index. The best way to modify the default value of
97 | `collectionTTL` is to remove the index by hand (in the mongo shell
98 | run `db.cronHistory.dropIndex({startedAt: 1})`) and re-run your
99 | project. SyncedCron will recreate the index with the updated TTL.
100 | */
101 | collectionTTL: 172800
102 | });
103 | ```
104 |
105 | ### Logging
106 |
107 | SyncedCron uses Meteor's `logging` package by default. If you want to use your own logger (for sending to other consumers or similar) you can do so by configuring the `logger` option.
108 |
109 | SyncedCron expects a function as `logger`, and will pass arguments to it for you to take action on.
110 |
111 | ```js
112 | var MyLogger = function(opts) {
113 | console.log('Level', opts.level);
114 | console.log('Message', opts.message);
115 | console.log('Tag', opts.tag);
116 | }
117 |
118 | SyncedCron.config({
119 | logger: MyLogger
120 | });
121 |
122 | SyncedCron.add({ name: 'Test Job', ... });
123 | SyncedCron.start();
124 | ```
125 |
126 | The `opts` object passed to `MyLogger` above includes `level`, `message`, and `tag`.
127 |
128 | - `level` will be one of `info`, `warn`, `error`, `debug`.
129 | - `message` is something like `Scheduled "Test Job" next run @Fri Mar 13 2015 10:15:00 GMT+0100 (CET)`.
130 | - `tag` will always be `"SyncedCron"` (handy for filtering).
131 |
132 |
133 | ## Caveats
134 |
135 | Beware, SyncedCron probably won't work as expected on certain shared hosting providers that shutdown app instances when they aren't receiving requests (like Heroku's free dyno tier or Meteor free galaxy).
136 |
137 | ## Contributing
138 |
139 | Write some code. Write some tests. To run the tests, do:
140 |
141 | ``` sh
142 | $ meteor test-packages ./
143 | ```
144 |
145 | ## License
146 |
147 | MIT. (c) Percolate Studio, originally designed and built by Zoltan Olah (@zol), now community maintained.
148 |
149 | Synced Cron was developed as part of the [Verso](http://versoapp.com) project.
150 |
--------------------------------------------------------------------------------
/example/.meteor/.finished-upgraders:
--------------------------------------------------------------------------------
1 | # This file contains information which helps Meteor properly upgrade your
2 | # app when you run 'meteor update'. You should check it into version control
3 | # with your project.
4 |
5 | notices-for-0.9.0
6 | notices-for-0.9.1
7 | 0.9.4-platform-file
8 | notices-for-facebook-graph-api-2
9 |
--------------------------------------------------------------------------------
/example/.meteor/.gitignore:
--------------------------------------------------------------------------------
1 | local
2 |
--------------------------------------------------------------------------------
/example/.meteor/.id:
--------------------------------------------------------------------------------
1 | # This file contains a token that is unique to your project.
2 | # Check it into your repository along with the rest of this directory.
3 | # It can be used for purposes such as:
4 | # - ensuring you don't accidentally deploy one app on top of another
5 | # - providing package authors with aggregated statistics
6 |
7 | 18n88nbddjnt450w00w
8 |
--------------------------------------------------------------------------------
/example/.meteor/packages:
--------------------------------------------------------------------------------
1 | # Meteor packages used by this project, one per line.
2 | #
3 | # 'meteor add' and 'meteor remove' will edit this file for you,
4 | # but you can also edit it by hand.
5 |
6 | standard-app-packages
7 | autopublish
8 | insecure
9 | percolate:synced-cron
10 |
--------------------------------------------------------------------------------
/example/.meteor/platforms:
--------------------------------------------------------------------------------
1 | browser
2 | server
3 |
--------------------------------------------------------------------------------
/example/.meteor/release:
--------------------------------------------------------------------------------
1 | METEOR@1.3
2 |
--------------------------------------------------------------------------------
/example/.meteor/versions:
--------------------------------------------------------------------------------
1 | autopublish@1.0.3
2 | autoupdate@1.2.1
3 | base64@1.0.3
4 | binary-heap@1.0.3
5 | blaze@2.1.2
6 | blaze-tools@1.0.3
7 | boilerplate-generator@1.0.3
8 | callback-hook@1.0.3
9 | check@1.0.5
10 | ddp@1.1.0
11 | deps@1.0.7
12 | ejson@1.0.6
13 | fastclick@1.0.3
14 | geojson-utils@1.0.3
15 | html-tools@1.0.4
16 | htmljs@1.0.4
17 | http@1.1.0
18 | id-map@1.0.3
19 | insecure@1.0.3
20 | jquery@1.11.3_2
21 | json@1.0.3
22 | launch-screen@1.0.2
23 | livedata@1.0.13
24 | logging@1.0.7
25 | meteor@1.1.6
26 | meteor-platform@1.2.2
27 | minifiers@1.1.5
28 | minimongo@1.0.8
29 | mobile-status-bar@1.0.3
30 | mongo@1.1.0
31 | observe-sequence@1.0.6
32 | ordered-dict@1.0.3
33 | percolate:synced-cron@1.2.2
34 | random@1.0.3
35 | reactive-dict@1.1.0
36 | reactive-var@1.0.5
37 | reload@1.1.3
38 | retry@1.0.3
39 | routepolicy@1.0.5
40 | session@1.1.0
41 | spacebars@1.0.6
42 | spacebars-compiler@1.0.6
43 | standard-app-packages@1.0.5
44 | templating@1.1.1
45 | tracker@1.0.7
46 | ui@1.0.6
47 | underscore@1.0.3
48 | url@1.0.4
49 | webapp@1.2.0
50 | webapp-hashing@1.0.3
51 |
--------------------------------------------------------------------------------
/example/example.css:
--------------------------------------------------------------------------------
1 | /* CSS declarations go here */
2 |
--------------------------------------------------------------------------------
/example/example.html:
--------------------------------------------------------------------------------
1 |