public void SerializedWorkerRaceTest() { int callCount = 0; Func <object, bool> func = (o) => { if (callCount == 0) { // call continue but return not completed // to see if the worker can handle this race SerializedWorker <object> worker = (SerializedWorker <object>)o; worker.ContinueWork(); ++callCount; return(false); } else { callCount = 100; return(true); } }; SerializedWorker <object> serialziedWorker = new SerializedWorker <object>(new Worker <object>(func)); serialziedWorker.DoWork(serialziedWorker); Assert.True(callCount == 100, "the work is not done even if continue is called."); }
protected AmqpLink(AmqpSession session, AmqpLinkSettings linkSettings) { if (linkSettings == null) { throw new ArgumentNullException("linkSettings"); } this.Session = session; this.settings = linkSettings; this.linkCredit = this.settings.TransferLimit; this.settings.AutoSendFlow = this.linkCredit > 0; this.syncRoot = new object(); Source source = (Source)this.settings.Source; if (source != null) { this.defaultOutcome = source.DefaultOutcome; } if (this.defaultOutcome == null) { this.defaultOutcome = AmqpConstants.ReleasedOutcome; } this.unsettledMap = new Dictionary<ArraySegment<byte>, Delivery>(ByteArrayComparer.Instance); this.pendingDeliveries = new SerializedWorker<Delivery>(this.TrySendDelivery, this.AbortDelivery, false); session.AttachLink(this); }
public AmqpConnectionBase(TransportBase transport, AmqpConnectionSettings settings) { if (settings == null) { throw new ArgumentNullException("settings"); } this.settings = settings; Fx.Assert(transport != null, "transport must not be null."); this.principal = transport.Principal; this.asyncIO = new AsyncIO( AmqpConstants.AsyncBufferSize, transport, new Action<ByteBuffer>(this.OnReceiveBuffer), this.OnAsyncIoFaulted); this.bufferHandler = new SerializedWorker<ByteBuffer>(this.OnReceiveFrameBuffer, null, false); }
public void ExtractFrameBuffers(ByteBuffer buffer, SerializedWorker<ByteBuffer> bufferHandler) { if (this.currentFrameBuffer != null) { int sizeToWrite = Math.Min(this.currentFrameBuffer.Size, buffer.Length); AmqpBitConverter.WriteBytes(this.currentFrameBuffer, buffer.Buffer, buffer.Offset, sizeToWrite); buffer.Complete(sizeToWrite); if (this.currentFrameBuffer.Size == 0) { ByteBuffer frameBuffer = this.currentFrameBuffer; this.currentFrameBuffer = null; bufferHandler.DoWork(frameBuffer); } } while (buffer.Length >= AmqpCodec.MinimumFrameDecodeSize) { int frameSize = AmqpCodec.GetFrameSize(buffer); if (frameSize < AmqpCodec.MinimumFrameDecodeSize || frameSize > this.maxFrameSize) { throw new AmqpException(AmqpErrorCode.FramingError, CommonResources.GetString(CommonResources.InvalidFrameSize, frameSize, this.maxFrameSize)); } int sizeToWrite = Math.Min(frameSize, buffer.Length); this.currentFrameBuffer = new ByteBuffer(frameSize, false); AmqpBitConverter.WriteBytes(this.currentFrameBuffer, buffer.Buffer, buffer.Offset, sizeToWrite); buffer.Complete(sizeToWrite); if (frameSize == sizeToWrite) { ByteBuffer frameBuffer = this.currentFrameBuffer; this.currentFrameBuffer = null; bufferHandler.DoWork(frameBuffer); } else { break; } } }
public void ExtractFrameBuffers(ByteBuffer buffer, SerializedWorker<ByteBuffer> bufferHandler) { if (this.currentFrameBuffer != null) { int sizeToWrite = Math.Min(this.currentFrameBuffer.Size, buffer.Length); this.currentFrameBuffer.WriteBytes(buffer.Buffer, buffer.Offset, sizeToWrite); buffer.Complete(sizeToWrite); if (this.currentFrameBuffer.Size == 0) { bufferHandler.DoWork(this.currentFrameBuffer); this.currentFrameBuffer = null; } } while (buffer.Length >= AmqpCodec.MinimumFrameDecodeSize) { int frameSize = AmqpCodec.GetFrameSize(buffer); if (frameSize < AmqpCodec.MinimumFrameDecodeSize || frameSize > this.maxFrameSize) { throw new AmqpException(AmqpError.FramingError, SRClient.InvalidFrameSize (frameSize, this.maxFrameSize)); } int sizeToWrite = Math.Min(frameSize, buffer.Length); this.currentFrameBuffer = ByteBuffer.Wrap(new byte[frameSize], 0, 0, frameSize); this.currentFrameBuffer.WriteBytes(buffer.Buffer, buffer.Offset, sizeToWrite); buffer.Complete(sizeToWrite); if (frameSize == sizeToWrite) { bufferHandler.DoWork(this.currentFrameBuffer); this.currentFrameBuffer = null; } else { break; } } }
public void SerializedWorkerTest() { const int workerCount = 3; const int workLoad = 1000000; const int totalCount = workLoad * workerCount; int completedCount = 0; int callCount = 0; ManualResetEvent completeEvent = new ManualResetEvent(false); WaitCallback callContinue = null; Func <object, bool> func = (o) => { bool workCompleted = callCount++ % 30000 != 0; if (workCompleted) { if (++completedCount == totalCount) { completeEvent.Set(); } } else { ThreadPool.QueueUserWorkItem(callContinue, null); } return(workCompleted); }; ParameterizedThreadStart producer = (o) => { SerializedWorker <object> worker = (SerializedWorker <object>)o; for (int i = 0; i < workLoad; ++i) { worker.DoWork(o); } }; SerializedWorker <object> serialziedWorker = new SerializedWorker <object>(new Worker <object>(func)); callContinue = (o) => { serialziedWorker.ContinueWork(); }; Thread[] workerThreads = new Thread[workerCount]; for (int i = 0; i < workerThreads.Length; ++i) { workerThreads[i] = new Thread(producer); workerThreads[i].Start(serialziedWorker); } // issue some continue work signal for (int i = 0; i < 20000; ++i) { serialziedWorker.ContinueWork(); } bool waitOne = completeEvent.WaitOne(60 * 1000); Debug.WriteLine(string.Format("total: {0}, completed: {1}", totalCount, completedCount)); if (!waitOne) { Assert.True(false, "Worker did not complete in time"); } else { Assert.True(totalCount == completedCount, "Completed count is not correct."); } }
protected override void ParseFrameBuffers(ByteBuffer buffer, SerializedWorker<ByteBuffer> bufferHandler) { this.frameDecoder.ExtractFrameBuffers(buffer, bufferHandler); }
public void SerializedWorkerTest() { const int workerCount = 3; const int workLoad = 1000000; const int totalCount = workLoad * workerCount; int completedCount = 0; int callCount = 0; int working = 0; ManualResetEvent completeEvent = new ManualResetEvent(false); WaitCallback callContinue = null; Func <object, bool> func = (o) => { // this function should be always called single threaded if (Interlocked.Exchange(ref working, 1) == 1) { Debug.WriteLine("Should not be called while working"); completeEvent.Set(); return(false); } bool workCompleted = callCount++ % 30000 != 0; if (workCompleted) { if (++completedCount == totalCount) { completeEvent.Set(); } } if (!workCompleted) { ThreadPool.QueueUserWorkItem(callContinue, null); } Interlocked.Exchange(ref working, 0); return(workCompleted); }; ParameterizedThreadStart producer = (o) => { SerializedWorker <object> worker = (SerializedWorker <object>)o; for (int i = 0; i < workLoad; ++i) { worker.DoWork(o); } }; SerializedWorker <object> serialziedWorker = new SerializedWorker <object>(new Worker <object>(func)); callContinue = (o) => { serialziedWorker.ContinueWork(); }; Thread[] workerThreads = new Thread[workerCount]; for (int i = 0; i < workerThreads.Length; ++i) { workerThreads[i] = new Thread(producer); workerThreads[i].Start(serialziedWorker); } // issue some continue work signal for (int i = 0; i < 20000; ++i) { serialziedWorker.ContinueWork(); } // wait for all producer to finish for (int i = 0; i < workerThreads.Length; ++i) { workerThreads[i].Join(); } bool waitOne = completeEvent.WaitOne(30 * 1000); Debug.WriteLine(string.Format("total: {0}, completed: {1}", totalCount, completedCount)); if (!waitOne) { Assert.True(false, "Worker did not complete in time"); } else { Assert.True(totalCount == completedCount, "Completed count is not correct."); } }
public Publisher(Container container, string node) : base(container, node) { this.sender = new SerializedWorker<AmqpMessage>(this.OnSend, null, false); }
protected abstract void ParseFrameBuffers(ByteBuffer buffer, SerializedWorker<ByteBuffer> bufferHandler);
public OutgoingSessionChannel(AmqpSession session) : base(session, session.settings.OutgoingBufferSize) { this.name = session.ToString() + "(out)"; this.maxFrameSize = session.connection.Settings.MaxFrameSize(); this.onSettledDeliveryComplete = this.OnSettledDeliveryComplete; this.inflightDeliveries = new SerializedWorker<Delivery>(this.OnSendDelivery, null, false); this.nextOutgoingId = session.settings.NextOutgoingId.Value; this.outgoingWindow = session.settings.OutgoingWindow.Value; this.remoteIncomingWindow = session.settings.OutgoingWindow.Value; this.IsReceiver = false; }
public IncomingSessionChannel(AmqpSession session) : base(session, session.settings.IncomingBufferSize) { this.name = session.ToString() + "(in)"; this.pendingTransfers = new SerializedWorker<Tuple<AmqpLink, Transfer>>(this.OnTransfer, null, false); this.incomingWindow = session.settings.IncomingWindow(); this.flowThreshold = this.incomingWindow == uint.MaxValue ? uint.MaxValue : this.incomingWindow * 2 / 3; this.IsReceiver = true; }