/// <summary> /// Receives a flow from the session. /// </summary> /// <param name="flow">The received flow.</param> protected virtual void OnReceiveFlow(Flow flow) { this.outgoingChannel.OnFlow(flow); this.incomingChannel.OnFlow(flow); if (flow.Handle.HasValue) { AmqpLink link = null; if (!this.linksByRemoteHandle.TryGetObject(flow.Handle.Value, out link)) { if (this.Settings.IgnoreMissingLinks) { AmqpTrace.Provider.AmqpMissingHandle(this.connection, this, "link", flow.Handle.Value); return; } this.SafeClose(new AmqpException(AmqpErrorCode.UnattachedHandle, AmqpResources.GetString(AmqpResources.AmqpHandleNotFound, flow.Handle.Value, this))); return; } link.OnFlow(flow); } else if (flow.Echo()) { this.SendFlow(); } }
protected override void OnProcessTransfer(Delivery delivery, Transfer transfer, Frame frame) { Fx.Assert(delivery == null || delivery == this.currentMessage, "The delivery must be null or must be the same as the current message."); if (this.Settings.MaxMessageSize.HasValue && this.Settings.MaxMessageSize.Value > 0) { ulong size = (ulong)(this.currentMessage.BytesTransfered + frame.Payload.Count); if (size > this.Settings.MaxMessageSize.Value) { if (this.IsClosing()) { // The closing sequence has been started, so any // transfer is meaningless, so we can treat them as no-op return; } throw new AmqpException(AmqpErrorCode.MessageSizeExceeded, AmqpResources.GetString(AmqpResources.AmqpMessageSizeExceeded, this.currentMessage.DeliveryId.Value, size, this.Settings.MaxMessageSize.Value)); } } Fx.Assert(this.currentMessage != null, "Current message must have been created!"); ArraySegment <byte> payload = frame.Payload; frame.RawByteBuffer.AdjustPosition(payload.Offset, payload.Count); frame.RawByteBuffer.Clone(); // Message also owns the buffer from now on this.currentMessage.AddPayload(frame.RawByteBuffer, !transfer.More()); if (!transfer.More()) { AmqpMessage message = this.currentMessage; this.currentMessage = null; AmqpTrace.Provider.AmqpReceiveMessage(this, message.DeliveryId.Value, message.RawByteBuffers.Count); this.OnReceiveMessage(message); } }
public void ProcessFrame(Frame frame) { Performative command = frame.Command; try { if (command.DescriptorCode == Attach.Code) { this.OnReceiveAttach((Attach)command); } else if (command.DescriptorCode == Detach.Code) { this.OnReceiveDetach((Detach)command); } else if (command.DescriptorCode == Transfer.Code) { this.OnReceiveTransfer((Transfer)command, frame); } else if (command.DescriptorCode == Flow.Code) { this.OnReceiveFlow((Flow)command); } else { throw new AmqpException(AmqpErrorCode.InvalidField, AmqpResources.GetString(AmqpResources.AmqpInvalidPerformativeCode, command.DescriptorCode)); } } catch (Exception exception) when(!Fx.IsFatal(exception)) { AmqpTrace.Provider.AmqpLogError(this, nameof(ProcessFrame), exception.Message); this.SafeClose(exception); } }
public void Open(TimeSpan timeout) { bool syncOpen = false; lock (this.thisLock) { if (this.openCalled) { throw new InvalidOperationException(AmqpResources.GetString(AmqpResources.AmqpInvalidReOpenOperation, this, this.State)); } this.openCalled = true; if (this.State == AmqpObjectState.OpenReceived) { syncOpen = true; } } if (syncOpen) { this.OpenInternal(); this.NotifyOpened(); } else { this.OnOpen(timeout); } }
public void Open(TimeSpan timeout) { bool syncOpen = false; lock (this.thisLock) { if (this.openCalled) { var exception = new InvalidOperationException(AmqpResources.GetString(AmqpResources.AmqpInvalidReOpenOperation, this, this.State)); AmqpTrace.Provider.AmqpThrowingExceptionWarning(ExceptionTrace.GetDetailsForThrownException(exception)); throw Fx.Exception.AsWarning(exception); } this.openCalled = true; if (this.State == AmqpObjectState.OpenReceived) { syncOpen = true; } } if (syncOpen) { this.OpenInternal(); this.NotifyOpened(); } else { this.OnOpen(timeout); } }
protected StateTransition TransitState(string operation, StateTransition[] states) { StateTransition state = null; lock (this.ThisLock) { foreach (StateTransition st in states) { if (st.From == this.State) { this.State = st.To; state = st; break; } } } if (state == null) { throw new AmqpException(AmqpErrorCode.IllegalState, AmqpResources.GetString(AmqpResources.AmqpIllegalOperationState, operation, this.State)); } AmqpTrace.Provider.AmqpStateTransition(this, operation, state.From, state.To); return(state); }
public uint Add(T value) { if (this.count > this.maxHandle) { throw new AmqpException(AmqpErrorCode.ResourceLimitExceeded, AmqpResources.GetString(AmqpResources.AmqpHandleExceeded, this.maxHandle)); } else if (this.count >= this.handleArray.Length) { this.GrowHandleArray(this.handleArray.Length * 2); int index = this.count; this.handleArray[index] = value; this.count++; return((uint)index); } else { for (int i = 0; i < this.handleArray.Length; i++) { if (this.handleArray[i] == null) { this.handleArray[i] = value; this.count++; return((uint)i); } } // count and actual handles go out of sync. there must be a bug throw new AmqpException(AmqpErrorCode.InternalError, null); } }
protected virtual void CompleteOnTimer() { if (this.timer != null) { this.timer.Dispose(); } this.CompleteInternal(false, new TimeoutException(AmqpResources.GetString(AmqpResources.AmqpTimeout, this.timeout, this.Target))); }
void OnReceiveSessionFrame(Frame frame) { AmqpSession session = null; Performative command = frame.Command; ushort channel = frame.Channel; if (command.DescriptorCode == Begin.Code) { Begin begin = (Begin)command; if (begin.RemoteChannel.HasValue) { // reply to begin lock (this.ThisLock) { if (!this.sessionsByLocalHandle.TryGetObject(begin.RemoteChannel.Value, out session)) { throw new AmqpException(AmqpErrorCode.NotFound, AmqpResources.GetString(AmqpResources.AmqpChannelNotFound, begin.RemoteChannel.Value, this)); } session.RemoteChannel = channel; this.sessionsByRemoteHandle.Add(channel, session); } } else { // new begin request AmqpSessionSettings settings = AmqpSessionSettings.Create(begin); settings.RemoteChannel = channel; session = this.SessionFactory.CreateSession(this, settings); this.AddSession(session, channel); } } else { if (!this.sessionsByRemoteHandle.TryGetObject((uint)channel, out session)) { if (command.DescriptorCode == End.Code || command.DescriptorCode == Detach.Code || this.Settings.IgnoreMissingSessions) { // The session close may timed out already AmqpTrace.Provider.AmqpMissingHandle(this, "session", channel); return; } throw new AmqpException(AmqpErrorCode.NotFound, AmqpResources.GetString(AmqpResources.AmqpChannelNotFound, channel, this)); } else if (command.DescriptorCode == End.Code) { this.sessionsByRemoteHandle.Remove((uint)channel); session.RemoteChannel = null; } } session.ProcessFrame(frame); }
static Error AdvanceBuffer(ByteBuffer buffer, uint size) { if (size > buffer.Length) { return(GetDecodeError(AmqpResources.GetString(Resources.AmqpInsufficientBufferSize, size, buffer.Length))); } buffer.Complete((int)size); return(null); }
public void Validate(bool write, int dataSize) { bool valid = false; if (write) { if (this.Size < dataSize && this.autoGrow) { if (this.references != 1) { throw new InvalidOperationException("Cannot grow the current buffer because it has more than one references"); } int newSize = Math.Max(this.Capacity * 2, this.Capacity + dataSize); ManagedBuffer newBuffer; if (this.bufferManager != null) { newBuffer = ByteBuffer.AllocateBuffer(newSize, this.bufferManager); } else { newBuffer = new ManagedBuffer(new byte[newSize], null); } System.Buffer.BlockCopy(this.buffer, this.start, newBuffer.Buffer, 0, this.Capacity); int consumed = this.read - this.start; int written = this.write - this.start; this.start = 0; this.read = consumed; this.write = written; this.end = newSize; if (this.bufferManager != null) { this.bufferManager.ReturnBuffer(this.buffer); } this.buffer = newBuffer.Buffer; this.bufferManager = newBuffer.BufferManager; } valid = this.Size >= dataSize; } else { valid = this.Length >= dataSize; } if (!valid) { throw new AmqpException(AmqpErrorCode.DecodeError, AmqpResources.GetString(AmqpResources.AmqpInsufficientBufferSize, dataSize, write ? this.Size : this.Length)); } }
protected void ProcessTransfer(Transfer transfer, Frame rawFrame, Delivery delivery, bool newDelivery) { if (newDelivery) { if (this.linkCredit < uint.MaxValue) { bool creditAvailable = true; lock (this.syncRoot) { // Updating new total credit is delayed to avoid flooding // the network with flows when there are many links that are // frequently opened/closed if (this.tempTotalCredit != null && this.ApplyTempTotalLinkCredit()) { this.SendFlow(false, false, properties: null); } if (this.linkCredit == 0 && this.bufferedCredit == 0) { creditAvailable = false; } else { this.deliveryCount.Increment(); if (this.bufferedCredit > 0) { --this.bufferedCredit; } else if (this.linkCredit < uint.MaxValue) { --this.linkCredit; } } } if (!creditAvailable) { throw new AmqpException(AmqpErrorCode.TransferLimitExceeded, AmqpResources.GetString(AmqpResources.AmqpTransferLimitExceeded, delivery.DeliveryId.Value)); } } if (!delivery.Settled) { lock (this.syncRoot) { this.unsettledMap.Add(delivery.DeliveryTag, delivery); } } } this.OnProcessTransfer(delivery, transfer, rawFrame); }
/// <summary> /// Compares two integers as sequence numbers. /// </summary> /// <param name="x">The first number.</param> /// <param name="y">The second number.</param> /// <returns>A negative integer, 0, or a possitive number if the first is /// less than, equal or greater than the second respectively.</returns> public static int Compare(int x, int y) { int delta = x - y; if (delta == int.MinValue) { // Behavior of comparing 0u-2147483648u, 1u-2147483649u, ... // is undefined, so we do not allow it. throw new InvalidOperationException(AmqpResources.GetString(AmqpResources.AmqpInvalidSequenceNumberComparison, x, y)); } return(delta); }
static Error ScanDataSection(byte formatCode, ByteBuffer buffer) { switch (formatCode) { case FormatCode.Binary8: return(AdvanceBuffer(buffer, AmqpBitConverter.ReadUByte(buffer))); case FormatCode.Binary32: return(AdvanceBuffer(buffer, AmqpBitConverter.ReadUInt(buffer))); default: return(GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidFormatCode, formatCode, buffer.Offset))); } }
void EnsureBodyType(SectionFlag expected) { if (this.sectionFlags == 0 && this.buffer != null) { this.Initialize(SectionFlag.All); } SectionFlag actual = this.sectionFlags & SectionFlag.Body; if (actual > 0 && actual != expected) { throw new InvalidOperationException(AmqpResources.GetString(Resources.AmqpInvalidMessageBodyType, actual, expected)); } }
public IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { lock (this.thisLock) { if (this.openCalled) { throw new InvalidOperationException(AmqpResources.GetString(AmqpResources.AmqpInvalidReOpenOperation, this, this.State)); } this.openCalled = true; } AmqpTrace.Provider.AmqpLogOperationVerbose(this, TraceOperation.Execute, "BeginOpen"); return(new OpenAsyncResult(this, timeout, callback, state)); }
static void OnHeartBeatTimer(object state) { TimedHeartBeat thisPtr = (TimedHeartBeat)state; if (thisPtr.connection.IsClosing()) { return; } DateTime now = DateTime.UtcNow; try { if (thisPtr.localInterval < uint.MaxValue && now.Subtract(thisPtr.lastReceiveTime).TotalMilliseconds > thisPtr.localInterval) { string message = AmqpResources.GetString(AmqpResources.AmqpConnectionInactive, thisPtr.localInterval, thisPtr.connection.Settings.ContainerId); AmqpTrace.Provider.AmqpLogError(thisPtr.connection, "OnHeartBeatTimer", message); thisPtr.connection.SafeClose(new AmqpException(AmqpErrorCode.ConnectionForced, message)); return; } if (thisPtr.remoteInterval < uint.MaxValue && now.Subtract(thisPtr.lastSendTime).TotalMilliseconds >= thisPtr.remoteInterval) { thisPtr.connection.SendCommand(null, 0, null); } thisPtr.SetTimer(now); } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } if (!thisPtr.connection.IsClosing()) { AmqpTrace.Provider.AmqpLogError(thisPtr.connection, "OnHeartBeatTimer", exception.Message); thisPtr.connection.SafeClose(exception); } } }
async Task <RequestResponseAmqpLink> CreateCbsLinkAsync(TimeSpan timeout) { string address = CbsConstants.CbsAddress; TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); AmqpSession session = null; RequestResponseAmqpLink link = null; Exception lastException = null; while (timeoutHelper.RemainingTime() > TimeSpan.Zero) { try { AmqpSessionSettings sessionSettings = new AmqpSessionSettings() { Properties = new Fields() }; session = this.connection.CreateSession(sessionSettings); await session.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); Fields properties = new Fields(); properties.Add(CbsConstants.TimeoutName, (uint)timeoutHelper.RemainingTime().TotalMilliseconds); link = new RequestResponseAmqpLink("cbs", session, address, properties); await link.OpenAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); AmqpTrace.Provider.AmqpOpenEntitySucceeded(this, link.Name, address); return(link); } catch (Exception exception) { if (this.connection.IsClosing()) { throw new OperationCanceledException("Connection is closing or closed.", exception); } lastException = exception; AmqpTrace.Provider.AmqpOpenEntityFailed(this, this.GetType().Name, address, exception); } await Task.Delay(1000).ConfigureAwait(false); } link?.Abort(); session?.SafeClose(); throw new TimeoutException(AmqpResources.GetString(AmqpResources.AmqpTimeout, timeout, address), lastException); }
public void AttachLink(AmqpLink link) { Fx.Assert(link.Session == this, "The link is not owned by this session."); link.Closed += onLinkClosed; lock (this.ThisLock) { if (this.links.ContainsKey(link.Name)) { throw new AmqpException(AmqpErrorCode.ResourceLocked, AmqpResources.GetString(AmqpResources.AmqpLinkNameInUse, link.Name, this.LocalChannel)); } this.links.Add(link.Name, link); link.LocalHandle = this.linksByLocalHandle.Add(link); } AmqpTrace.Provider.AmqpAttachLink(this.connection, this, link, link.LocalHandle.Value, link.RemoteHandle ?? 0u, link.Name, link.IsReceiver ? "receiver" : "sender"); }
void OnReceiveOpen(Open open) { StateTransition stateTransition = this.TransitState("R:OPEN", StateTransition.ReceiveOpen); uint peerIdleTimeout = open.IdleTimeOut(); if (peerIdleTimeout < this.Settings.MinIdleTimeout) { this.CompleteOpen(false, new AmqpException(AmqpErrorCode.NotAllowed, AmqpResources.GetString(AmqpResources.AmqpIdleTimeoutNotSupported, peerIdleTimeout, this.Settings.MinIdleTimeout))); return; } this.Negotiate(open); this.NotifyOpening(open); if (stateTransition.To == AmqpObjectState.OpenReceived) { this.SendOpen(); } if (this.isInitiator) { // check if open returned an error right away Error openError = null; if (open.Properties != null && open.Properties.TryGetValue <Error>(AmqpConstants.OpenErrorName, out openError)) { this.CompleteOpen(stateTransition.From == AmqpObjectState.Start, new AmqpException(openError)); return; } } uint myIdleTimeout = this.Settings.IdleTimeOut(); peerIdleTimeout = open.IdleTimeOut(); if (peerIdleTimeout != uint.MaxValue || myIdleTimeout != uint.MaxValue) { this.heartBeat = HeartBeat.Initialize(this, myIdleTimeout, peerIdleTimeout); } this.CompleteOpen(stateTransition.From == AmqpObjectState.Start, null); }
public void Add(uint handle, T value) { if (handle > this.maxHandle) { throw new AmqpException(AmqpErrorCode.ResourceLimitExceeded, AmqpResources.GetString(AmqpResources.AmqpHandleExceeded, this.maxHandle)); } int index = (int)handle; if (index >= this.handleArray.Length) { int capacity = UpperPowerOfTwo(this.handleArray.Length, index); this.GrowHandleArray(capacity); } else if (this.handleArray[index] != null) { throw new AmqpException(AmqpErrorCode.HandleInUse, AmqpResources.GetString(AmqpResources.AmqpHandleInUse, handle, this.handleArray[index])); } this.handleArray[(int)handle] = value; this.count++; }
internal static AmqpDescribed CreateAmqpDescribed( ByteBuffer buffer, Dictionary <string, Func <AmqpDescribed> > byName, Dictionary <ulong, Func <AmqpDescribed> > byCode) { FormatCode formatCode = AmqpEncoding.ReadFormatCode(buffer); if (formatCode == FormatCode.Null) { return(null); } EncodingBase.VerifyFormatCode(formatCode, buffer.Offset, FormatCode.Described); Func <AmqpDescribed> knownTypeCtor = null; formatCode = AmqpEncoding.ReadFormatCode(buffer); if (formatCode == FormatCode.Symbol8 || formatCode == FormatCode.Symbol32) { AmqpSymbol name = SymbolEncoding.Decode(buffer, formatCode); byName.TryGetValue(name.Value, out knownTypeCtor); } else if (formatCode == FormatCode.ULong0 || formatCode == FormatCode.ULong || formatCode == FormatCode.SmallULong) { ulong code = ULongEncoding.Decode(buffer, formatCode).Value; byCode.TryGetValue(code, out knownTypeCtor); } if (knownTypeCtor == null) { throw AmqpEncoding.GetEncodingException(AmqpResources.GetString(AmqpResources.AmqpInvalidFormatCode, formatCode, buffer.Offset)); } AmqpDescribed value = knownTypeCtor(); return(value); }
protected override void OnProtocolHeader(ProtocolHeader header) { #if DEBUG header.Trace(false); AmqpTrace.Provider.AmqpLogOperationVerbose(this, TraceOperation.Receive, header); #endif this.heartBeat.OnReceive(); if (this.UsageMeter != null) { this.UsageMeter.OnRead(this, 0, header.EncodeSize); } this.TransitState("R:HDR", StateTransition.ReceiveHeader); Exception exception = null; if (this.isInitiator) { if (!this.initialHeader.Equals(header)) { exception = new AmqpException(AmqpErrorCode.NotImplemented, AmqpResources.GetString(AmqpResources.AmqpProtocolVersionNotSupported, this.initialHeader.ToString(), header.ToString())); } } else { ProtocolHeader supportedHeader = this.amqpSettings.GetSupportedHeader(header); this.SendProtocolHeader(supportedHeader); if (!supportedHeader.Equals(header)) { exception = new AmqpException(AmqpErrorCode.NotImplemented, AmqpResources.GetString(AmqpResources.AmqpProtocolVersionNotSupported, this.initialHeader.ToString(), header.ToString())); } } if (exception != null) { this.CompleteOpen(false, exception); } }
static Exception ConvertToException(int statusCode, string statusDescription) { Exception exception; if (Enum.IsDefined(typeof(AmqpResponseStatusCode), statusCode)) { AmqpResponseStatusCode amqpResponseStatusCode = (AmqpResponseStatusCode)statusCode; switch (amqpResponseStatusCode) { case AmqpResponseStatusCode.BadRequest: exception = new AmqpException(AmqpErrorCode.InvalidField, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription)); break; case AmqpResponseStatusCode.NotFound: exception = new AmqpException(AmqpErrorCode.NotFound, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription)); break; case AmqpResponseStatusCode.Forbidden: exception = new AmqpException(AmqpErrorCode.TransferLimitExceeded, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription)); break; case AmqpResponseStatusCode.Unauthorized: exception = new AmqpException(AmqpErrorCode.UnauthorizedAccess, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription)); break; default: exception = new AmqpException(AmqpErrorCode.InvalidField, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription)); break; } } else { exception = new AmqpException(AmqpErrorCode.InvalidField, AmqpResources.GetString(AmqpResources.AmqpPutTokenFailed, statusCode, statusDescription)); } return(exception); }
static Error ScanValueSection(byte formatCode, ByteBuffer buffer, int depth = 0) { if (formatCode == FormatCode.Described) { if (depth > 10) { // protection for stack overflow return(GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidFormatCode, formatCode, buffer.Offset))); } Error error = ScanValueSection(AmqpEncoding.ReadFormatCode(buffer), buffer, depth + 1); if (error != null) { return(error); } formatCode = AmqpEncoding.ReadFormatCode(buffer); } uint size; if (formatCode >= FormatCode.Binary8) { // variable width size = (formatCode & 0x10) == 0 ? AmqpBitConverter.ReadUByte(buffer) : AmqpBitConverter.ReadUInt(buffer); } else { // fixed width size = (uint)((1 << ((formatCode >> 4) - 4)) >> 1); } return(AdvanceBuffer(buffer, size)); }
/// <summary> /// Attaches a link to the session. The link is assigned a local handle on success. /// </summary> /// <param name="link">The link to attach.</param> public void AttachLink(AmqpLink link) { Fx.Assert(link.Session == this, "The link is not owned by this session."); lock (this.ThisLock) { if (this.IsClosing()) { throw new InvalidOperationException(AmqpResources.GetString(AmqpResources.AmqpIllegalOperationState, "attach", this.State)); } if (this.links.ContainsKey(link.Name)) { throw new AmqpException(AmqpErrorCode.ResourceLocked, AmqpResources.GetString(AmqpResources.AmqpLinkNameInUse, link.Name, this.LocalChannel)); } link.Closed += onLinkClosed; this.links.Add(link.Name, link); link.LocalHandle = this.linksByLocalHandle.Add(link); } AmqpTrace.Provider.AmqpAttachLink(this, link, link.LocalHandle.Value, link.RemoteHandle ?? 0u, link.Name, link.IsReceiver ? "receiver" : "sender", link.Settings.Source, link.Settings.Target); }
void NotifyClosed() { // Make sure no pending async result is leaked if (this.pendingOpen != null) { this.CompleteOpen(false, this.TerminalException ?? new OperationCanceledException(AmqpResources.GetString(AmqpResources.AmqpObjectAborted, this.name))); } if (this.pendingClose != null) { this.CompleteClose(false, this.TerminalException ?? new OperationCanceledException(AmqpResources.GetString(AmqpResources.AmqpObjectAborted, this.name))); } EventHandler closed = null; lock (this.thisLock) { if (!this.closedHandlerInvoked) { closed = this.Closed; this.closedHandlerInvoked = true; } } if (closed != null) { closed(this, EventArgs.Empty); } }
static bool TryReadSectionInfo(ByteBuffer buffer, out SectionInfo info, out Error error) { info = default(SectionInfo); FormatCode formatCode = AmqpEncoding.ReadFormatCode(buffer); if (formatCode != FormatCode.Described) { error = GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidFormatCode, formatCode, buffer.Offset - FixedWidth.FormatCode)); return(false); } ulong code = ulong.MaxValue; formatCode = AmqpEncoding.ReadFormatCode(buffer); switch (formatCode) { case FormatCode.SmallULong: code = AmqpBitConverter.ReadUByte(buffer); break; case FormatCode.ULong: code = AmqpBitConverter.ReadULong(buffer); break; case FormatCode.Symbol32: case FormatCode.Symbol8: // symbol name should be seldom used so do not optimize for it AmqpSymbol name = SymbolEncoding.Decode(buffer, formatCode); for (int i = 0; i < MessageSections.Length; i++) { if (MessageSections[i].Name.Equals(name.Value)) { code = MessageSections[i].Code; break; } } if (code == ulong.MaxValue) { error = GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidMessageSectionCode, name)); return(false); } break; default: error = GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidFormatCode, formatCode, buffer.Offset - FixedWidth.FormatCode)); return(false); } int index = (int)(code - MessageSections[0].Code); if (index < 0 || index >= MessageSections.Length) { error = GetDecodeError(AmqpResources.GetString(Resources.AmqpInvalidMessageSectionCode, code)); return(false); } info = MessageSections[index]; error = null; return(true); }
static void OnHeartBeatTimer(object state) { TimedHeartBeat thisPtr = (TimedHeartBeat)state; if (thisPtr.connection.IsClosing()) { return; } bool wasActive = false; DateTime capturedLastActive = thisPtr.lastSendTime; DateTime now = DateTime.UtcNow; DateTime scheduleAfterTime = now; if (now.Subtract(capturedLastActive) < TimeSpan.FromMilliseconds(thisPtr.heartBeatInterval)) { wasActive = true; scheduleAfterTime = capturedLastActive; } try { if (!wasActive) { thisPtr.connection.SendCommand(null, 0, null); } thisPtr.heartBeatTimer.Change(scheduleAfterTime.AddMilliseconds(thisPtr.heartBeatInterval).Subtract(now), Timeout.InfiniteTimeSpan); } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } AmqpTrace.Provider.AmqpLogError(thisPtr.connection, "OnHeartBeatTimer", exception.Message); } // idle timeout can be different for the peers. but instead of creating another timer, // we use the sending timer to also check if we have received anything just in case uint thisIdletimeout = thisPtr.connection.Settings.IdleTimeOut(); if (thisIdletimeout < uint.MaxValue && now > thisPtr.lastReceiveTime.AddMilliseconds((int)thisIdletimeout)) { AmqpTrace.Provider.AmqpLogError(thisPtr.connection, "OnHeartBeatTimer", AmqpResources.GetString(AmqpResources.AmqpTimeout, thisIdletimeout, thisPtr.connection)); thisPtr.connection.SafeClose(new AmqpException(AmqpErrorCode.ConnectionForced, AmqpResources.AmqpConnectionInactive)); } }
protected override IEnumerator <AsyncStep> GetAsyncSteps() { string address = CbsConstants.CbsAddress; while (this.RemainingTime() > TimeSpan.Zero) { try { AmqpSessionSettings sessionSettings = new AmqpSessionSettings() { Properties = new Fields() }; this.session = new AmqpSession(this.connection, sessionSettings, this); connection.AddSession(session, null); } catch (InvalidOperationException exception) { this.Complete(exception); yield break; } yield return(this.CallAsync( (thisPtr, t, c, s) => thisPtr.session.BeginOpen(t, c, s), (thisPtr, r) => thisPtr.session.EndOpen(r), ExceptionPolicy.Continue)); Exception lastException = this.LastAsyncStepException; if (lastException != null) { AmqpTrace.Provider.AmqpOpenEntityFailed(this.connection, this.session, string.Empty, address, lastException.Message); this.session.Abort(); this.Complete(lastException); yield break; } Fields properties = new Fields(); properties.Add(CbsConstants.TimeoutName, (uint)this.RemainingTime().TotalMilliseconds); this.Link = new RequestResponseAmqpLink("cbs", this.session, address, properties); yield return(this.CallAsync( (thisPtr, t, c, s) => thisPtr.Link.BeginOpen(t, c, s), (thisPtr, r) => thisPtr.Link.EndOpen(r), ExceptionPolicy.Continue)); lastException = this.LastAsyncStepException; if (lastException != null) { AmqpTrace.Provider.AmqpOpenEntityFailed(this.connection, this.Link, this.Link.Name, address, lastException.Message); this.session.SafeClose(); this.Link = null; this.Complete(lastException); yield break; } AmqpTrace.Provider.AmqpOpenEntitySucceeded(this.connection, this.Link, this.Link.Name, address); yield break; } if (this.session != null) { this.session.SafeClose(); } this.Complete(new TimeoutException(AmqpResources.GetString(AmqpResources.AmqpTimeout, this.OriginalTimeout, address))); }