public Task __ExchangeUnbind(string source, string destination, string routingKey, IDictionary <string, object> arguments, bool waitConfirmation) { var tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); var writer = AmqpChannelLevelFrameWriter.ExchangeUnbind(source, destination, routingKey, arguments, waitConfirmation); _connectionIo.SendCommand(_channelNum, Amqp.Channel.Exchange.ClassId, Amqp.Channel.Exchange.Methods.ExchangeUnBind, writer, reply: (channel, classMethodId, error) => { if (!waitConfirmation || classMethodId == AmqpClassMethodChannelLevelConstants.ExchangeUnbindOk) { if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "< ExchangeUnbindOk " + source); } tcs.SetResult(true); } else { AmqpIOBase.SetException(tcs, error, classMethodId); } }, expectsReply: waitConfirmation); return(tcs.Task); }
internal Task __QueueUnbind(string queue, string exchange, string routingKey, IDictionary <string, object> arguments) { var tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); var writer = AmqpChannelLevelFrameWriter.QueueUnbind(queue, exchange, routingKey, arguments); _connectionIo.SendCommand(_channelNum, Amqp.Channel.Queue.ClassId, Amqp.Channel.Queue.Methods.QueueUnbind, writer, reply: (channel, classMethodId, error) => { if (classMethodId == AmqpClassMethodChannelLevelConstants.QueueUnbindOk) { if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "< QueueUnbindOk " + queue); } tcs.SetResult(true); } else { AmqpIOBase.SetException(tcs, error, classMethodId); } }, expectsReply: true); return(tcs.Task); }
private Task __SendConnectionClose(ushort replyCode, string message) { if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "__SendConnectionClose >"); } var tcs = new TaskCompletionSource <bool>(); SendCommand(0, Amqp.Connection.ClassId, 50, AmqpConnectionFrameWriter.ConnectionClose, reply: (channel, classMethodId, error) => { if (classMethodId == AmqpClassMethodConnectionLevelConstants.ConnectionCloseOk) { if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "__SendConnectionClose enabled"); } tcs.SetResult(true); } else { AmqpIOBase.SetException(tcs, error, classMethodId); } }, expectsReply: true, optArg: new FrameParameters.CloseParams() { replyCode = replyCode, replyText = message }, immediately: true); return(tcs.Task); }
internal virtual async Task <bool> InitiateCleanClose(bool initiatedByServer, AmqpError error) { if (_isClosed) { return(false); } Thread.MemoryBarrier(); _isClosed = true; if (LogAdapter.IsDebugEnabled) { LogAdapter.LogDebug(LogSource, "Clean close initiated. By server? " + initiatedByServer); } if (initiatedByServer) { await SendCloseConfirmation().ConfigureAwait(false); } else { await SendStartClose().ConfigureAwait(false); } DrainPending(error); if (error != null) { await FireErrorEvent(error); } return(true); }
// Run on its own thread, and invokes user code from it private void ReadFramesLoop() { if (LogAdapter.ExtendedLogEnabled) { LogAdapter.LogDebug("ConnectionIO", "ReadFramesLoop starting"); } try { var token = _threadCancelToken; while (!token.IsCancellationRequested) { _frameReader.ReadAndDispatch(); } LogAdapter.LogError("ConnectionIO", "ReadFramesLoop exiting"); } catch (ThreadAbortException) { // no-op } catch (Exception ex) { LogAdapter.LogError("ConnectionIO", "ReadFramesLoop error", ex); this.InitiateAbruptClose(ex); } }
public static WriterDelegate QueueBind(string queue, string exchange, string routingKey, IDictionary <string, object> arguments, bool waitConfirmation) { return((writer, channel, classId, methodId, args) => { if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "> QueueBind : " + queue + "|" + exchange + "|" + routingKey); } writer.WriteFrameWithPayloadFirst(AmqpConstants.FrameMethod, channel, w => { w.WriteUShort(classId); w.WriteUShort(methodId); w.WriteUShort(0); w.WriteShortstr(queue); w.WriteShortstr(exchange); w.WriteShortstr(routingKey); w.WriteBits(!waitConfirmation); w.WriteTable(arguments); }); }); }
private Task <string> __SendConnectionOpen(string vhost) { if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug("ConnectionIO", "__SendConnectionOpen > vhost " + vhost); } var tcs = new TaskCompletionSource <string>(); var writer = AmqpConnectionFrameWriter.ConnectionOpen(vhost, string.Empty, false); SendCommand(0, 10, 40, writer, reply: (channel, classMethodId, error) => { if (classMethodId == AmqpClassMethodConnectionLevelConstants.ConnectionOpenOk) { _frameReader.Read_ConnectionOpenOk((knowHosts) => { if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug("ConnectionIO", "__SendConnectionOpen completed for vhost " + vhost); } tcs.SetResult(knowHosts); }); } else { AmqpIOBase.SetException(tcs, error, classMethodId); } return(Task.CompletedTask); }, expectsReply: true); return(tcs.Task); }
private void OnRecvWorker() { var polling = new Polling(PollingEvents.RecvReady, this._socket); polling.RecvReady += socket => { var topic = _socket.RecvString(); var messageInBytes = _socket.Recv(); var message = _deserializer(messageInBytes); this.OnReceived(topic, message); }; try { while (_started) { polling.Poll(1000); } } catch (ZmqException e) { if (LogAdapter.LogEnabled) { LogAdapter.LogDebug(this.GetType().FullName, "BaseSubscriber exception. Disposing. Details: " + e.ToString()); } this.Dispose(); } }
private void InvalidatePoll(string name, string reason) { if (LogAdapter.LogEnabled) { LogAdapter.LogDebug("RequestPoll", "InvalidatePoll called. " + reason); } lock (_endpoint2Sockets) { EndpointPoll endpoint; if (!_endpoint2Sockets.TryRemove(name, out endpoint)) { return; } // if (endpoint.monitor != null) // { // endpoint.monitor.Dispose(); // endpoint.monitored = false; // endpoint.monitor = null; // } foreach (var socket in endpoint.SocketsQueue.ToArray()) { socket.Dispose(); } } }
internal Task __ExchangeDelete(string exchange, bool waitConfirmation) { var tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); var writer = AmqpChannelLevelFrameWriter.ExchangeDelete(exchange, waitConfirmation); _connectionIo.SendCommand(_channelNum, Amqp.Channel.Exchange.ClassId, Amqp.Channel.Exchange.Methods.ExchangeDelete, writer, reply: (channel, classMethodId, error) => { if (!waitConfirmation || classMethodId == AmqpClassMethodChannelLevelConstants.ExchangeDeleteOk) { if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "< ExchangeDeleteOk " + exchange); } tcs.SetResult(true); } else { AmqpIOBase.SetException(tcs, error, classMethodId); } }, expectsReply: waitConfirmation); return(tcs.Task); }
public Task __ExchangeDeclare(string exchange, string type, bool durable, bool autoDelete, IDictionary <string, object> arguments, bool waitConfirmation) { var tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); var writer = AmqpChannelLevelFrameWriter.ExchangeDeclare(exchange, type, durable, autoDelete, arguments, false, false, waitConfirmation); _connectionIo.SendCommand(_channelNum, 40, 10, writer, reply: (channel, classMethodId, error) => { if (!waitConfirmation || classMethodId == AmqpClassMethodChannelLevelConstants.ExchangeDeclareOk) { if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "< ExchangeDeclareOk " + exchange); } tcs.SetResult(true); } else { AmqpIOBase.SetException(tcs, error, classMethodId); } }, expectsReply: waitConfirmation); return(tcs.Task); }
public Task Apply(Channel channel) { if (LogAdapter.ExtendedLogEnabled) { LogAdapter.LogDebug("Recovery", "Recovering queue " + _queue); } return(channel.QueueDeclare(_queue, _passive, _durable, _exclusive, _autoDelete, _arguments, waitConfirmation: !_passive)); }
public static void ConnectionCloseOk(AmqpPrimitivesWriter writer, ushort channel, ushort classId, ushort methodId, object args) { if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "> ConnectionCloseOk"); } WriteEmptyMethodFrame(writer, channel, classId, methodId); }
public void NotifyConnected(string hostname) { _selectedHostname = hostname; if (LogAdapter.IsDebugEnabled) { LogAdapter.LogDebug(LogSource, "Connected to " + hostname); } }
public Task Apply(Channel channel) { if (LogAdapter.ExtendedLogEnabled) { LogAdapter.LogDebug("Recovery", "Recovering binding queue: " + _queue + " ex: " + _exchange + " routing: " + _routingKey); } return(channel.QueueBind(_queue, _exchange, _routingKey, _arguments, waitConfirmation: true)); }
internal void NotifyCloseByUser() { _disableRecovery = true; if (LogAdapter.IsDebugEnabled) { LogAdapter.LogDebug(LogSource, "NotifyClosedByUser"); } }
public Task Apply(Channel channel) { if (LogAdapter.ExtendedLogEnabled) { LogAdapter.LogDebug(LogSource, "Recovering binding source: " + _source + " dest: " + _destination + " routing: " + _routingKey); } return(channel.ExchangeBind(_source, _destination, _routingKey, _arguments, waitConfirmation: true)); }
public Task Apply(Channel channel) { if (LogAdapter.ExtendedLogEnabled) { LogAdapter.LogDebug("Recovery", "Recovering exchange: " + _exchange); } return(channel.ExchangeDeclare(_exchange, _type, _durable, _autoDelete, _arguments, waitConfirmation: true)); }
internal RecoveryAction NotifyCloseByServer() { LogAdapter.LogDebug(LogSource, "NotifyClosedByServer "); // TODO: Block RecoveryChannels? So new operations are blocked. also should fire notifications to indicate recovery in progress TryInitiateRecovery(); return(RecoveryAction.WillReconnect); }
private Task __SendConnectionStartOk(string username, string password, string connectionName) { if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "__SendConnectionStartOk >"); } var tcs = new TaskCompletionSource <bool>(); // Only supports PLAIN authentication for now var clientProperties = Protocol.ClientProperties; if (!string.IsNullOrEmpty(connectionName)) { clientProperties = new Dictionary <string, object>(clientProperties); clientProperties["connection_name"] = connectionName; } var auth = Encoding.UTF8.GetBytes("\0" + username + "\0" + password); var writer = AmqpConnectionFrameWriter.ConnectionStartOk(clientProperties, "PLAIN", auth, "en_US"); SendCommand(0, Amqp.Connection.ClassId, 30, writer, reply: (channel, classMethodId, error) => { if (classMethodId == AmqpClassMethodConnectionLevelConstants.ConnectionTune) { _frameReader.Read_ConnectionTune((channelMax, frameMax, heartbeat) => { this._channelMax = channelMax; this._frameMax = frameMax; this.Heartbeat = heartbeat; if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "__SendConnectionStartOk completed."); } if (LogAdapter.IsDebugEnabled) { LogAdapter.LogDebug(LogSource, "Tune results: Channel max: " + channel + " Frame max size: " + frameMax + " heartbeat: " + heartbeat); } tcs.SetResult(true); }); } else { AmqpIOBase.SetException(tcs, error, classMethodId); } }, expectsReply: true, immediately: true); return(tcs.Task); }
public void Read_ConnectionBlocked(Action <string> continuation) { string reason = _amqpReader.ReadShortStr(); if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "< ConnectionBlocked " + reason); } continuation(reason); }
public void Read_ChannelOpenOk(Action <string> continuation) { string reserved = _amqpReader.ReadLongstr(); if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "< ChannelOpenOk " + reserved); } continuation(reserved); }
// Run on its own thread, and invokes user code from it (task continuations) private void WriteFramesLoop() { if (LogAdapter.IsDebugEnabled) { LogAdapter.LogDebug(LogSource, "WriteFramesLoop starting"); } CommandToSend cmdToSend = null; _writeThreadRunning = true; try { var token = _threadCancelToken; while (!token.IsCancellationRequested) { _commandOutboxEvent.WaitOne(1000); // maybe it's better to _cancellationToken.Register(action) ? if (token.IsCancellationRequested) { break; // perf hit? } while (_commandOutbox.TryDequeue(out cmdToSend)) { FlushCommand(cmdToSend); } } if (LogAdapter.IsErrorEnabled) { LogAdapter.LogError(LogSource, "WriteFramesLoop exiting"); } } catch (ThreadAbortException) { // no-op } catch (Exception ex) { if (LogAdapter.IsErrorEnabled) { LogAdapter.LogError(LogSource, "WriteFramesLoop error. Last command " + cmdToSend.ToDebugInfo(), ex); } this.InitiateAbruptClose(ex).IntentionallyNotAwaited(); } finally { _writeThreadRunning = false; TryTriggerClean(); } }
public void Read_GenericMessageCount(Action <uint> continuation) { uint messageCount = _amqpReader.ReadLong(); if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "< GenericMessageCount : " + messageCount); } continuation(messageCount); }
public void Read_CancelOk(Action <string> continuation) { var consumerTag = _amqpReader.ReadShortStr(); if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "< CancelOk " + consumerTag); } continuation(consumerTag); }
internal void SendHeartbeat() { if (LogAdapter.ExtendedLogEnabled) { LogAdapter.LogDebug(LogSource, "Sending Heartbeat"); } SendCommand(0, 0, 0, AmqpConnectionFrameWriter.ConnectionClose, reply: null, expectsReply: false, optArg: AmqpConnectionFrameWriter.HeartbeatFrameWriter, immediately: false); }
public Task Apply(Channel channel, IDictionary <string, string> reservedNamesMapping) { var queueNameToUse = _queue.StartsWith(AmqpConstants.AmqpReservedPrefix, StringComparison.Ordinal) ? reservedNamesMapping[_queue] : _queue; if (LogAdapter.ExtendedLogEnabled) { LogAdapter.LogDebug("Recovery", "Recovering binding queue: " + queueNameToUse + " ex: " + _exchange + " routing: " + _routingKey); } return(channel.QueueBind(queueNameToUse, _exchange, _routingKey, _arguments, waitConfirmation: true)); }
public void Read_BasicAck(Channel channel) { ulong deliveryTags = _amqpReader.ReadULong(); bool multiple = _amqpReader.ReadBits() != 0; if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "< BasicAck : " + deliveryTags + " multiple " + multiple); } channel.ProcessAcks(deliveryTags, multiple); }
internal async Task <bool> InternalDoConnectSocket(string hostname, int port, bool throwOnError) { var index = Interlocked.Increment(ref _counter); // read and write threads should not be running at this point if (_readThreadRunning) { throw new Exception("Read thread should not be running"); } if (_writeThreadRunning) { throw new Exception("Write thread should not be running"); } var result = await _socketHolder.Connect(hostname, port, index, throwOnError).ConfigureAwait(false); if (!result) { // Interlocked.Decrement(ref _counter); return(false); } if (LogAdapter.IsDebugEnabled) { LogAdapter.LogDebug(LogSource, "Connected socket to " + hostname + " port " + port); } DrainCommandsAndResetErrorState(); if (_threadCancelSource != null) { if (LogAdapter.IsDebugEnabled) { LogAdapter.LogDebug(LogSource, "Disposing existing cancellation token source"); } _threadCancelSource.Dispose(); } _threadCancelSource = new CancellationTokenSource(); _threadCancelToken = _threadCancelSource.Token; _socketHolder.WireStreams(_threadCancelToken, OnSocketClosed); _amqpWriter.Initialize(_socketHolder.Writer); _amqpReader.Initialize(_socketHolder.Reader); _frameReader.Initialize(_socketHolder.Reader, _amqpReader, this); ThreadFactory.BackgroundThread(WriteFramesLoop, WriteFrameThreadNamePrefix + index); ThreadFactory.BackgroundThread(ReadFramesLoop, ReadFrameThreadNamePrefix + index); return(true); }
public void Read_BasicCancel(Action <string, byte> continuation) { string consumerTag = _amqpReader.ReadShortStr(); var noWait = _amqpReader.ReadBits(); if (LogAdapter.ProtocolLevelLogEnabled) { LogAdapter.LogDebug(LogSource, "< BasicCancel : " + consumerTag + " bits " + noWait); } continuation(consumerTag, noWait); }