private void Pooling(ReceptionContext <TMessage> receptionContext) { var assistant = receptionContext.Assistant; if (assistant.IsStopPooling) { lock (assistant.PoolingLocker) { Monitor.Wait(assistant.PoolingLocker); } } if (DISPATCH_MANY) { if (assistant.DelayCancellation != null) { assistant.DelayCancellation.Cancel(); assistant.DelayCancellation = null; } assistant.Pool.Add(receptionContext); if (assistant.Pool.Count >= MaximumThreads) { DispatchMany(assistant); } else { assistant.DelayCancellation = new CancellationTokenSource(); Task.Delay(1000, assistant.DelayCancellation.Token).ContinueWith((task) => { if (!task.IsCanceled) { DispatchMany(assistant); } }); } } else { lock (assistant.PoolingLocker) { assistant.Pool.Add(receptionContext); assistant.IsStopPooling = assistant.Pool.Count >= MaximumThreads; } DispatchOne(receptionContext); } if (assistant.IsStopPooling) { lock (assistant.PoolingLocker) { Monitor.Wait(assistant.PoolingLocker); } } }
public Startup(IConfiguration configuration) { Configuration = configuration; using var db = new ReceptionContext(); db.Database.EnsureCreated(); db.Database.Migrate(); }
private void DispatchMessage(ReceptionContext <TMessage> receptionContext) { var timeout = Timeout.HasValue ? Timeout.Value : Constants.DefaultTimeoutMilliseconds.AsNullableTimeSpan().Value; var dispatchContext = new DispatchContext <TMessage>( receptionContext.Message, timeout, _cts, (sender, status) => { if (status == DispatchStatus.Complete) { ContinueOnSuccess(receptionContext, sender); } else if (status == DispatchStatus.Timeout) { ContinueOnTimeout(receptionContext, sender); } }); try { var options = new ParallelOptions { CancellationToken = dispatchContext.LinkedCancellation.Token }; var result = Parallel.ForEach(_messageHandlers, options, (handler) => { try { handler(dispatchContext); } catch (Exception ex) { dispatchContext.LogException(ex); } }); if (result.IsCompleted) { dispatchContext.GotoComplete(); } } catch (OperationCanceledException) { if (!_cts.Token.IsCancellationRequested) { dispatchContext.GotoTimeout(); } } }
private void HandlerCallback <TMessage>(ReceptionContext <TMessage> context, ReceptionStatus status) { var assistant = context.Assistant; var rawMessage = (RedisValue)context.RawMessage; var database = _connectionFactory.GetDatabase(); if (status == ReceptionStatus.Completed) { RemoveProcessingMessage(assistant, database, rawMessage); } else if (status == ReceptionStatus.Retry) { database.ListRemove(assistant.ProcessingQueueName, rawMessage, 1); database.ListLeftPush(assistant.QueueName, rawMessage.GetString().RemoveEnqueueTime().AddEnqueueTime()); } }
private void HandlerCallback <TMessage>(ReceptionContext <TMessage> context, ReceptionStatus status) { var assistant = context.Assistant; var rawMessage = (string)context.RawMessage; var queue = GetQueue(assistant.QueueName); var queueProcessing = GetQueue(assistant.ProcessingQueueName); if (status == ReceptionStatus.Completed) { RemoveProcessingMessage(context.Assistant, queueProcessing, rawMessage); } else if (status == ReceptionStatus.Retry) { queueProcessing.Remove(rawMessage); queue.Add(rawMessage.RemoveEnqueueTime().AddEnqueueTime()); } }
private void ContinueOnTimeout(ReceptionContext <TMessage> receptionContext, DispatchContext <TMessage> dispatchContext) { if (!dispatchContext.OwnedCancellation.IsCancellationRequested) { lock (dispatchContext.Locker) { if (!dispatchContext.OwnedCancellation.IsCancellationRequested) { foreach (var timeout in _timeoutHandlers) { try { timeout(dispatchContext); } catch { } } dispatchContext.Dispose(); receptionContext.Timeout(); } } } }
private void ContinueOnSuccess(ReceptionContext <TMessage> receptionContext, DispatchContext <TMessage> dispatchContext) { if (!dispatchContext.OwnedCancellation.IsCancellationRequested) { lock (dispatchContext.Locker) { if (!dispatchContext.OwnedCancellation.IsCancellationRequested) { foreach (var complete in _completeHandlers) { try { complete(dispatchContext); } catch { } } dispatchContext.Dispose(); receptionContext.Success(); } } } }
private void DispatchOne(ReceptionContext <TMessage> receptionContext) { var assistant = receptionContext.Assistant; receptionContext.OnDone = () => { lock (assistant.PoolingLocker) { assistant.Pool.Remove(receptionContext); assistant.IsStopPooling = assistant.Pool.Count >= MaximumThreads; if (!assistant.IsStopPooling) { Monitor.Pulse(assistant.PoolingLocker); } } }; Task.Run(() => { DispatchMessage(receptionContext); }, _cts.Token); }