private async Task <ArraySegment <byte> > InternalExecuteAsync(FormattedRoute route, IRestRequestContent content, IRestRequestOptions options) { var request = new DefaultRestRequest(route, content, options); if (options is DefaultRestRequestOptions defaultOptions) { defaultOptions.RequestAction?.Invoke(request); } await RateLimiter.EnqueueRequestAsync(request).ConfigureAwait(false); var response = await request.WaitAsync().ConfigureAwait(false); using (var jsonStream = await response.HttpResponse.ReadAsync().ConfigureAwait(false)) { var stream = new MemoryStream((int)jsonStream.Length); await jsonStream.CopyToAsync(stream).ConfigureAwait(false); stream.TryGetBuffer(out var buffer); if (!IsValidResponse(response)) { var errorModel = Serializer.Deserialize <RestApiErrorJsonModel>(buffer); throw new RestApiException(response.HttpResponse.Code, errorModel); } return(buffer); } }
public Bucket(DefaultRestRateLimiter rateLimiter, FormattedRoute route, bool isUnlimited) { _rateLimiter = rateLimiter; _route = route.ToString(); _isUnlimited = isUnlimited; _requests = Channel.CreateUnbounded <IRestRequest>(); _ = RunAsync(); }
public DefaultRestRequest(FormattedRoute route, IRestRequestContent content = null, IRestRequestOptions options = null) { Guard.IsNotNull(route); Route = route; Content = content; Options = options; _tcs = new Tcs <IRestResponse>(); }
public async Task <TModel> ExecuteAsync <TModel>(FormattedRoute route, IRestRequestContent content = null, IRestRequestOptions options = null) where TModel : class { var buffer = await InternalExecuteAsync(route, content, options ?? new DefaultRestRequestOptions()).ConfigureAwait(false); if (typeof(TModel) == typeof(string)) { return((TModel)(object)Encoding.UTF8.GetString(buffer)); } return(Serializer.Deserialize <TModel>(buffer)); }
public DefaultRestRequest(FormattedRoute route, IRestRequestContent content, IRestRequestOptions options = null) { if (route == null) { throw new ArgumentNullException(nameof(route)); } Route = route; Content = content; Options = options; _tcs = new TaskCompletionSource <IRestResponse>(TaskCreationOptions.RunContinuationsAsynchronously); }
public async Task <TModel> ExecuteAsync <TModel>(FormattedRoute route, IRestRequestContent content = null, IRestRequestOptions options = null, CancellationToken cancellationToken = default) where TModel : class { await using (var jsonStream = await InternalExecuteAsync(route, content, options).ConfigureAwait(false)) { if (typeof(TModel) == typeof(string)) { var reader = new StreamReader(jsonStream, Encoding.UTF8); return(Unsafe.As <TModel>(await reader.ReadToEndAsync().ConfigureAwait(false))); } return(Serializer.Deserialize <TModel>(jsonStream)); } }
/// <inheritdoc/> public bool IsRateLimited(FormattedRoute route = null) { if (route == null) { return(_globalResetsAt > DateTimeOffset.UtcNow); } var bucket = GetBucket(route, false); if (bucket == null) { return(false); } return(bucket.Remaining == 0); }
private async ValueTask <Stream> InternalExecuteAsync(FormattedRoute route, IRestRequestContent content, IRestRequestOptions options) { content?.Validate(); var request = new DefaultRestRequest(route, content, options); var defaultOptions = options as DefaultRestRequestOptions; defaultOptions?.RequestAction?.Invoke(request); await RateLimiter.EnqueueRequestAsync(request).ConfigureAwait(false); var response = await request.WaitForCompletionAsync().ConfigureAwait(false); defaultOptions?.HeadersAction?.Invoke(new DefaultRestResponseHeaders(response.HttpResponse.Headers)); var responseStream = await response.HttpResponse.ReadAsync().ConfigureAwait(false); var statusCode = (int)response.HttpResponse.Code; if (statusCode > 199 && statusCode < 300) { return(responseStream); } if (statusCode > 499 && statusCode < 600) { throw new RestApiException(response.HttpResponse.Code, response.HttpResponse.ReasonPhrase, null); } RestApiErrorJsonModel errorModel = null; try { errorModel = Serializer.Deserialize <RestApiErrorJsonModel>(responseStream); } catch (Exception ex) { Logger.LogError(ex, "An exception occurred while attempting to deserialize the error model."); } finally { await responseStream.DisposeAsync().ConfigureAwait(false); } throw new RestApiException(response.HttpResponse.Code, response.HttpResponse.ReasonPhrase, errorModel); }
public bool IsRateLimited(FormattedRoute route = null) { // TODO: proper global handling if (route == null) { return(false); } var bucket = GetBucket(route, false); if (bucket == null) { return(false); } return(bucket.Remaining == 0); }
private async ValueTask <Stream> InternalExecuteAsync(FormattedRoute route, IRestRequestContent content, IRestRequestOptions options) { var request = new DefaultRestRequest(route, content, options); var defaultOptions = options as DefaultRestRequestOptions; defaultOptions?.RequestAction?.Invoke(request); await RateLimiter.EnqueueRequestAsync(request).ConfigureAwait(false); var response = await request.WaitAsync().ConfigureAwait(false); defaultOptions?.HeadersAction?.Invoke(new DefaultRestResponseHeaders(response.HttpResponse.Headers)); var jsonStream = await response.HttpResponse.ReadAsync().ConfigureAwait(false); if (IsValidResponse(response)) { return(jsonStream); } await using (jsonStream) { var errorModel = Serializer.Deserialize <RestApiErrorJsonModel>(jsonStream); throw new RestApiException(response.HttpResponse.Code, errorModel); } }
/// <inheritdoc/> public async Task ExecuteAsync(FormattedRoute route, IRestRequestContent content = null, IRestRequestOptions options = null, CancellationToken cancellationToken = default) { var stream = await InternalExecuteAsync(route, content, options ?? new DefaultRestRequestOptions()).ConfigureAwait(false); await stream.DisposeAsync().ConfigureAwait(false); }
public async Task ExecuteAsync(FormattedRoute route, IRestRequestContent content = null, IRestRequestOptions options = null) { await InternalExecuteAsync(route, content, options ?? new DefaultRestRequestOptions()).ConfigureAwait(false); }