@@ -128,9 +128,19 @@ export class Queue {
128
128
* queue.start() will return early with a false boolean value instead
129
129
* of running multiple queue processing loops concurrently.
130
130
*
131
+ * Lifespan can be passed to start() in order to run the queue for a specific amount of time before stopping.
132
+ * This is useful, as an example, for OS background tasks which typically are time limited.
133
+ *
134
+ * NOTE: If lifespan is set, only jobs with a timeout property at least 500ms less than remaining lifespan will be processed
135
+ * during queue processing lifespan. This is to buffer for the small amount of time required to query Realm for suitable
136
+ * jobs, and to mark such jobs as complete or failed when job finishes processing.
137
+ *
138
+ * IMPORTANT: Jobs with timeout set to 0 that run indefinitely will not be processed if the queue is running with a lifespan.
139
+ *
140
+ * @param lifespan {number} - If lifespan is passed, the queue will start up and run for lifespan ms, then queue will be stopped.
131
141
* @return {boolean|undefined } - False if queue is already started. Otherwise nothing is returned when queue finishes processing.
132
142
*/
133
- async start ( ) {
143
+ async start ( lifespan = 0 ) {
134
144
135
145
// If queue is already running, don't fire up concurrent loop.
136
146
if ( this . status == 'active' ) {
@@ -139,7 +149,18 @@ export class Queue {
139
149
140
150
this . status = 'active' ;
141
151
142
- let concurrentJobs = await this . getConcurrentJobs ( ) ;
152
+ // Get jobs to process
153
+ const startTime = Date . now ( ) ;
154
+ let lifespanRemaining = null ;
155
+ let concurrentJobs = [ ] ;
156
+
157
+ if ( lifespan !== 0 ) {
158
+ lifespanRemaining = lifespan - ( Date . now ( ) - startTime ) ;
159
+ lifespanRemaining = ( lifespanRemaining === 0 ) ? - 1 : lifespanRemaining ; // Handle exactly zero lifespan remaining edge case.
160
+ concurrentJobs = await this . getConcurrentJobs ( lifespanRemaining ) ;
161
+ } else {
162
+ concurrentJobs = await this . getConcurrentJobs ( ) ;
163
+ }
143
164
144
165
while ( this . status == 'active' && concurrentJobs . length ) {
145
166
@@ -153,7 +174,13 @@ export class Queue {
153
174
await Promise . all ( processingJobs . map ( promiseReflect ) ) ;
154
175
155
176
// Get next batch of jobs.
156
- concurrentJobs = await this . getConcurrentJobs ( ) ;
177
+ if ( lifespan !== 0 ) {
178
+ lifespanRemaining = lifespan - ( Date . now ( ) - startTime ) ;
179
+ lifespanRemaining = ( lifespanRemaining === 0 ) ? - 1 : lifespanRemaining ; // Handle exactly zero lifespan remaining edge case.
180
+ concurrentJobs = await this . getConcurrentJobs ( lifespanRemaining ) ;
181
+ } else {
182
+ concurrentJobs = await this . getConcurrentJobs ( ) ;
183
+ }
157
184
158
185
}
159
186
0 commit comments