Skip to content

Commit d8ed09c

Browse files
committed
cleanup: move node-cron jobs into cron
1 parent 0e11979 commit d8ed09c

File tree

2 files changed

+110
-103
lines changed

2 files changed

+110
-103
lines changed

src/cron.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { firebase } from './firebase';
2+
import {
3+
dateMarketCloses,
4+
dateMarketOpens,
5+
getMarketHours,
6+
MarketHours,
7+
tradier
8+
} from './tradier';
9+
import { sanitize } from '@prmichaelsen/ts-utils';
10+
import { CronJob } from 'cron';
11+
import moment = require("moment");
12+
13+
const db = firebase.database();
14+
15+
/**
16+
* runs every month at midnight NYSE time
17+
* to update the database with market hours
18+
* for this month and next
19+
*/
20+
const onUpdateMonthlyMarketHours = async () => {
21+
const thisMonth = moment();
22+
const nextMonth = moment().add({ month: 1 });
23+
const marketHours: MarketHours[] = [
24+
...getMarketHours(await tradier.calendar({
25+
month: String(thisMonth.month() + 1),
26+
year: String(thisMonth.year()),
27+
})),
28+
...getMarketHours(await tradier.calendar({
29+
month: String(nextMonth.month() + 1),
30+
year: String(nextMonth.year()),
31+
})),
32+
];
33+
await db.ref('market/meta/marketHours').set(marketHours);
34+
}
35+
new CronJob({
36+
// at 00:00:00 on day-of-month 1
37+
cronTime: '0 0 0 1 * *',
38+
timeZone: 'America/New_York',
39+
start: true,
40+
onTick: onUpdateMonthlyMarketHours,
41+
});
42+
43+
/**
44+
* runs every day at midnight NYSE time
45+
* to update the database with market hours
46+
* for today
47+
*/
48+
const onUpdateTodaysMarketHours = async () => {
49+
const marketHours: MarketHours[] = (
50+
await db.ref('market/meta/marketHours').once('value')
51+
).val() || [];
52+
await db.ref('market/meta').update(sanitize({
53+
dateMarketCloses: dateMarketCloses(marketHours),
54+
dateMarketOpens: dateMarketOpens(marketHours),
55+
}));
56+
};
57+
new CronJob({
58+
// at 00:00:00
59+
cronTime: '0 0 0 * * *',
60+
timeZone: 'America/New_York',
61+
start: true,
62+
onTick: onUpdateTodaysMarketHours,
63+
});
64+
65+
/**
66+
* runs every second in order to update
67+
* the database with whether or not
68+
* the market is currently open.
69+
*/
70+
const onUpdateMarketIsOpen = async () => {
71+
const now = moment();
72+
const dateMarketCloses = moment((
73+
await db.ref('market/meta/dateMarketCloses').once('value')
74+
).val());
75+
const dateMarketOpens = moment((
76+
await db.ref('market/meta/dateMarketOpens').once('value')
77+
).val());
78+
if (!dateMarketCloses.isValid() || !dateMarketOpens.isValid()) {
79+
return;
80+
}
81+
const isOpen = now.isAfter(dateMarketOpens) && now.isBefore(dateMarketCloses);
82+
await db.ref('market/meta/isOpen').set(isOpen);
83+
};
84+
new CronJob({
85+
// every second
86+
cronTime: '0/1 0 0 * * *',
87+
timeZone: 'America/New_York',
88+
start: true,
89+
onTick: onUpdateMarketIsOpen,
90+
});
91+
92+
// fire off jobs, in case they have
93+
// never been run before
94+
(async function seedJobs() {
95+
await onUpdateMonthlyMarketHours();
96+
await onUpdateTodaysMarketHours();
97+
await onUpdateMarketIsOpen();
98+
})();

src/index.ts

Lines changed: 12 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,21 @@ import {
44
run,
55
validate
66
} from './jobs';
7-
import {
8-
dateMarketCloses,
9-
dateMarketOpens,
10-
getMarketHours,
11-
MarketHours,
12-
tradier
13-
} from './tradier';
147
import { Job } from '@prmichaelsen/hb-common';
158
import { database } from 'firebase-admin';
169
import * as _ from 'lodash';
10+
import * as moment from 'moment';
1711
import { isNullOrUndefined } from 'util';
18-
import {
19-
CronJob,
20-
} from 'cron';
2112
import {
2213
sanitize,
2314
DeepImmutableObject,
2415
time as _time,
2516
ITimeString,
2617
} from '@prmichaelsen/ts-utils';
27-
import moment = require('moment');
18+
19+
20+
/** initialize the node-cron jobs */
21+
require('./cron');
2822

2923
const time = {
3024
..._time,
@@ -33,121 +27,36 @@ const time = {
3327
}
3428
}
3529

