pg-boss 9.0.1 → 9.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,814 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for timekeeper.js</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="prettify.css" />
9
+ <link rel="stylesheet" href="base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="index.html">All files</a> timekeeper.js</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">97.39% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>112/115</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">79.54% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>35/44</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>21/21</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">100% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>105/105</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input oninput="onInput()" type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">12x</span>
310
+ <span class="cline-any cline-yes">12x</span>
311
+ <span class="cline-any cline-yes">12x</span>
312
+ <span class="cline-any cline-yes">12x</span>
313
+ <span class="cline-any cline-yes">12x</span>
314
+ <span class="cline-any cline-neutral">&nbsp;</span>
315
+ <span class="cline-any cline-yes">12x</span>
316
+ <span class="cline-any cline-neutral">&nbsp;</span>
317
+ <span class="cline-any cline-neutral">&nbsp;</span>
318
+ <span class="cline-any cline-neutral">&nbsp;</span>
319
+ <span class="cline-any cline-neutral">&nbsp;</span>
320
+ <span class="cline-any cline-yes">12x</span>
321
+ <span class="cline-any cline-neutral">&nbsp;</span>
322
+ <span class="cline-any cline-neutral">&nbsp;</span>
323
+ <span class="cline-any cline-neutral">&nbsp;</span>
324
+ <span class="cline-any cline-neutral">&nbsp;</span>
325
+ <span class="cline-any cline-neutral">&nbsp;</span>
326
+ <span class="cline-any cline-neutral">&nbsp;</span>
327
+ <span class="cline-any cline-yes">201x</span>
328
+ <span class="cline-any cline-neutral">&nbsp;</span>
329
+ <span class="cline-any cline-yes">201x</span>
330
+ <span class="cline-any cline-yes">201x</span>
331
+ <span class="cline-any cline-yes">201x</span>
332
+ <span class="cline-any cline-yes">201x</span>
333
+ <span class="cline-any cline-yes">201x</span>
334
+ <span class="cline-any cline-yes">201x</span>
335
+ <span class="cline-any cline-neutral">&nbsp;</span>
336
+ <span class="cline-any cline-yes">201x</span>
337
+ <span class="cline-any cline-neutral">&nbsp;</span>
338
+ <span class="cline-any cline-yes">201x</span>
339
+ <span class="cline-any cline-yes">201x</span>
340
+ <span class="cline-any cline-yes">201x</span>
341
+ <span class="cline-any cline-yes">201x</span>
342
+ <span class="cline-any cline-yes">201x</span>
343
+ <span class="cline-any cline-yes">201x</span>
344
+ <span class="cline-any cline-neutral">&nbsp;</span>
345
+ <span class="cline-any cline-yes">201x</span>
346
+ <span class="cline-any cline-neutral">&nbsp;</span>
347
+ <span class="cline-any cline-neutral">&nbsp;</span>
348
+ <span class="cline-any cline-neutral">&nbsp;</span>
349
+ <span class="cline-any cline-neutral">&nbsp;</span>
350
+ <span class="cline-any cline-neutral">&nbsp;</span>
351
+ <span class="cline-any cline-yes">201x</span>
352
+ <span class="cline-any cline-neutral">&nbsp;</span>
353
+ <span class="cline-any cline-neutral">&nbsp;</span>
354
+ <span class="cline-any cline-neutral">&nbsp;</span>
355
+ <span class="cline-any cline-neutral">&nbsp;</span>
356
+ <span class="cline-any cline-yes">184x</span>
357
+ <span class="cline-any cline-yes">7x</span>
358
+ <span class="cline-any cline-neutral">&nbsp;</span>
359
+ <span class="cline-any cline-neutral">&nbsp;</span>
360
+ <span class="cline-any cline-neutral">&nbsp;</span>
361
+ <span class="cline-any cline-yes">177x</span>
362
+ <span class="cline-any cline-neutral">&nbsp;</span>
363
+ <span class="cline-any cline-yes">177x</span>
364
+ <span class="cline-any cline-yes">177x</span>
365
+ <span class="cline-any cline-neutral">&nbsp;</span>
366
+ <span class="cline-any cline-neutral">&nbsp;</span>
367
+ <span class="cline-any cline-yes">177x</span>
368
+ <span class="cline-any cline-neutral">&nbsp;</span>
369
+ <span class="cline-any cline-neutral">&nbsp;</span>
370
+ <span class="cline-any cline-yes">177x</span>
371
+ <span class="cline-any cline-neutral">&nbsp;</span>
372
+ <span class="cline-any cline-yes">177x</span>
373
+ <span class="cline-any cline-neutral">&nbsp;</span>
374
+ <span class="cline-any cline-yes">177x</span>
375
+ <span class="cline-any cline-neutral">&nbsp;</span>
376
+ <span class="cline-any cline-neutral">&nbsp;</span>
377
+ <span class="cline-any cline-neutral">&nbsp;</span>
378
+ <span class="cline-any cline-yes">202x</span>
379
+ <span class="cline-any cline-yes">26x</span>
380
+ <span class="cline-any cline-neutral">&nbsp;</span>
381
+ <span class="cline-any cline-neutral">&nbsp;</span>
382
+ <span class="cline-any cline-yes">176x</span>
383
+ <span class="cline-any cline-neutral">&nbsp;</span>
384
+ <span class="cline-any cline-yes">176x</span>
385
+ <span class="cline-any cline-yes">176x</span>
386
+ <span class="cline-any cline-neutral">&nbsp;</span>
387
+ <span class="cline-any cline-yes">176x</span>
388
+ <span class="cline-any cline-yes">176x</span>
389
+ <span class="cline-any cline-yes">176x</span>
390
+ <span class="cline-any cline-neutral">&nbsp;</span>
391
+ <span class="cline-any cline-neutral">&nbsp;</span>
392
+ <span class="cline-any cline-yes">176x</span>
393
+ <span class="cline-any cline-yes">176x</span>
394
+ <span class="cline-any cline-yes">176x</span>
395
+ <span class="cline-any cline-neutral">&nbsp;</span>
396
+ <span class="cline-any cline-neutral">&nbsp;</span>
397
+ <span class="cline-any cline-neutral">&nbsp;</span>
398
+ <span class="cline-any cline-neutral">&nbsp;</span>
399
+ <span class="cline-any cline-yes">7x</span>
400
+ <span class="cline-any cline-yes">7x</span>
401
+ <span class="cline-any cline-yes">2x</span>
402
+ <span class="cline-any cline-neutral">&nbsp;</span>
403
+ <span class="cline-any cline-neutral">&nbsp;</span>
404
+ <span class="cline-any cline-yes">5x</span>
405
+ <span class="cline-any cline-neutral">&nbsp;</span>
406
+ <span class="cline-any cline-yes">5x</span>
407
+ <span class="cline-any cline-yes">2x</span>
408
+ <span class="cline-any cline-neutral">&nbsp;</span>
409
+ <span class="cline-any cline-neutral">&nbsp;</span>
410
+ <span class="cline-any cline-yes">2x</span>
411
+ <span class="cline-any cline-neutral">&nbsp;</span>
412
+ <span class="cline-any cline-neutral">&nbsp;</span>
413
+ <span class="cline-any cline-neutral">&nbsp;</span>
414
+ <span class="cline-any cline-neutral">&nbsp;</span>
415
+ <span class="cline-any cline-yes">188x</span>
416
+ <span class="cline-any cline-neutral">&nbsp;</span>
417
+ <span class="cline-any cline-yes">188x</span>
418
+ <span class="cline-any cline-yes">188x</span>
419
+ <span class="cline-any cline-yes">2x</span>
420
+ <span class="cline-any cline-neutral">&nbsp;</span>
421
+ <span class="cline-any cline-neutral">&nbsp;</span>
422
+ <span class="cline-any cline-yes">186x</span>
423
+ <span class="cline-any cline-neutral">&nbsp;</span>
424
+ <span class="cline-any cline-yes">186x</span>
425
+ <span class="cline-any cline-neutral">&nbsp;</span>
426
+ <span class="cline-any cline-yes">186x</span>
427
+ <span class="cline-any cline-neutral">&nbsp;</span>
428
+ <span class="cline-any cline-yes">186x</span>
429
+ <span class="cline-any cline-neutral">&nbsp;</span>
430
+ <span class="cline-any cline-yes">186x</span>
431
+ <span class="cline-any cline-neutral">&nbsp;</span>
432
+ <span class="cline-any cline-yes">186x</span>
433
+ <span class="cline-any cline-yes">1x</span>
434
+ <span class="cline-any cline-neutral">&nbsp;</span>
435
+ <span class="cline-any cline-neutral">&nbsp;</span>
436
+ <span class="cline-any cline-yes">2x</span>
437
+ <span class="cline-any cline-neutral">&nbsp;</span>
438
+ <span class="cline-any cline-yes">188x</span>
439
+ <span class="cline-any cline-neutral">&nbsp;</span>
440
+ <span class="cline-any cline-neutral">&nbsp;</span>
441
+ <span class="cline-any cline-neutral">&nbsp;</span>
442
+ <span class="cline-any cline-neutral">&nbsp;</span>
443
+ <span class="cline-any cline-yes">206x</span>
444
+ <span class="cline-any cline-neutral">&nbsp;</span>
445
+ <span class="cline-any cline-neutral">&nbsp;</span>
446
+ <span class="cline-any cline-neutral">&nbsp;</span>
447
+ <span class="cline-any cline-neutral">&nbsp;</span>
448
+ <span class="cline-any cline-neutral">&nbsp;</span>
449
+ <span class="cline-any cline-yes">206x</span>
450
+ <span class="cline-any cline-neutral">&nbsp;</span>
451
+ <span class="cline-any cline-neutral">&nbsp;</span>
452
+ <span class="cline-any cline-neutral">&nbsp;</span>
453
+ <span class="cline-any cline-yes">31x</span>
454
+ <span class="cline-any cline-neutral">&nbsp;</span>
455
+ <span class="cline-any cline-yes">27x</span>
456
+ <span class="cline-any cline-yes">27x</span>
457
+ <span class="cline-any cline-yes">1x</span>
458
+ <span class="cline-any cline-neutral">&nbsp;</span>
459
+ <span class="cline-any cline-neutral">&nbsp;</span>
460
+ <span class="cline-any cline-yes">26x</span>
461
+ <span class="cline-any cline-neutral">&nbsp;</span>
462
+ <span class="cline-any cline-yes">26x</span>
463
+ <span class="cline-any cline-neutral">&nbsp;</span>
464
+ <span class="cline-any cline-yes">26x</span>
465
+ <span class="cline-any cline-yes">7x</span>
466
+ <span class="cline-any cline-neutral">&nbsp;</span>
467
+ <span class="cline-any cline-neutral">&nbsp;</span>
468
+ <span class="cline-any cline-yes">26x</span>
469
+ <span class="cline-any cline-neutral">&nbsp;</span>
470
+ <span class="cline-any cline-neutral">&nbsp;</span>
471
+ <span class="cline-any cline-yes">26x</span>
472
+ <span class="cline-any cline-neutral">&nbsp;</span>
473
+ <span class="cline-any cline-yes">1x</span>
474
+ <span class="cline-any cline-neutral">&nbsp;</span>
475
+ <span class="cline-any cline-neutral">&nbsp;</span>
476
+ <span class="cline-any cline-yes">27x</span>
477
+ <span class="cline-any cline-neutral">&nbsp;</span>
478
+ <span class="cline-any cline-neutral">&nbsp;</span>
479
+ <span class="cline-any cline-yes">27x</span>
480
+ <span class="cline-any cline-neutral">&nbsp;</span>
481
+ <span class="cline-any cline-neutral">&nbsp;</span>
482
+ <span class="cline-any cline-neutral">&nbsp;</span>
483
+ <span class="cline-any cline-yes">7x</span>
484
+ <span class="cline-any cline-neutral">&nbsp;</span>
485
+ <span class="cline-any cline-yes">7x</span>
486
+ <span class="cline-any cline-neutral">&nbsp;</span>
487
+ <span class="cline-any cline-yes">7x</span>
488
+ <span class="cline-any cline-neutral">&nbsp;</span>
489
+ <span class="cline-any cline-yes">7x</span>
490
+ <span class="cline-any cline-neutral">&nbsp;</span>
491
+ <span class="cline-any cline-yes">7x</span>
492
+ <span class="cline-any cline-neutral">&nbsp;</span>
493
+ <span class="cline-any cline-neutral">&nbsp;</span>
494
+ <span class="cline-any cline-neutral">&nbsp;</span>
495
+ <span class="cline-any cline-yes">7x</span>
496
+ <span class="cline-any cline-neutral">&nbsp;</span>
497
+ <span class="cline-any cline-neutral">&nbsp;</span>
498
+ <span class="cline-any cline-neutral">&nbsp;</span>
499
+ <span class="cline-any cline-neutral">&nbsp;</span>
500
+ <span class="cline-any cline-neutral">&nbsp;</span>
501
+ <span class="cline-any cline-yes">7x</span>
502
+ <span class="cline-any cline-neutral">&nbsp;</span>
503
+ <span class="cline-any cline-neutral">&nbsp;</span>
504
+ <span class="cline-any cline-neutral">&nbsp;</span>
505
+ <span class="cline-any cline-yes">6x</span>
506
+ <span class="cline-any cline-yes">6x</span>
507
+ <span class="cline-any cline-yes">6x</span>
508
+ <span class="cline-any cline-neutral">&nbsp;</span>
509
+ <span class="cline-any cline-neutral">&nbsp;</span>
510
+ <span class="cline-any cline-neutral">&nbsp;</span>
511
+ <span class="cline-any cline-yes">26x</span>
512
+ <span class="cline-any cline-yes">26x</span>
513
+ <span class="cline-any cline-neutral">&nbsp;</span>
514
+ <span class="cline-any cline-neutral">&nbsp;</span>
515
+ <span class="cline-any cline-neutral">&nbsp;</span>
516
+ <span class="cline-any cline-yes">8x</span>
517
+ <span class="cline-any cline-neutral">&nbsp;</span>
518
+ <span class="cline-any cline-yes">8x</span>
519
+ <span class="cline-any cline-neutral">&nbsp;</span>
520
+ <span class="cline-any cline-neutral">&nbsp;</span>
521
+ <span class="cline-any cline-yes">8x</span>
522
+ <span class="cline-any cline-neutral">&nbsp;</span>
523
+ <span class="cline-any cline-yes">8x</span>
524
+ <span class="cline-any cline-neutral">&nbsp;</span>
525
+ <span class="cline-any cline-yes">8x</span>
526
+ <span class="cline-any cline-neutral">&nbsp;</span>
527
+ <span class="cline-any cline-yes">8x</span>
528
+ <span class="cline-any cline-neutral">&nbsp;</span>
529
+ <span class="cline-any cline-neutral">&nbsp;</span>
530
+ <span class="cline-any cline-neutral">&nbsp;</span>
531
+ <span class="cline-any cline-yes">1x</span>
532
+ <span class="cline-any cline-yes">1x</span>
533
+ <span class="cline-any cline-neutral">&nbsp;</span>
534
+ <span class="cline-any cline-neutral">&nbsp;</span>
535
+ <span class="cline-any cline-neutral">&nbsp;</span>
536
+ <span class="cline-any cline-yes">26x</span>
537
+ <span class="cline-any cline-neutral">&nbsp;</span>
538
+ <span class="cline-any cline-neutral">&nbsp;</span>
539
+ <span class="cline-any cline-neutral">&nbsp;</span>
540
+ <span class="cline-any cline-yes">5x</span>
541
+ <span class="cline-any cline-neutral">&nbsp;</span>
542
+ <span class="cline-any cline-yes">5x</span>
543
+ <span class="cline-any cline-neutral">&nbsp;</span>
544
+ <span class="cline-any cline-yes">5x</span>
545
+ <span class="cline-any cline-neutral">&nbsp;</span>
546
+ <span class="cline-any cline-yes">5x</span>
547
+ <span class="cline-any cline-neutral">&nbsp;</span>
548
+ <span class="cline-any cline-neutral">&nbsp;</span>
549
+ <span class="cline-any cline-neutral">&nbsp;</span>
550
+ <span class="cline-any cline-yes">12x</span>
551
+ <span class="cline-any cline-yes">12x</span>
552
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">const EventEmitter = require('events')
553
+ const plans = require('./plans')
554
+ const cronParser = require('cron-parser')
555
+ const Attorney = require('./attorney')
556
+ const pMap = require('p-map')
557
+ &nbsp;
558
+ const queues = {
559
+ CRON: '__pgboss__cron',
560
+ SEND_IT: '__pgboss__send-it'
561
+ }
562
+ &nbsp;
563
+ const events = {
564
+ error: 'error',
565
+ schedule: 'schedule'
566
+ }
567
+ &nbsp;
568
+ class Timekeeper extends EventEmitter {
569
+ constructor (db, config) {
570
+ super()
571
+ &nbsp;
572
+ this.db = db
573
+ this.config = config
574
+ this.manager = config.manager
575
+ this.skewMonitorIntervalMs = config.clockMonitorIntervalSeconds * 1000
576
+ this.cronMonitorIntervalMs = config.cronMonitorIntervalSeconds * 1000
577
+ this.clockSkew = 0
578
+ &nbsp;
579
+ this.events = events
580
+ &nbsp;
581
+ this.getTimeCommand = plans.getTime(config.schema)
582
+ this.getSchedulesCommand = plans.getSchedules(config.schema)
583
+ this.scheduleCommand = plans.schedule(config.schema)
584
+ this.unscheduleCommand = plans.unschedule(config.schema)
585
+ this.getCronTimeCommand = plans.getCronTime(config.schema)
586
+ this.setCronTimeCommand = plans.setCronTime(config.schema)
587
+ &nbsp;
588
+ this.functions = [
589
+ this.schedule,
590
+ this.unschedule,
591
+ this.getSchedules
592
+ ]
593
+ &nbsp;
594
+ this.stopped = true
595
+ }
596
+ &nbsp;
597
+ async start () {
598
+ // setting the archive config too low breaks the cron 60s debounce interval so don't even try
599
+ if (this.config.archiveSeconds &lt; 60 || this.config.archiveFailedSeconds &lt; 60) {
600
+ return
601
+ }
602
+ &nbsp;
603
+ // cache the clock skew from the db server
604
+ await this.cacheClockSkew()
605
+ &nbsp;
606
+ await this.manager.work(queues.CRON, { newJobCheckIntervalSeconds: this.config.cronWorkerIntervalSeconds }, (job) =&gt; this.onCron(job))
607
+ await this.manager.work(queues.SEND_IT, { newJobCheckIntervalSeconds: this.config.cronWorkerIntervalSeconds, teamSize: 50, teamConcurrency: 5 }, (job) =&gt; this.onSendIt(job))
608
+ &nbsp;
609
+ // uses sendDebounced() to enqueue a cron check
610
+ await this.checkSchedulesAsync()
611
+ &nbsp;
612
+ // create monitoring interval to make sure cron hasn't crashed
613
+ this.cronMonitorInterval = setInterval(async () =&gt; await this.monitorCron(), this.cronMonitorIntervalMs)
614
+ // create monitoring interval to measure and adjust for drift in clock skew
615
+ this.skewMonitorInterval = setInterval(async () =&gt; await this.cacheClockSkew(), this.skewMonitorIntervalMs)
616
+ &nbsp;
617
+ this.stopped = false
618
+ }
619
+ &nbsp;
620
+ async stop () {
621
+ if (this.stopped) {
622
+ return
623
+ }
624
+ &nbsp;
625
+ this.stopped = true
626
+ &nbsp;
627
+ await this.manager.offWork(queues.CRON)
628
+ await this.manager.offWork(queues.SEND_IT)
629
+ &nbsp;
630
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (this.skewMonitorInterval) {
631
+ clearInterval(this.skewMonitorInterval)
632
+ this.skewMonitorInterval = null
633
+ }
634
+ &nbsp;
635
+ <span class="missing-if-branch" title="else path not taken" >E</span>if (this.cronMonitorInterval) {
636
+ clearInterval(this.cronMonitorInterval)
637
+ this.cronMonitorInterval = null
638
+ }
639
+ }
640
+ &nbsp;
641
+ async monitorCron () {
642
+ try {
643
+ if (this.config.__test__force_cron_monitoring_error) {
644
+ throw new Error(this.config.__test__force_cron_monitoring_error)
645
+ }
646
+ &nbsp;
647
+ const { secondsAgo } = await this.getCronTime()
648
+ &nbsp;
649
+ if (secondsAgo &gt; 60) {
650
+ await this.checkSchedulesAsync()
651
+ }
652
+ } catch (err) {
653
+ this.emit(this.events.error, err)
654
+ }
655
+ }
656
+ &nbsp;
657
+ async cacheClockSkew () {
658
+ let skew = 0
659
+ &nbsp;
660
+ try {
661
+ if (this.config.__test__force_clock_monitoring_error) {
662
+ throw new Error(this.config.__test__force_clock_monitoring_error)
663
+ }
664
+ &nbsp;
665
+ const { rows } = await this.db.executeSql(this.getTimeCommand)
666
+ &nbsp;
667
+ const local = Date.now()
668
+ &nbsp;
669
+ const dbTime = parseFloat(rows[0].time)
670
+ &nbsp;
671
+ skew = dbTime - local
672
+ &nbsp;
673
+ const skewSeconds = Math.abs(skew) / 1000
674
+ &nbsp;
675
+ if (skewSeconds &gt;= 60 || this.config.__test__force_clock_skew_warning) {
676
+ Attorney.warnClockSkew(`Instance clock is ${skewSeconds}s ${skew &gt; 0 ? <span class="branch-0 cbranch-no" title="branch not covered" >'slower' </span>: 'faster'} than database.`)
677
+ }
678
+ } catch (err) {
679
+ this.emit(this.events.error, err)
680
+ } finally {
681
+ this.clockSkew = skew
682
+ }
683
+ }
684
+ &nbsp;
685
+ async checkSchedulesAsync () {
686
+ const opts = {
687
+ retryLimit: 2,
688
+ retentionSeconds: 60,
689
+ onComplete: false
690
+ }
691
+ &nbsp;
692
+ await this.manager.sendDebounced(queues.CRON, null, opts, 60)
693
+ }
694
+ &nbsp;
695
+ async onCron () {
696
+ if (this.stopped) return
697
+ &nbsp;
698
+ try {
699
+ if (this.config.__test__throw_clock_monitoring) {
700
+ throw new Error(this.config.__test__throw_clock_monitoring)
701
+ }
702
+ &nbsp;
703
+ const items = await this.getSchedules()
704
+ &nbsp;
705
+ const sending = items.filter(i =&gt; this.shouldSendIt(i.cron, i.timezone))
706
+ &nbsp;
707
+ if (sending.length &amp;&amp; !this.stopped) {
708
+ await pMap(sending, it =&gt; this.send(it), { concurrency: 5 })
709
+ }
710
+ &nbsp;
711
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (this.stopped) <span class="cstat-no" title="statement not covered" >return</span>
712
+ &nbsp;
713
+ // set last time cron was evaluated for downstream usage in cron monitoring
714
+ await this.setCronTime()
715
+ } catch (err) {
716
+ this.emit(this.events.error, err)
717
+ }
718
+ &nbsp;
719
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (this.stopped) <span class="cstat-no" title="statement not covered" >return</span>
720
+ &nbsp;
721
+ // uses sendDebounced() to enqueue a cron check
722
+ await this.checkSchedulesAsync()
723
+ }
724
+ &nbsp;
725
+ shouldSendIt (cron, tz) {
726
+ const interval = cronParser.parseExpression(cron, { tz })
727
+ &nbsp;
728
+ const prevTime = interval.prev()
729
+ &nbsp;
730
+ const databaseTime = Date.now() + this.clockSkew
731
+ &nbsp;
732
+ const prevDiff = (databaseTime - prevTime.getTime()) / 1000
733
+ &nbsp;
734
+ return prevDiff &lt; 60
735
+ }
736
+ &nbsp;
737
+ async send (job) {
738
+ const options = {
739
+ singletonKey: job.name,
740
+ singletonSeconds: 60,
741
+ onComplete: false
742
+ }
743
+ &nbsp;
744
+ await this.manager.send(queues.SEND_IT, job, options)
745
+ }
746
+ &nbsp;
747
+ async onSendIt (job) {
748
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (this.stopped) <span class="cstat-no" title="statement not covered" >return</span>
749
+ const { name, data, options } = job.data
750
+ await this.manager.send(name, data, options)
751
+ }
752
+ &nbsp;
753
+ async getSchedules () {
754
+ const { rows } = await this.db.executeSql(this.getSchedulesCommand)
755
+ return rows
756
+ }
757
+ &nbsp;
758
+ async schedule (name, cron, data, options = {}) {
759
+ const { tz = 'UTC' } = options
760
+ &nbsp;
761
+ cronParser.parseExpression(cron, { tz })
762
+ &nbsp;
763
+ // validation pre-check
764
+ Attorney.checkSendArgs([name, data, options], this.config)
765
+ &nbsp;
766
+ const values = [name, cron, tz, data, options]
767
+ &nbsp;
768
+ const result = await this.db.executeSql(this.scheduleCommand, values)
769
+ &nbsp;
770
+ return result ? result.rowCount : <span class="branch-1 cbranch-no" title="branch not covered" >null</span>
771
+ }
772
+ &nbsp;
773
+ async unschedule (name) {
774
+ const result = await this.db.executeSql(this.unscheduleCommand, [name])
775
+ return result ? result.rowCount : <span class="branch-1 cbranch-no" title="branch not covered" >null</span>
776
+ }
777
+ &nbsp;
778
+ async setCronTime () {
779
+ await this.db.executeSql(this.setCronTimeCommand)
780
+ }
781
+ &nbsp;
782
+ async getCronTime () {
783
+ const { rows } = await this.db.executeSql(this.getCronTimeCommand)
784
+ &nbsp;
785
+ let { cron_on: cronOn, seconds_ago: secondsAgo } = rows[0]
786
+ &nbsp;
787
+ secondsAgo = secondsAgo !== null ? parseFloat(secondsAgo) : <span class="branch-1 cbranch-no" title="branch not covered" >61</span>
788
+ &nbsp;
789
+ return { cronOn, secondsAgo }
790
+ }
791
+ }
792
+ &nbsp;
793
+ module.exports = Timekeeper
794
+ module.exports.QUEUES = queues
795
+ &nbsp;</pre></td></tr></table></pre>
796
+
797
+ <div class='push'></div><!-- for sticky footer -->
798
+ </div><!-- /wrapper -->
799
+ <div class='footer quiet pad2 space-top1 center small'>
800
+ Code coverage generated by
801
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
802
+ at 2023-07-02T21:44:11.859Z
803
+ </div>
804
+ <script src="prettify.js"></script>
805
+ <script>
806
+ window.onload = function () {
807
+ prettyPrint();
808
+ };
809
+ </script>
810
+ <script src="sorter.js"></script>
811
+ <script src="block-navigation.js"></script>
812
+ </body>
813
+ </html>
814
+