private async Task <MsgOp> DoRequestAsync(string subject, ReadOnlyMemory <byte> body, CancellationToken cancellationToken = default) { var replyToSubject = UniqueId.Generate(); var taskComp = new TaskCompletionSource <MsgOp>(); using var _ = MsgOpStream .WhereSubjectMatches(replyToSubject) .SubscribeSafe(msg => taskComp.SetResult(msg), ex => taskComp.SetException(ex)); using var cts = cancellationToken == default ? new CancellationTokenSource(_connectionInfo.RequestTimeoutMs) : CancellationTokenSource.CreateLinkedTokenSource(_cancellation.Token, cancellationToken); await using var __ = cts.Token.Register(() => taskComp.SetCanceled()).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await _connection.WithWriteLockAsync(async (writer, arg) => { var(subjectIn, bodyIn, replyToIn) = arg; var sid = UniqueId.Generate().AsMemory(); await SubCmd.WriteAsync(writer, replyToIn, sid, ReadOnlyMemory <char> .Empty).ConfigureAwait(false); await UnsubCmd.WriteAsync(writer, sid, 1).ConfigureAwait(false); await writer.FlushAsync().ConfigureAwait(false); await PubCmd.WriteAsync(writer, subjectIn, replyToIn, bodyIn).ConfigureAwait(false); await writer.FlushAsync().ConfigureAwait(false); }, Tuple.Create(subject.AsMemory(), body, replyToSubject.AsMemory())).ConfigureAwait(false); return(await taskComp.Task.ConfigureAwait(false)); }
private Task DoSubAsync(SubscriptionInfo subscriptionInfo) => _connection.WithWriteLockAsync(async(writer, arg) => { var sid = arg.Id.AsMemory(); await SubCmd.WriteAsync(writer, arg.Subject.AsMemory(), sid, arg.QueueGroup.AsMemory()) .ConfigureAwait(false); if (arg.MaxMessages.HasValue) { await UnsubCmd.WriteAsync(writer, sid, arg.MaxMessages).ConfigureAwait(false); } await writer.FlushAsync().ConfigureAwait(false); }, subscriptionInfo);
private async Task <MsgOp> DoRequestUsingInboxAsync(string subject, ReadOnlyMemory <byte> body, CancellationToken cancellationToken = default) { var requestId = UniqueId.Generate(); var replyToSubject = $"{_inboxAddress}.{requestId}"; var taskComp = new TaskCompletionSource <MsgOp>(); if (!_outstandingRequests.TryAdd(requestId, taskComp)) { throw NatsException.InitRequestError("Unable to initiate request."); } using var cts = cancellationToken == default ? new CancellationTokenSource(_connectionInfo.RequestTimeoutMs) : CancellationTokenSource.CreateLinkedTokenSource(_cancellation.Token, cancellationToken); await using var _ = cts.Token.Register(() => { if (_outstandingRequests.TryRemove(requestId, out var ts)) { ts.TrySetCanceled(); } }).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await _connection.WithWriteLockAsync(async (writer, arg) => { var(subjectIn, bodyIn, replyToIn) = arg; if (_inboxSubscription == null) { SetupInboxSubscription(); await SubCmd.WriteAsync( writer, _inboxSubscription.SubscriptionInfo.Subject.AsMemory(), _inboxSubscription.SubscriptionInfo.Id.AsMemory(), _inboxSubscription.SubscriptionInfo.QueueGroup.AsMemory()).ConfigureAwait(false); } await PubCmd.WriteAsync(writer, subjectIn, replyToIn, bodyIn).ConfigureAwait(false); await writer.FlushAsync().ConfigureAwait(false); }, Tuple.Create(subject.AsMemory(), body, replyToSubject.AsMemory())).ConfigureAwait(false); return(await taskComp.Task.ConfigureAwait(false)); }
private Task DoSubAsync(SubscriptionInfo[] subscriptionInfos) => _connection.WithWriteLockAsync(async(writer, arg) => { foreach (var subscriptionInfo in arg) { var sid = subscriptionInfo.Id.AsMemory(); await SubCmd.WriteAsync(writer, subscriptionInfo.Subject.AsMemory(), sid, subscriptionInfo.QueueGroup.AsMemory()) .ConfigureAwait(false); if (subscriptionInfo.MaxMessages.HasValue) { await UnsubCmd.WriteAsync(writer, sid, subscriptionInfo.MaxMessages).ConfigureAwait(false); } await writer.FlushAsync().ConfigureAwait(false); } }, subscriptionInfos);