feat(r): retry configuration for status codes (#5925)

* feat(r): retry configuration for status codes

* fix(r) : fixing review comments
This commit is contained in:
Ramanth Addala 2020-09-08 12:04:32 +05:30 committed by GitHub
parent f9514705a1
commit c39aef2a79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 82 additions and 2 deletions

View File

@ -24,6 +24,8 @@
#' @field apiKeys #' @field apiKeys
#' @field accessToken #' @field accessToken
#' @field timeout Default timeout in seconds #' @field timeout Default timeout in seconds
#' @field retryStatusCodes vector of status codes to retry
#' @field maxRetryAttempts maximum number of retries for the status codes
#' @importFrom httr add_headers accept timeout content #' @importFrom httr add_headers accept timeout content
{{#useRlangExceptionHandling}} {{#useRlangExceptionHandling}}
#' @importFrom rlang abort #' @importFrom rlang abort
@ -48,8 +50,12 @@ ApiClient <- R6::R6Class(
accessToken = NULL, accessToken = NULL,
# Time Out (seconds) # Time Out (seconds)
timeout = NULL, timeout = NULL,
# Vector of status codes to retry
retryStatusCodes=NULL,
# Maximum number of retry attempts for the retry status codes
maxRetryAttempts = NULL,
# constructor # constructor
initialize = function(basePath=NULL, userAgent=NULL, defaultHeaders=NULL, username=NULL, password=NULL, apiKeys=NULL, accessToken=NULL, timeout=NULL){ initialize = function(basePath=NULL, userAgent=NULL, defaultHeaders=NULL, username=NULL, password=NULL, apiKeys=NULL, accessToken=NULL, timeout=NULL, retryStatusCodes=NULL, maxRetryAttempts=NULL){
if (!is.null(basePath)) { if (!is.null(basePath)) {
self$basePath <- basePath self$basePath <- basePath
} }
@ -83,8 +89,42 @@ ApiClient <- R6::R6Class(
if (!is.null(timeout)) { if (!is.null(timeout)) {
self$timeout <- timeout self$timeout <- timeout
} }
if (!is.null(retryStatusCodes)) {
self$retryStatusCodes <- retryStatusCodes
}
if (!is.null(maxRetryAttempts)) {
self$maxRetryAttempts <- maxRetryAttempts
}
}, },
CallApi = function(url, method, queryParams, headerParams, body, ...){ CallApi = function(url, method, queryParams, headerParams, body, ...){
resp <- self$Execute(url, method, queryParams, headerParams, body, ...)
statusCode <- httr::status_code(resp)
if (is.null(self$maxRetryAttempts)) {
self$maxRetryAttempts = 3
}
if (!is.null(self$retryStatusCodes)) {
for (i in 1 : self$maxRetryAttempts) {
if (statusCode %in% self$retryStatusCodes) {
Sys.sleep((2 ^ i) + stats::runif(n = 1, min = 0, max = 1))
resp <- self$Execute(url, method, queryParams, headerParams, body, ...)
statusCode <- httr::status_code(resp)
} else {
break;
}
}
}
resp
},
Execute = function(url, method, queryParams, headerParams, body, ...){
headers <- httr::add_headers(c(headerParams, self$defaultHeaders)) headers <- httr::add_headers(c(headerParams, self$defaultHeaders))
{{! Adding timeout that can be set at the apiClient object level}} {{! Adding timeout that can be set at the apiClient object level}}

View File

@ -31,6 +31,8 @@
#' @field apiKeys #' @field apiKeys
#' @field accessToken #' @field accessToken
#' @field timeout Default timeout in seconds #' @field timeout Default timeout in seconds
#' @field retryStatusCodes vector of status codes to retry
#' @field maxRetryAttempts maximum number of retries for the status codes
#' @importFrom httr add_headers accept timeout content #' @importFrom httr add_headers accept timeout content
#' @export #' @export
ApiClient <- R6::R6Class( ApiClient <- R6::R6Class(
@ -52,8 +54,12 @@ ApiClient <- R6::R6Class(
accessToken = NULL, accessToken = NULL,
# Time Out (seconds) # Time Out (seconds)
timeout = NULL, timeout = NULL,
# Vector of status codes to retry
retryStatusCodes=NULL,
# Maximum number of retry attempts for the retry status codes
maxRetryAttempts = NULL,
# constructor # constructor
initialize = function(basePath=NULL, userAgent=NULL, defaultHeaders=NULL, username=NULL, password=NULL, apiKeys=NULL, accessToken=NULL, timeout=NULL){ initialize = function(basePath=NULL, userAgent=NULL, defaultHeaders=NULL, username=NULL, password=NULL, apiKeys=NULL, accessToken=NULL, timeout=NULL, retryStatusCodes=NULL, maxRetryAttempts=NULL){
if (!is.null(basePath)) { if (!is.null(basePath)) {
self$basePath <- basePath self$basePath <- basePath
} }
@ -87,8 +93,42 @@ ApiClient <- R6::R6Class(
if (!is.null(timeout)) { if (!is.null(timeout)) {
self$timeout <- timeout self$timeout <- timeout
} }
if (!is.null(retryStatusCodes)) {
self$retryStatusCodes <- retryStatusCodes
}
if (!is.null(maxRetryAttempts)) {
self$maxRetryAttempts <- maxRetryAttempts
}
}, },
CallApi = function(url, method, queryParams, headerParams, body, ...){ CallApi = function(url, method, queryParams, headerParams, body, ...){
resp <- self$Execute(url, method, queryParams, headerParams, body, ...)
statusCode <- httr::status_code(resp)
if (is.null(self$maxRetryAttempts)) {
self$maxRetryAttempts = 3
}
if (!is.null(self$retryStatusCodes)) {
for (i in 1 : self$maxRetryAttempts) {
if (statusCode %in% self$retryStatusCodes) {
Sys.sleep((2 ^ i) + stats::runif(n = 1, min = 0, max = 1))
resp <- self$Execute(url, method, queryParams, headerParams, body, ...)
statusCode <- httr::status_code(resp)
} else {
break;
}
}
}
resp
},
Execute = function(url, method, queryParams, headerParams, body, ...){
headers <- httr::add_headers(c(headerParams, self$defaultHeaders)) headers <- httr::add_headers(c(headerParams, self$defaultHeaders))
httpTimeout <- NULL httpTimeout <- NULL