private void ReassembleChunksAndDispatch(IReadOnlyList <MultiPartChunkDto> chunks) { // Console.WriteLine(chunks.First().MultiPartMessageId.ToString("n").Substring(0, 6) + " Got to reassemble!"); RemoveAssemblerFromCache(chunks.First().MultiPartMessageId); var payloadLength = chunks.Sum(c => c.BodyLength); var payloadBytes = new byte[payloadLength]; for (int i = 0, offset = 0; i < chunks.Count; i++) { var chunk = chunks[i]; Buffer.BlockCopy(chunk.Body, 0, payloadBytes, offset, chunk.BodyLength); offset += chunk.BodyLength; } var e = inboundDataEventPool.TakeObject(); e.Data = payloadBytes; e.DataOffset = 0; e.DataLength = payloadLength; // Console.WriteLine(chunks.First().MultiPartMessageId.ToString("n").Substring(0, 6) + " Dispatching to HIDE!"); dispatcher.HandleInboundDataEvent( e, _ => { e.Data = null; inboundDataEventPool.ReturnObject(e); }); }
public void FinishedWorkWithChannel_WhenCalled_ReturnsObjectToPool() { pool.ReturnObject(null); LastCall.IgnoreArguments(); repo.ReplayAll(); CreatePoolManager().FinishedWorkWithChannel(null); }
/// <summary> /// Compiles the input linqExpression into a Linq expression tree /// </summary> /// <param name="linqExpression">The linqExpression.</param> /// <returns></returns> public Action <object, object> CompileAction(LinqExpressionToRun linqExpression) { Guard.NotNull(() => linqExpression, linqExpression); Guard.NotNullOrEmpty(() => linqExpression.Linq, linqExpression.Linq); var compiler = _objectPool.GetObject(); try { return(compiler.CompileAction(linqExpression)); } catch (Exception error) { throw new CompileException($"Failed to compile linq expression {linqExpression.Linq}", error, linqExpression.Linq); } finally { _objectPool.ReturnObject(compiler); } }
public async Task WritePayloadAsync(NetworkStream ns, object payload, AsyncLock writerLock, CancellationToken cancellationToken = default(CancellationToken)) { var ms = memoryStreamPool.TakeObject(); Serialize.To(ms, payload); using (await writerLock.LockAsync(cancellationToken).ConfigureAwait(false)) { await WriteMemoryStreamAsync(ns, ms, 0, (int)ms.Position, cancellationToken).ConfigureAwait(false); } ms.SetLength(0); memoryStreamPool.ReturnObject(ms); }
public static async Task Visit(InboundMessageRouter router, MessageDto message, PeerContext peer) { var e = eventPool.TakeObject(); e.Message = message; e.Sender = peer; if (!await router.TryRouteAsync(e).ConfigureAwait(false)) { logger.Trace($"Failed to route inbound message of body type {e.Body?.GetType().Name ?? "[null]"}"); } e.Message = null; eventPool.ReturnObject(e); }
/// <inheritdoc /> public void Intercept(IInvocation invocation) { if (invocation is null) { throw new ArgumentNullException(nameof(invocation)); } if (!invocation.Method.Name.Equals("Dispose", StringComparison.OrdinalIgnoreCase)) { invocation.Proceed(); } else { _pool.ReturnObject(this); } }
public async Task BroadcastAsync <T>(T payload) { #if DEBUG Interlocked.Increment(ref DebugRuntimeStats.out_ps); #endif var ms = outboundMemoryStreamPool.TakeObject(); Trace.Assert(ms.Position == 0); await AsyncSerialize.ToAsync(ms, payload).ConfigureAwait(false); udpClient.Broadcast( ms, 0, (int)ms.Position, () => { ms.SetLength(0); outboundMemoryStreamPool.ReturnObject(ms); #if DEBUG Interlocked.Increment(ref DebugRuntimeStats.out_ps_done); #endif }); }
public async Task SendBroadcastAsync(MessageDto message) { var packet = PacketDto.Create( identity.Id, Guid.Empty, message, false); var ms = broadcastOutboundMemoryStreamPool.TakeObject(); ms.SetLength(0); try { await AsyncSerialize.ToAsync(ms, packet).ConfigureAwait(false); } catch (NotSupportedException) { throw new InvalidOperationException("Broadcast message would surpass Courier Maximum UDP Transport Size"); } udpClient.Broadcast( ms, 0, (int)ms.Position, () => { ms.SetLength(0); broadcastOutboundMemoryStreamPool.ReturnObject(ms); }); }
public virtual void Deactivate() { IsInUse = false; myPool.ReturnObject(this); gameObject.SetActive(false); }
public void Unicast(UdpClientRemoteInfo remoteInfo, MemoryStream[] frames, Action action) { // Frames larger than half the maximum packet size certainly cannot be packed together. var smallFrames = new List <MemoryStream>(frames.Length); var largeFrames = new List <MemoryStream>(frames.Length); const int kHalfMaximumTransportSize = UdpConstants.kMaximumTransportSize / 2; for (var i = 0; i < frames.Length; i++) { var frame = frames[i]; if (frame.Length <= kHalfMaximumTransportSize) { smallFrames.Add(frame); } else { largeFrames.Add(frame); } } // Order small frames ascending by size, large frames descending by size. smallFrames.Sort(new MemoryStreamByPositionComparer()); largeFrames.Sort(new ReverseComparer <MemoryStream>(new MemoryStreamByPositionComparer())); // Place large frames into outbound buffers. var outboundBuffers = new List <MemoryStream>(frames.Length); foreach (var largeFrame in largeFrames) { var outboundBuffer = outboundMemoryStreamPool.TakeObject(); outboundBuffer.Write(largeFrame.GetBuffer(), 0, (int)largeFrame.Position); outboundBuffers.Add(outboundBuffer); } // Place small frames into outbound buffers. Note that as the // small frames are ascending in size and the buffers are descending // in size, while we iterate if a small frame cannot fit into the // next outbound buffer then none of the following small frames can either. int activeOutboundBufferIndex = 0; foreach (var smallFrame in smallFrames) { // precompute greatest outbound buffer permission for which // we will still be able to fit into the buffer. int frameSize = (int)smallFrame.Position; int greatestFittableBufferPosition = UdpConstants.kMaximumTransportSize - frameSize; // Attempt to place the small frame into existing outbound buffers bool placed = false; while (!placed && activeOutboundBufferIndex != outboundBuffers.Count) { var outboundBuffer = outboundBuffers[activeOutboundBufferIndex]; if (outboundBuffer.Position > greatestFittableBufferPosition) { activeOutboundBufferIndex++; } else { outboundBuffer.Write(smallFrame.GetBuffer(), 0, (int)smallFrame.Position); placed = true; } } // If no existing outbound buffer had space, allocate a new one if (!placed) { AssertEquals(outboundBuffers.Count, activeOutboundBufferIndex); var outboundBuffer = outboundMemoryStreamPool.TakeObject(); outboundBuffer.Write(smallFrame.GetBuffer(), 0, (int)smallFrame.Position); outboundBuffers.Add(outboundBuffer); } } // Console.WriteLine($"Batched {frames.Length} to {outboundBuffers.Count} buffers."); int sendsRemaining = outboundBuffers.Count; foreach (var outboundBuffer in outboundBuffers) { var job = new UdpUnicastJob { OutboundBuffer = outboundBuffer, RemoteInfo = remoteInfo, SendCompletionHandler = () => { outboundBuffer.SetLength(0); outboundMemoryStreamPool.ReturnObject(outboundBuffer); if (Interlocked.Decrement(ref sendsRemaining) == 0) { action(); } } }; unicastJobQueue.Enqueue(job); } // int sendsRemaining = outboundBuffers.Count; // Parallel.ForEach( // outboundBuffers, // outboundBuffer => { // outboundBytesAggregator.Put(outboundBuffer.Length); // // var e = new SocketAsyncEventArgs(); // e.RemoteEndPoint = remoteInfo.IPEndpoint; // e.SetBuffer(outboundBuffer.GetBuffer(), 0, (int)outboundBuffer.Position); // e.Completed += (sender, args) => { // // Duplicate code with below. // args.SetBuffer(null, 0, 0); // args.Dispose(); // // outboundBuffer.SetLength(0); // outboundMemoryStreamPool.ReturnObject(outboundBuffer); // // if (Interlocked.Decrement(ref sendsRemaining) == 0) { // action(); // } // }; // // const int kSendStateAsync = 1; // const int kSendStateDone = 2; // const int kSendStateError = 3; // int sendState; // try { // bool completingAsynchronously = remoteInfo.Socket.SendToAsync(e); // sendState = completingAsynchronously ? kSendStateAsync : kSendStateDone; // } catch (ObjectDisposedException) when (isShutdown) { // sendState = kSendStateError; // } // // if (sendState == kSendStateDone || sendState == kSendStateError) { // // Completed synchronously so e.Completed won't be called. // e.SetBuffer(null, 0, 0); // e.Dispose(); // // outboundBuffer.SetLength(0); // outboundMemoryStreamPool.ReturnObject(outboundBuffer); // // if (Interlocked.Decrement(ref sendsRemaining) == 0) { // action(); // } // } // }); // int sendsRemaining = outboundBuffers.Count; // foreach (var outboundBuffer in outboundBuffers) { // outboundBytesAggregator.Put(outboundBuffer.Length); // // var e = new SocketAsyncEventArgs(); // e.RemoteEndPoint = remoteInfo.IPEndpoint; // e.SetBuffer(outboundBuffer.GetBuffer(), 0, (int)outboundBuffer.Position); // e.Completed += (sender, args) => { // // Duplicate code with below. // args.SetBuffer(null, 0, 0); // args.Dispose(); // // outboundBuffer.SetLength(0); // outboundMemoryStreamPool.ReturnObject(outboundBuffer); // // if (Interlocked.Decrement(ref sendsRemaining) == 0) { // action(); // } // }; // // const int kSendStateAsync = 1; // const int kSendStateDone = 2; // const int kSendStateError = 3; // int sendState; // try { // bool completingAsynchronously = remoteInfo.Socket.SendToAsync(e); // sendState = completingAsynchronously ? kSendStateAsync : kSendStateDone; // } catch (ObjectDisposedException) when (isShutdown) { // sendState = kSendStateError; // } // // if (sendState == kSendStateDone || sendState == kSendStateError) { // // Completed synchronously so e.Completed won't be called. // e.SetBuffer(null, 0, 0); // e.Dispose(); // // outboundBuffer.SetLength(0); // outboundMemoryStreamPool.ReturnObject(outboundBuffer); // // if (sendState == kSendStateError) { // // Don't send remaining messages. // // To the application, this appears like packet loss. // action(); // return; // } else if (Interlocked.Decrement(ref sendsRemaining) == 0) { // action(); // } // } // } }
/// <summary> /// Returns the borrowed object to the pool /// </summary> public void Dispose() { pool.ReturnObject(pooled); }
public void SelfDestroy() { Pool.ReturnObject(this); }