/// <inheritdoc /> public async Task <Bucket> GetBucketAndWaitForAvailability(Request request, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); await timerFactory.CreateJitter(cancellationToken); var bucket = await repository.FindByEndpointAndMajorParameters(request.Endpoint, request.Parameters, cancellationToken); bucket ??= await CreateBucket(request, cancellationToken); if (bucket.HitsRemaining <= 1) { var delay = (int)Math.Ceiling((bucket.ResetAfter - DateTimeOffset.Now).TotalMilliseconds); delay = Math.Max(delay, 100); await timerFactory.CreateDelay(delay, cancellationToken); bucket.HitsRemaining++; } bucket.HitsRemaining--; return(bucket); }
public async Task ShouldCreateNewBucketIfOneWasntFound( Request request, [Frozen, Substitute] IBucketRepository repository, [Target] DefaultBucketService service, CancellationToken cancellationToken ) { var resetAfter = DateTimeOffset.Now; repository.FindByEndpointAndMajorParameters(Any <Endpoint>(), Any <MajorParameters>(), Any <CancellationToken>()).Returns((Bucket?)null); await service.GetBucketAndWaitForAvailability(request, cancellationToken); await repository.Received().Add( Is <Bucket>(bucket => bucket.Endpoints == Convert.ToUInt64(request.Endpoint.Value) && bucket.ApiCategory == request.Endpoint.Category && bucket.MajorParameters == request.Parameters && bucket.HitsRemaining == 1 && bucket.ResetAfter >= resetAfter ), Is(cancellationToken) ); }