public async Task <T> Run <T>(BizwebRequestMessage baseReqMsg, ExecuteRequestAsync <T> executeRequestAsync) { var accessToken = GetAccessToken(baseReqMsg); LeakyBucket bucket = null; if (accessToken != null) { bucket = LeakyBucket.GetBucketByToken(accessToken); } while (true) { using (var reqMsg = baseReqMsg.Clone()) { if (accessToken != null) { await bucket.GrantAsync(); } try { var fullResult = await executeRequestAsync(reqMsg); var bucketState = GetBucketState(fullResult.Response); var reportedFillLevel = bucketState.Item1; var reportedCapacity = bucketState.Item2; if (reportedFillLevel != null && reportedCapacity != null) { bucket?.SetBucketState(reportedFillLevel.Value, reportedCapacity.Value); } return(fullResult.Result); } catch (BizwebSharpException) { //An exception may still occur: //-Shopify may have a slightly different algorithm //-Shopify may change to a different algorithm in the future //-There may be timing and latency delays //-Multiple programs may use the same access token //-Multiple instances of the same program may use the same access token await Task.Delay(THROTTLE_DELAY); } } } }