36-
// As an admin, the app has access to read and write all data, regardless of Security Rules
37-
var db = firebase.database();
30+
/** db reference for firebase connection */
31+
const db = firebase.database();
3832
db.ref('meta/').once('value').then(function (snapshot: any) {
3933
console.log('meta', snapshot.val());
4034
});
4135
db.ref('meta/dateServerLastStarted').set(time.now().toString());
4236

43-
db.ref('jobs').on('child_added', receive);
44-
45-
/**
46-
* runs every month at midnight NYSE time
47-
* to update the database with market hours
48-
* for this month and next
49-
*/
50-
const onUpdateMonthlyMarketHours = async () => {
51-
const thisMonth = moment();
52-
const nextMonth = moment().add({ month: 1 });
53-
const marketHours: MarketHours[] = [
54-
...getMarketHours(await tradier.calendar({
55-
month: String(thisMonth.month() + 1),
56-
year: String(thisMonth.year()),
57-
})),
58-
...getMarketHours(await tradier.calendar({
59-
month: String(nextMonth.month() + 1),
60-
year: String(nextMonth.year()),
61-
})),
62-
];
63-
await db.ref('market/meta/marketHours').set(marketHours);
64-
}
65-
new CronJob({
66-
// at 00:00:00 on day-of-month 1
67-
cronTime: '0 0 0 1 * *',
68-
timeZone: 'America/New_York',
69-
start: true,
70-
onTick: onUpdateMonthlyMarketHours,
71-
});
72-
73-
/**
74-
* runs every day at midnight NYSE time
75-
* to update the database with market hours
76-
* for today
77-
*/
78-
const onUpdateTodaysMarketHours = async () => {
79-
const marketHours: MarketHours[] = (
80-
await db.ref('market/meta/marketHours').once('value')
81-
).val() || [];
82-
await db.ref('market/meta').update(sanitize({
83-
dateMarketCloses: dateMarketCloses(marketHours),
84-
dateMarketOpens: dateMarketOpens(marketHours),
85-
}));
86-
};
87-
new CronJob({
88-
// at 00:00:00
89-
cronTime: '0 0 0 * * *',
90-
timeZone: 'America/New_York',
91-
start: true,
92-
onTick: onUpdateTodaysMarketHours,
93-
});
94-
9537
/**
96-
* runs every second in order to update
97-
* the database with whether or not
98-
* the market is currently open.
38+
* handle newly created jobs by setting some metadata
9939
*/
100-
const onUpdateMarketIsOpen = async () => {
101-
const now = moment();
102-
const dateMarketCloses = moment((
103-
await db.ref('market/meta/dateMarketCloses').once('value')
104-
).val());
105-
const dateMarketOpens = moment((
106-
await db.ref('market/meta/dateMarketOpens').once('value')
107-
).val());
108-
if (!dateMarketCloses.isValid() || !dateMarketOpens.isValid()) {
109-
return;
110-
}
111-
const isOpen = now.isAfter(dateMarketOpens) && now.isBefore(dateMarketCloses);
112-
await db.ref('market/meta/isOpen').set(isOpen);
113-
};
114-
new CronJob({
115-
// every second
116-
cronTime: '0/1 0 0 * * *',
117-
timeZone: 'America/New_York',
118-
start: true,
119-
onTick: onUpdateMarketIsOpen,
120-
});
121-
122-
// fire off jobs, in case they have
123-
// never been run before
124-
(async function seedJobs() {
125-
await onUpdateMonthlyMarketHours();
126-
await onUpdateTodaysMarketHours();
127-
await onUpdateMarketIsOpen();
128-
})();
129-
130-
async function receive(snapshot: database.DataSnapshot) {
40+
db.ref('jobs').on('child_added', async snapshot => {
13141
const job: Job.Job = snapshot.val();
13242
if (job.status !== 'Sent')
13343
return;
13444
const id = snapshot.key;
13545
const uri = ['jobs', id].join('/');
136-
const data = _.cloneDeep<Job.Job>(job);
13746
const result: Job.Job = {
138-
...data,
47+
...job,
13948
lifecycle: { step: 'init' },
14049
status: 'Received',
14150
dateReceived: time.now().toString(),
14251
id,
14352
}
14453
return await db.ref(uri).set(sanitize(result));
145-
}
54+
});
14655

56+
/** fires any time a job has been updated in any way */
14757
db.ref('jobs').on('child_changed', async snapshot => {
14858
const job: DeepImmutableObject<Job.Job> = snapshot.val();
14959
const key = snapshot.key;
150-
const id = job.id;
15160
const uri = ['jobs', key].join('/');
15261
const data = _.cloneDeep<Job.Job>(job);
15362
switch (job.status) {

0 commit comments

Comments
 (0)