Beispiel #1
0
        public Task <BoolResult> RegisterCheckpointAsync(OperationContext context, CheckpointState checkpointState)
        {
            TriggerGarbageCollection(context);

            var msg = checkpointState.ToString();

            return(context.PerformOperationWithTimeoutAsync(
                       Tracer,
                       context =>
            {
                var blobName = GenerateBlobName();
                checkpointState.Consumers.TryAdd(_primaryMachineLocation);
                if (_configuration.WriteLegacyFormat)
                {
                    return _storage.WriteAsync(context, blobName, JsonSerializer.Serialize(checkpointState, _jsonSerializerOptions));
                }
                else
                {
                    return _storage.WriteAsync(context, blobName, checkpointState);
                }
            },
                       traceOperationStarted: false,
                       extraStartMessage: msg,
                       extraEndMessage: _ => msg,
                       timeout: _configuration.RegisterCheckpointTimeout));
        }
Beispiel #2
0
        internal Task <BoolResult> GarbageCollectAsync(OperationContext context, int retentionLimit)
        {
            Contract.Requires(retentionLimit >= 0);

            return(context.PerformOperationWithTimeoutAsync(
                       Tracer,
                       async context =>
            {
                var blobs = ListBlobsRecentFirstAsync(context)
                            .Skip(retentionLimit);

                await foreach (var blob in blobs)
                {
                    try
                    {
                        var deleteSucceeded = await _storage.DeleteIfExistsAsync(context, blob);
                        Tracer.Info(context, $"Delete attempt Name=[{blob.Name}] Succeeded=[{deleteSucceeded}]");
                    }
                    catch (Exception e)
                    {
                        Tracer.Error(context, e, $"Delete attempt Name=[{blob.Name}]");
                    }
                }

                return BoolResult.Success;
            },
                       timeout: _configuration.GarbageCollectionTimeout));
        }
Beispiel #3
0
        public Task <Result <CheckpointState> > GetCheckpointStateAsync(OperationContext context)
        {
            // NOTE: this function is naturally retried by the heartbeat mechanisms in LLS
            return(context.PerformOperationWithTimeoutAsync(
                       Tracer,
                       async context =>
            {
                var blobs = ListBlobsRecentFirstAsync(context);

                await foreach (var blob in blobs)
                {
                    try
                    {
                        var checkpointState = await _storage.ReadAsync <CheckpointState>(context, blob).ThrowIfFailureAsync();
                        checkpointState.FileName = blob;

                        foreach (var consumer in checkpointState.Consumers)
                        {
                            _pushLocations.Add(consumer, _configuration.PushCheckpointCandidateExpiry);
                        }

                        return Result.Success(checkpointState);
                    }
                    catch (TaskCanceledException) when(context.Token.IsCancellationRequested)
                    {
                        // We hit timeout or a proper cancellation.
                        // Breaking from the loop instead of tracing error for each iteration.
                        break;
                    }
                    catch (Exception e)
                    {
                        Tracer.Error(context, e, $"Failed to obtain {nameof(CheckpointState)} from blob `{blob.Name}`. Skipping.");
                        continue;
                    }
                }

                // Add slack for start cursor to account for clock skew
                return CheckpointState.CreateUnavailable(_clock.UtcNow - _configuration.NewEpochEventStartCursorDelay);
            },
                       extraEndMessage: result =>
            {
                if (!result.Succeeded)
                {
                    return string.Empty;
                }

                var checkpointState = result.Value;
                return $"CheckpointId=[{checkpointState.CheckpointId}] SequencePoint=[{checkpointState.StartSequencePoint}]";
            },
                       timeout: _configuration.CheckpointStateTimeout));
        }