コード例 #1
0
        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);
            });
        }
コード例 #2
0
        public void FinishedWorkWithChannel_WhenCalled_ReturnsObjectToPool()
        {
            pool.ReturnObject(null);
            LastCall.IgnoreArguments();
            repo.ReplayAll();

            CreatePoolManager().FinishedWorkWithChannel(null);
        }
コード例 #3
0
        /// <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);
            }
        }
コード例 #4
0
        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);
        }
コード例 #5
0
                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);
                }
コード例 #6
0
        /// <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);
            }
        }
コード例 #7
0
        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
            });
        }
コード例 #8
0
        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);
            });
        }
コード例 #9
0
 public virtual void Deactivate()
 {
     IsInUse = false;
     myPool.ReturnObject(this);
     gameObject.SetActive(false);
 }
コード例 #10
0
        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();
//               }
//            }
//         }
        }
コード例 #11
0
 /// <summary>
 /// Returns the borrowed object to the pool
 /// </summary>
 public void Dispose()
 {
     pool.ReturnObject(pooled);
 }
コード例 #12
0
ファイル: Step.cs プロジェクト: valanchik/testwork
 public void SelfDestroy()
 {
     Pool.ReturnObject(this);
 }