7
7
# '
8
8
# ' While running, you'll get a progress bar that looks like:
9
9
# ' `[working] (1 + 4) -> 5 -> 5`. The string tells you the current status of
10
- # ' the queue (e.g. working, waiting, errored, finishing ) followed by (the
10
+ # ' the queue (e.g. working, waiting, errored) followed by (the
11
11
# ' number of pending requests + pending retried requests) -> the number of
12
12
# ' active requests -> the number of complete requests.
13
13
# '
24
24
# '
25
25
# ' Additionally, it does not respect the `max_tries` argument to `req_retry()`
26
26
# ' because if you have five requests in flight and the first one gets rate
27
- # ' limited, it's likely that all the others do too.
27
+ # ' limited, it's likely that all the others do too. This also means that
28
+ # ' the circuit breaker is never triggered.
28
29
# '
29
30
# ' @inherit req_perform_sequential params return
30
31
# ' @param pool `r lifecycle::badge("deprecated")`. No longer supported;
@@ -154,7 +155,7 @@ RequestQueue <- R6::R6Class(
154
155
total = n ,
155
156
format = paste0(
156
157
" [{self$queue_status}] " ,
157
- " ({self$n_pending} + {self$n_retried }) -> {self$n_active} -> {self$n_complete} | " ,
158
+ " ({self$n_pending} + {self$n_retries }) -> {self$n_active} -> {self$n_complete} | " ,
158
159
" {cli::pb_bar} {cli::pb_percent}"
159
160
),
160
161
.envir = error_call
@@ -209,67 +210,58 @@ RequestQueue <- R6::R6Class(
209
210
# Exposed for testing, so we can manaully work through one step at a time
210
211
process1 = function (deadline = Inf ) {
211
212
if (self $ queue_status == " done" ) {
212
- FALSE
213
- } else if (self $ queue_status == " waiting" ) {
213
+ return (FALSE )
214
+ }
215
+
216
+ if (! is.null(self $ progress )) {
217
+ cli :: cli_progress_update(id = self $ progress , set = self $ n_complete )
218
+ }
219
+
220
+ if (self $ queue_status == " waiting" ) {
214
221
request_deadline <- max(self $ token_deadline , self $ rate_limit_deadline )
215
- if (request_deadline < = deadline ) {
216
- # Assume we're done waiting; done_failure() will reset if needed
222
+ if (request_deadline < = unix_time()) {
217
223
self $ queue_status <- " working"
218
- pool_wait_for_deadline(self $ pool , request_deadline )
219
- NULL
224
+ return ()
225
+ }
226
+
227
+ if (self $ rate_limit_deadline > self $ token_deadline ) {
228
+ waiting <- " for rate limit"
220
229
} else {
221
- pool_wait_for_deadline(self $ pool , deadline )
222
- TRUE
230
+ waiting <- " for throttling"
223
231
}
232
+ pool_wait_for_deadline(self $ pool , min(request_deadline , deadline ), waiting )
233
+ NULL
224
234
} else if (self $ queue_status == " working" ) {
225
- if (self $ n_pending == 0 ) {
226
- self $ queue_status <- " finishing "
227
- } else if (self $ n_active < self $ max_active ) {
235
+ if (self $ n_pending == 0 && self $ n_active == 0 ) {
236
+ self $ queue_status <- " done "
237
+ } else if (self $ n_pending > 0 && self $ n_active < = self $ max_active ) {
228
238
if (! self $ submit_next(deadline )) {
229
239
self $ queue_status <- " waiting"
230
240
}
231
241
} else {
232
242
pool_wait_for_one(self $ pool , deadline )
233
243
}
234
244
NULL
235
- } else if (self $ queue_status == " finishing" ) {
236
- pool_wait_for_one(self $ pool , deadline )
237
-
238
- if (self $ rate_limit_deadline > unix_time()) {
239
- self $ queue_status <- " waiting"
240
- } else if (self $ n_pending > 0 ) {
241
- # we had to retry
242
- self $ queue_status <- " working"
243
- } else if (self $ n_active > 0 ) {
244
- # keep going
245
- self $ queue_status <- " finishing"
245
+ } else if (self $ queue_status == " errored" ) {
246
+ # Finish out any active requests but don't add any more
247
+ if (self $ n_active > 0 ) {
248
+ pool_wait_for_one(self $ pool , deadline )
246
249
} else {
247
250
self $ queue_status <- " done"
248
251
}
249
252
NULL
250
- } else if (self $ queue_status == " errored" ) {
251
- # Finish out any active request but don't add any more
252
- pool_wait_for_one(self $ pool , deadline )
253
- self $ queue_status <- if (self $ n_active > 0 ) " errored" else " done"
254
- NULL
255
253
}
256
254
},
257
255
258
256
submit_next = function (deadline ) {
259
- next_i <- which(self $ status == " pending" )[[1 ]]
257
+ i <- which(self $ status == " pending" )[[1 ]]
260
258
261
- self $ token_deadline <- throttle_deadline(self $ reqs [[next_i ]])
259
+ self $ token_deadline <- throttle_deadline(self $ reqs [[i ]])
262
260
if (self $ token_deadline > unix_time()) {
263
- throttle_return_token(self $ reqs [[next_i ]])
261
+ throttle_return_token(self $ reqs [[i ]])
264
262
return (FALSE )
265
263
}
266
264
267
- self $ submit(next_i )
268
- },
269
-
270
- submit = function (i ) {
271
- retry_check_breaker(self $ reqs [[i ]], self $ tries [[i ]], error_call = error_call )
272
-
273
265
self $ set_status(i , " active" )
274
266
self $ resps [i ] <- list (NULL )
275
267
self $ tries [[i ]] <- self $ tries [[i ]] + 1
@@ -305,6 +297,7 @@ RequestQueue <- R6::R6Class(
305
297
306
298
self $ set_status(i , " pending" )
307
299
self $ n_retries <- self $ n_retries + 1
300
+ self $ queue_status <- " waiting"
308
301
} else if (resp_is_invalid_oauth_token(req , resp ) && self $ can_reauth(i )) {
309
302
# This isn't quite right, because if there are (e.g.) four requests in
310
303
# the queue and the first one fails, we'll clear the cache for all four,
@@ -336,10 +329,6 @@ RequestQueue <- R6::R6Class(
336
329
)
337
330
338
331
self $ status [[i ]] <- status
339
-
340
- if (! is.null(self $ progress )) {
341
- cli :: cli_progress_update(id = self $ progress , set = self $ n_complete )
342
- }
343
332
},
344
333
345
334
can_retry = function (i ) {
@@ -357,7 +346,7 @@ pool_wait_for_one <- function(pool, deadline) {
357
346
pool_wait(pool , poll = TRUE , timeout = timeout )
358
347
}
359
348
360
- pool_wait_for_deadline <- function (pool , deadline ) {
349
+ pool_wait_for_deadline <- function (pool , deadline , waiting_for ) {
361
350
now <- unix_time()
362
351
timeout <- deadline - now
363
352
if (timeout < = 0 ) {
@@ -368,8 +357,10 @@ pool_wait_for_deadline <- function(pool, deadline) {
368
357
369
358
# pool might finish early; we still want to wait out the full time
370
359
remaining <- timeout - (unix_time() - now )
371
- if (remaining > 0 ) {
372
- # cat("Sleeping for ", remaining, " seconds\n", sep = "")
360
+ if (remaining > 2 ) {
361
+ # Use a progress bar
362
+ sys_sleep(remaining , waiting_for )
363
+ } else if (remaining > 0 ) {
373
364
Sys.sleep(remaining )
374
365
}
375
366
0 commit comments