Example #1
0
        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);
                    }
                }
            }
        }