コード例 #1
0
 protected void HandleCloseMethod(ushort replyCode, string replyText, ushort classId, ushort methodId)
 {
     var error = new AmqpError() { ClassId = classId, MethodId = methodId, ReplyCode = replyCode, ReplyText = replyText };
     Volatile.Write(ref _lastError, error);
     InitiateCleanClose(startedByServer: true, offendingClassId: classId, offendingMethodId: methodId);
     //			DrainMethodsWithErrorAndClose(error, classId, methodId, sendCloseOk: true);
     //			return Task.CompletedTask;
 }
コード例 #2
0
		public void DrainDueToFailure(AmqpError error)
		{
			for (int i = 0; i < _tasks.Length; i++)
			{
				var tcs = Interlocked.Exchange(ref _tasks[i], null);
				if (tcs == null) continue;

				tcs.SetException(new Exception("Cancelled due to error " + error.ToErrorString()), runContinuationAsync: true);
			}
		}
コード例 #3
0
		internal void CloseAllChannels(bool initiatedByServer, AmqpError error)
		{
			foreach (var channel in _channels)
			{
				if (channel == null) continue;

#pragma warning disable 4014
				channel._io.InitiateCleanClose(initiatedByServer, error);
#pragma warning restore 4014
			}
		}
コード例 #4
0
        protected void HandleCloseMethod(ushort replyCode, string replyText, ushort classId, ushort methodId)
        {
            var error = new AmqpError()
            {
                ClassId = classId, MethodId = methodId, ReplyCode = replyCode, ReplyText = replyText
            };

            Volatile.Write(ref _lastError, error);
            InitiateCleanClose(startedByServer: true, offendingClassId: classId, offendingMethodId: methodId);
//			DrainMethodsWithErrorAndClose(error, classId, methodId, sendCloseOk: true);
//			return Task.CompletedTask;
        }
コード例 #5
0
        public async Task RunReplyAction(ushort channel, int classMethodId, AmqpError error)
        {
#if DEBUG
            if (classMethodId != 0)
            {
                // Confirm reply
                var classId  = classMethodId >> 16;
                var methodId = classMethodId & 0x0000FFFF;

                var matchesClass  = (ClassId == classId);
                var matchesMethod = MethodId == (methodId - 1);

                if (!matchesClass || !matchesMethod)
                {
                    Console.WriteLine("[channel " + channel + "] Command for " + ClassId + "|" + MethodId + " did not match reply " + classId + "|" + methodId);
                }
            }
#endif

            if (this.ReplyAction != null)
            {
                await this.ReplyAction(channel, classMethodId, error);
            }
            else
            {
                if (error != null)
                {
                    AmqpIOBase.SetException(Tcs, error, classMethodId);
                    AmqpIOBase.SetException(TcsSlim, error, classMethodId);
                }
                else
                {
                    if (Tcs != null)
                    {
                        Tcs.SetResult(true);
                    }

                    if (TcsSlim != null)
                    {
                        TcsSlim.SetCompleted();
                    }
                }
            }

            if (_recycler != null)
            {
                _recycler(this);
            }
        }
コード例 #6
0
		public async Task RunReplyAction(ushort channel, int classMethodId, AmqpError error)
		{
#if DEBUG
			if (classMethodId != 0)
			{
				// Confirm reply
				var classId = classMethodId >> 16;
				var methodId = classMethodId & 0x0000FFFF;

				var matchesClass = (ClassId == classId);
				var matchesMethod = MethodId == (methodId - 1);

				if (!matchesClass || !matchesMethod)
				{
					Console.WriteLine("[channel " + channel + "] Command for " + ClassId + "|" + MethodId + " did not match reply " + classId + "|" + methodId);
				}
			}
#endif

			if (this.ReplyAction != null)
			{
				await this.ReplyAction(channel, classMethodId, error);
			}
			else
			{
				if (error != null)
				{
					AmqpIOBase.SetException(Tcs, error, classMethodId);
					AmqpIOBase.SetException(TcsSlim, error, classMethodId);
				}
				else
				{
					if (Tcs != null)
						Tcs.SetResult(true);

					if (TcsSlim != null)
						TcsSlim.SetCompleted();
				}
			}

			if (_recycler != null) _recycler(this);
		}
コード例 #7
0
        public void DrainDueToFailure(AmqpError error)
        {
            Exception exception = null;

            for (int i = 0; i < _tasks.Length; i++)
            {
                var tcs = Interlocked.Exchange(ref _tasks[i], null);
                if (tcs == null)
                {
                    continue;
                }

                if (exception == null)
                {
                    exception = new Exception("Cancelled due to error " + error.ToErrorString());
                }

                tcs.TrySetException(exception);
            }
        }
コード例 #8
0
        public async Task RunReplyAction(ushort channel, int classMethodId, AmqpError error)
        {
            AssertCanBeUsed();

#if DEBUG
            if (classMethodId != 0)
            {
                // Confirm reply
                var classId  = classMethodId >> 16;
                var methodId = classMethodId & 0x0000FFFF;

                var matchesClass  = (ClassId == classId);
                var matchesMethod = MethodId == (methodId - 1);

                if (!matchesClass || !matchesMethod)
                {
                    if (LogAdapter.ExtendedLogEnabled)
                    {
                        LogAdapter.LogDebug("CommandToSend", "[channel " + channel + "] Command for " + ClassId + "|" + MethodId + " did not match reply " + classId + "|" + methodId);
                    }
                }
            }
#endif

            // Allows more commands to be sent. This contention is sadly required by the amqp/rabbitmq
            if (_whenReplyReceived != null)
            {
                _whenReplyReceived.Set();
            }
            // ---

            if (this.ReplyAction != null)
            {
                try
                {
                    await this.ReplyAction(channel, classMethodId, error).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    error = new AmqpError
                    {
                        ReplyText = ex.Message
                    };
                    AmqpIOBase.SetException(Tcs, error, classMethodId);
                    AmqpIOBase.SetException(TcsSlim, error, classMethodId);

                    throw;
                }
            }
            else
            {
                if (error != null)
                {
                    AmqpIOBase.SetException(Tcs, error, classMethodId);
                    AmqpIOBase.SetException(TcsSlim, error, classMethodId);
                }
                else
                {
                    if (Tcs != null)
                    {
                        Tcs.SetResult(true);
                    }

                    if (TcsSlim != null)
                    {
                        TcsSlim.SetCompleted();
                    }
                }
            }

            if (_recycler != null)
            {
                _recycler(this);
            }
        }
コード例 #9
0
		internal override async Task<bool> InitiateCleanClose(bool initiatedByServer, AmqpError error)
		{
			if (!initiatedByServer)
			{
				while (true)
				{
					if (_socketHolder.StillSending)
					{
						Thread.Sleep(1000); // give it some time to finish writing to the socket (if it's open)
					}
					break;
				}
			}

			_conn.CloseAllChannels(initiatedByServer, error);

			await base.InitiateCleanClose(initiatedByServer, error);

			CancelPendingCommands(error);

			_socketHolder.Close();

			return true;
		}
コード例 #10
0
		private void CancelPendingCommands(AmqpError error)
		{
			CommandToSend cmdToSend;
			while (_commandOutbox.TryDequeue(out cmdToSend))
			{
#pragma warning disable 4014
				cmdToSend.RunReplyAction(0, 0, error);
#pragma warning restore 4014
			}
		}