public Task <EventStoreSubscription> FilteredSubscribeToAllAsync(bool resolveLinkTos, Filter filter, Func <EventStoreSubscription, ResolvedEvent, Task> eventAppeared, Func <EventStoreSubscription, Position, Task> checkpointReached, int checkpointInterval, Action <EventStoreSubscription, SubscriptionDropReason, Exception> subscriptionDropped = null, UserCredentials userCredentials = null) { Ensure.NotNull(eventAppeared, nameof(eventAppeared)); Ensure.NotNull(filter, nameof(filter)); Ensure.NotNull(checkpointReached, nameof(checkpointReached)); if (checkpointInterval <= 0 && checkpointInterval != DontReportCheckpointReached) { throw new ArgumentOutOfRangeException(nameof(checkpointInterval)); } var source = TaskCompletionSourceFactory.Create <EventStoreSubscription>(); _handler.EnqueueMessage(new StartFilteredSubscriptionMessage(source, string.Empty, resolveLinkTos, checkpointInterval, filter, userCredentials, eventAppeared, checkpointReached, subscriptionDropped, Settings.MaxRetries, Settings.OperationTimeout)); return(source.Task); }
public async Task <AllEventsSlice> FilteredReadAllEventsBackwardAsync(Position position, int maxCount, bool resolveLinkTos, Filter filter, int maxSearchWindow, UserCredentials userCredentials = null) { Ensure.Positive(maxCount, "maxCount"); Ensure.Positive(maxSearchWindow, nameof(maxSearchWindow)); Ensure.GreaterThanOrEqualTo(maxSearchWindow, maxCount, nameof(maxSearchWindow)); Ensure.NotNull(filter, nameof(filter)); if (maxCount > ClientApiConstants.MaxReadSize) { throw new ArgumentException(string.Format( "Count should be less than {0}. For larger reads you should page.", ClientApiConstants.MaxReadSize)); } var source = TaskCompletionSourceFactory.Create <AllEventsSlice>(); var operation = new FilteredReadAllEventsBackwardOperation(Settings.Log, source, position, maxCount, resolveLinkTos, Settings.RequireLeader, maxSearchWindow, filter.Value, userCredentials); await EnqueueOperation(operation).ConfigureAwait(false); return(await source.Task.ConfigureAwait(false)); }
/// <summary> /// Sometimes, we need to manually send more requests: /// - When more requests are added to the DicomClient /// - When a pending request has completed, perhaps freeing up an async operations slot on the association /// </summary> private async Task KeepSendingUntilAllRequestsHaveCompletedAsync() { while (true) { var cancellationTaskCompletionSource = TaskCompletionSourceFactory.Create <bool>(); using (_sendRequestsCancellationTokenSource.Token.Register(() => cancellationTaskCompletionSource.SetResult(true))) { /* * This event will be triggered when the DicomClientConnection believes it has finished its work by triggering the OnSendQueueEmpty event */ var sendMoreRequests = _sendMoreRequests.WaitAsync(); /* * This event will be triggered when the CancellationToken passed into SendAsync is cancelled */ var onCancel = cancellationTaskCompletionSource.Task; /* * This event will be triggered when the pending queue becomes empty */ var allRequestsHaveCompleted = _allRequestsHaveCompletedTaskCompletionSource.Task; var winner = await Task.WhenAny(allRequestsHaveCompleted, sendMoreRequests, onCancel).ConfigureAwait(false); if (winner == allRequestsHaveCompleted || winner == onCancel) { return; } } try { if (Interlocked.CompareExchange(ref _sending, 1, 0) == 0) { try { if (!_dicomClient.QueuedRequests.IsEmpty) { if (_numberOfSentRequests >= _maximumNumberOfRequestsPerAssociation) { _dicomClient.Logger.Debug( $"[{this}] DICOM client has reached the maximum number of requests for this association and is still waiting for the sent requests to complete"); } else { _dicomClient.Logger.Debug($"[{this}] DICOM client has more queued requests, sending those now..."); await SendRequests().ConfigureAwait(false); } } if (Connection.IsSendNextMessageRequired) { _dicomClient.Logger.Debug($"[{this}] DICOM client connection still has unsent requests, sending those now..."); await Connection.SendNextMessageAsync().ConfigureAwait(false); } } finally { Interlocked.Exchange(ref _sending, 0); } } } finally { _sendMoreRequests.Reset(); } } }
public DicomClientConnectState(DicomClient dicomClient) { _dicomClient = dicomClient ?? throw new ArgumentNullException(nameof(dicomClient)); _cancellationRequestedTaskCompletionSource = TaskCompletionSourceFactory.Create <bool>(); _disposables = new List <IDisposable>(); }