Esempio n. 1
0
        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));
        }
Esempio n. 2
0
        private async Task DoSubAsync(SubscriptionInfo subscriptionInfo) => await _connection.WithWriteLockAsync(async writer =>
        {
            await writer.WriteAsync(SubCmd.Generate(subscriptionInfo.Subject, subscriptionInfo.Id, subscriptionInfo.QueueGroup)).ConfigureAwait(false);

            if (subscriptionInfo.MaxMessages.HasValue)
            {
                await writer.WriteAsync(UnsubCmd.Generate(subscriptionInfo.Id, subscriptionInfo.MaxMessages)).ConfigureAwait(false);
            }

            await writer.FlushAsync().ConfigureAwait(false);
        }).ConfigureAwait(false);
Esempio n. 3
0
        private void DoSub(SubscriptionInfo subscriptionInfo) => _connection.WithWriteLock(writer =>
        {
            writer.Write(SubCmd.Generate(subscriptionInfo.Subject, subscriptionInfo.Id, subscriptionInfo.QueueGroup));

            if (subscriptionInfo.MaxMessages.HasValue)
            {
                writer.Write(UnsubCmd.Generate(subscriptionInfo.Id, subscriptionInfo.MaxMessages));
            }

            writer.Flush();
        });
Esempio n. 4
0
        private void DoSub(SubscriptionInfo subscriptionInfo) => _connection.WithWriteLock((writer, arg) =>
        {
            var sid = arg.Id.AsSpan();

            SubCmd.Write(writer, arg.Subject, sid, arg.QueueGroup);

            if (arg.MaxMessages.HasValue)
            {
                UnsubCmd.Write(writer, sid, arg.MaxMessages);
            }

            writer.Flush();
        }, subscriptionInfo);
Esempio n. 5
0
        private async Task <MsgOp> DoRequestAsync(string subject, byte[] body, int?timeoutMs)
        {
            var requestReplyAddress = $"{Guid.NewGuid():N}";
            var pubCmd = PubCmd.Generate(subject, body, requestReplyAddress);

            var taskComp            = new TaskCompletionSource <MsgOp>();
            var requestSubscription = MsgOpStream.Where(msg => msg.Subject == requestReplyAddress).Subscribe(
                msg => taskComp.SetResult(msg),
                ex => taskComp.SetException(ex));

            var subscriptionInfo = new SubscriptionInfo(requestReplyAddress, maxMessages: 1);
            var subCmd           = SubCmd.Generate(subscriptionInfo.Subject, subscriptionInfo.Id);
            var unsubCmd         = UnsubCmd.Generate(subscriptionInfo.Id, subscriptionInfo.MaxMessages);

            await _connection.WithWriteLockAsync(async writer =>
            {
                await writer.WriteAsync(subCmd).ConfigureAwait(false);
                await writer.WriteAsync(unsubCmd).ConfigureAwait(false);
                await writer.FlushAsync().ConfigureAwait(false);
                await writer.WriteAsync(pubCmd).ConfigureAwait(false);
                await writer.FlushAsync().ConfigureAwait(false);
            }).ConfigureAwait(false);

            Task.WaitAny(new[] { Task.Delay(timeoutMs ?? _connectionInfo.RequestTimeoutMs), taskComp.Task }, _cancellation.Token);
            if (!taskComp.Task.IsCompleted)
            {
                taskComp.SetException(NatsException.RequestTimedOut());
            }

            return(await taskComp.Task
                   .ContinueWith(t =>
            {
                requestSubscription?.Dispose();

                if (!t.IsFaulted)
                {
                    return t.Result;
                }

                var ex = t.Exception?.GetBaseException() ?? t.Exception;
                if (ex == null)
                {
                    return t.Result;
                }

                _logger.Error("Exception while performing request.", ex);

                throw ex;
            })
                   .ConfigureAwait(false));
        }
Esempio n. 6
0
        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);
Esempio n. 7
0
        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));
        }
Esempio n. 8
0
        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);
Esempio n. 9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ctype"></param>
        /// <param name="CheckSumLength"></param>
        /// <param name="mcmd"></param>
        /// <param name="scmd"></param>
        /// <param name="dataArea"></param>
        /// <param name="beginAddress"></param>
        /// <param name="length"></param>
        /// <param name="writeValue"></param>//if read,writevalue=null
        /// <returns></returns>
        public string CreateMsg(CommunicationType ctype, string RequestDataLength, MainCmd mcmd, SubCmd scmd, string dataArea, string beginAddress, string length, string writeValue)
        {
            MCcmd  mc    = new MCcmd();
            string mcMsg = null;

            if (ctype == 0)
            {
                mcMsg = mc.SubTitleNumber + mc.NetwrokNumber + mc.PcNumber + GetDescription(IOnumber.ascii) + mc.ChannelNumber + RequestDataLength
                        + GetDescription(Cpu_time.ascii) + string.Format("{0:X4}", mcmd.GetHashCode()) + string.Format("{0:X4}", scmd.GetHashCode())
                        + GetDescription((DataArea_ASCII)Enum.Parse(typeof(DataArea_ASCII), dataArea)) + beginAddress + length + writeValue;
            }
            else
            {
                mcMsg = mc.SubTitleNumber + mc.NetwrokNumber + mc.PcNumber + GetDescription(IOnumber.bin) + mc.ChannelNumber + RequestDataLength
                        + GetDescription(Cpu_time.bin) + string.Format("{0:X4}", mcmd.GetHashCode()) + string.Format("{0:X4}", scmd.GetHashCode())
                        + beginAddress + string.Format("{0:X}", (int)Enum.Parse(typeof(DataArea_BIN), dataArea)) + length + writeValue;
            }

            return(mcMsg);
        }