/// <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);
        }
Ejemplo n.º 2
0
            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)
                    );
            }