105 lines
3.2 KiB
C#
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;
|
|
}
|
|
}
|