dotnet-cqrs/Svrnty.CQRS.Events.Grpc/GrpcEventDeliveryProvider.cs

105 lines
3.2 KiB
C#

using System;
using Svrnty.CQRS.Events.Abstractions.Delivery;
using Svrnty.CQRS.Events.Abstractions.EventStore;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Svrnty.CQRS.Events.Abstractions;
namespace Svrnty.CQRS.Events.Grpc;
/// <summary>
/// gRPC-based event delivery provider for push-based streaming.
/// </summary>
/// <remarks>
/// <para>
/// <strong>Phase 1.7 Implementation:</strong>
/// This provider integrates with <see cref="EventServiceImpl"/> to enable
/// push-based event delivery over gRPC bidirectional streams.
/// </para>
/// <para>
/// <strong>Current Behavior:</strong>
/// - Tracks active gRPC connections via EventServiceImpl
/// - Logs event notifications for observability
/// - Phase 1 uses polling-based delivery in EventSubscriptionClient
/// </para>
/// <para>
/// <strong>Phase 2+ Evolution:</strong>
/// - Will integrate with Channels for efficient event pushing
/// - Will replace polling with true push-based delivery
/// - Will support stream multiplexing and backpressure
/// </para>
/// </remarks>
public sealed class GrpcEventDeliveryProvider : IEventDeliveryProvider
{
private readonly ILogger<GrpcEventDeliveryProvider> _logger;
private bool _isRunning;
public GrpcEventDeliveryProvider(ILogger<GrpcEventDeliveryProvider> logger)
{
_logger = logger;
}
/// <inheritdoc />
public string ProviderName => "gRPC";
/// <inheritdoc />
public Task NotifyEventAvailableAsync(
string streamName,
ICorrelatedEvent @event,
CancellationToken cancellationToken = default)
{
if (!_isRunning)
{
_logger.LogWarning(
"Received event notification for stream {StreamName} but provider is not running",
streamName);
return Task.CompletedTask;
}
_logger.LogDebug(
"Event available in stream {StreamName}: {EventType} (EventId: {EventId}, CorrelationId: {CorrelationId})",
streamName,
@event.GetType().Name,
@event.EventId,
@event.CorrelationId);
// Phase 1.7: Event notification logged for observability
// Phase 2+: Will push events to active streams via Channels
// For now, EventSubscriptionClient handles delivery via polling
return Task.CompletedTask;
}
/// <inheritdoc />
public Task StartAsync(CancellationToken cancellationToken = default)
{
_logger.LogInformation("Starting gRPC event delivery provider");
_isRunning = true;
return Task.CompletedTask;
}
/// <inheritdoc />
public Task StopAsync(CancellationToken cancellationToken = default)
{
_logger.LogInformation("Stopping gRPC event delivery provider");
_isRunning = false;
return Task.CompletedTask;
}
/// <inheritdoc />
public int GetActiveConsumerCount()
{
// Delegate to EventServiceImpl which tracks active gRPC streams
return EventServiceImpl.GetActiveStreamCount();
}
/// <inheritdoc />
public bool IsHealthy()
{
// Provider is healthy if it's running
// In Phase 2+, could add additional health checks (channel capacity, error rates, etc.)
return _isRunning;
}
}