Esempio n. 1
0
        async Task <Result> ClientSingleConnectionAsync(Direction dir, AsyncManualResetEvent fireMeWhenReady, CancellationToken cancel)
        {
            Result ret = new Result();

            using (NetPalTcpProtocolStub tcp = new NetPalTcpProtocolStub(cancel: cancel))
            {
                await tcp.ConnectAsync(ServerIP, ServerPort, cancel, ConnectTimeout);

                using (ConnSock sock = new ConnSock(tcp))
                {
                    NetAppStub app = sock.GetNetAppProtocolStub();

                    AttachHandle attachHandle = app.AttachHandle;

                    PipeStream st = app.GetStream();

                    if (dir == Direction.Recv)
                    {
                        app.AttachHandle.SetStreamReceiveTimeout(RecvTimeout);
                    }

                    try
                    {
                        var hello = await st.ReceiveAllAsync(16);

                        if (hello.Span.ToArray()._GetString_Ascii().StartsWith("TrafficServer\r\n") == false)
                        {
                            throw new ApplicationException("Target server is not a Traffic Server.");
                        }

                        //throw new ApplicationException("aaaa" + dir.ToString());

                        fireMeWhenReady.Set();

                        cancel.ThrowIfCancellationRequested();

                        await TaskUtil.WaitObjectsAsync(
                            manualEvents : ClientStartEvent._SingleArray(),
                            cancels : cancel._SingleArray()
                            );

                        long tickStart = FastTick64.Now;
                        long tickEnd   = tickStart + this.TimeSpan;

                        var sendData = new MemoryBuffer <byte>();
                        sendData.WriteBool8(dir == Direction.Recv);
                        sendData.WriteUInt64(SessionId);
                        sendData.WriteSInt64(TimeSpan);

                        await st.SendAsync(sendData);

                        if (dir == Direction.Recv)
                        {
                            RefInt totalRecvSize = new RefInt();
                            while (true)
                            {
                                long now = FastTick64.Now;

                                if (now >= tickEnd)
                                {
                                    break;
                                }

                                await TaskUtil.WaitObjectsAsync(
                                    tasks : st.FastReceiveAsync(totalRecvSize : totalRecvSize)._SingleArray(),
                                    timeout : (int)(tickEnd - now),
                                    exceptions : ExceptionWhen.TaskException | ExceptionWhen.CancelException);

                                ret.NumBytesDownload += totalRecvSize;
                            }
                        }
                        else
                        {
                            attachHandle.SetStreamReceiveTimeout(Timeout.Infinite);

                            while (true)
                            {
                                long now = FastTick64.Now;

                                if (now >= tickEnd)
                                {
                                    break;
                                }

                                /*await WebSocketHelper.WaitObjectsAsync(
                                 *  tasks: st.FastSendAsync(SendData, flush: true).ToSingleArray(),
                                 *  timeout: (int)(tick_end - now),
                                 *  exceptions: ExceptionWhen.TaskException | ExceptionWhen.CancelException);*/

                                await st.FastSendAsync(SendData, flush : true);
                            }

                            Task recvResult = Task.Run(async() =>
                            {
                                var recvMemory = await st.ReceiveAllAsync(8);

                                MemoryBuffer <byte> recvMemoryBuf = recvMemory;
                                ret.NumBytesUpload = recvMemoryBuf.ReadSInt64();

                                st.Disconnect();
                            });

                            Task sendSurprise = Task.Run(async() =>
                            {
                                byte[] surprise = new byte[260];
                                surprise.AsSpan().Fill((byte)'!');
                                while (true)
                                {
                                    await st.SendAsync(surprise);

                                    await TaskUtil.WaitObjectsAsync(
                                        manualEvents: sock.Pipe.OnDisconnectedEvent._SingleArray(),
                                        timeout: 200);
                                }
                            });

                            await WhenAll.Await(false, recvResult, sendSurprise);

                            await recvResult;
                        }

                        st.Disconnect();
                        return(ret);
                    }
                    catch (Exception ex)
                    {
                        ExceptionQueue !.Add(ex);
                        throw;
                    }
                }
            }
        }
Esempio n. 2
0
 public WhenAllCollectionObserver(WhenAll parent, int index)
 {
     this.parent = parent;
     this.index  = index;
 }
Esempio n. 3
0
        public async Task <Result?> RunClientAsync()
        {
            CurrentCount.Increment();

            try
            {
                if (Once.IsFirstCall() == false)
                {
                    throw new ApplicationException("You cannot reuse the object.");
                }

                Con.WriteLine("Client mode start");

                ExceptionQueue = new ExceptionQueue();
                SessionId      = Util.RandUInt64();

                List <Task <Result> >        tasks       = new List <Task <Result> >();
                List <AsyncManualResetEvent> readyEvents = new List <AsyncManualResetEvent>();

                using (CancelWatcher cancelWatcher = new CancelWatcher(this.Cancel))
                {
                    for (int i = 0; i < NumConnection; i++)
                    {
                        Direction dir;
                        if (Mode == SpeedTestModeFlag.Download)
                        {
                            dir = Direction.Recv;
                        }
                        else if (Mode == SpeedTestModeFlag.Upload)
                        {
                            dir = Direction.Send;
                        }
                        else
                        {
                            dir = ((i % 2) == 0) ? Direction.Recv : Direction.Send;
                        }

                        AsyncManualResetEvent readyEvent = new AsyncManualResetEvent();
                        var t = ClientSingleConnectionAsync(dir, readyEvent, cancelWatcher.CancelToken);
                        ExceptionQueue.RegisterWatchedTask(t);
                        tasks.Add(t);
                        readyEvents.Add(readyEvent);
                    }

                    try
                    {
                        using (var whenAllReady = new WhenAll(readyEvents.Select(x => x.WaitAsync())))
                        {
                            await TaskUtil.WaitObjectsAsync(
                                tasks : tasks.Append(whenAllReady.WaitMe).ToArray(),
                                cancels : cancelWatcher.CancelToken._SingleArray(),
                                manualEvents : ExceptionQueue.WhenExceptionAdded._SingleArray());
                        }

                        Cancel.ThrowIfCancellationRequested();
                        ExceptionQueue.ThrowFirstExceptionIfExists();

                        ExceptionQueue.WhenExceptionAdded.CallbackList.AddSoftCallback(x =>
                        {
                            cancelWatcher.Cancel();
                        });

                        using (new DelayAction(TimeSpan * 3 + 180 * 1000, x =>
                        {
                            cancelWatcher.Cancel();
                        }, doNotBlockOnDispose: true))
                        {
                            ClientStartEvent.Set(true);

                            using (var whenAllCompleted = new WhenAll(tasks))
                            {
                                await TaskUtil.WaitObjectsAsync(
                                    tasks : whenAllCompleted.WaitMe._SingleArray(),
                                    cancels : cancelWatcher.CancelToken._SingleArray()
                                    );

                                await whenAllCompleted.WaitMe;
                            }
                        }

                        Result ret = new Result();

                        ret.Span = TimeSpan;

                        foreach (var r in tasks.Select(x => x._GetResult()))
                        {
                            ret.NumBytesDownload += r.NumBytesDownload;
                            ret.NumBytesUpload   += r.NumBytesUpload;
                        }

                        ret.NumBytesTotal = ret.NumBytesUpload + ret.NumBytesDownload;

                        ret.BpsUpload   = (long)((double)ret.NumBytesUpload * 1000.0 * 8.0 / (double)ret.Span * 1514.0 / 1460.0);
                        ret.BpsDownload = (long)((double)ret.NumBytesDownload * 1000.0 * 8.0 / (double)ret.Span * 1514.0 / 1460.0);
                        ret.BpsTotal    = ret.BpsUpload + ret.BpsDownload;

                        return(ret);
                    }
                    catch (Exception ex)
                    {
                        await Task.Yield();

                        ExceptionQueue.Add(ex);
                    }
                    finally
                    {
                        cancelWatcher.Cancel();
                        try
                        {
                            await Task.WhenAll(tasks);
                        }
                        catch { }
                    }

                    ExceptionQueue.ThrowFirstExceptionIfExists();
                }

                return(null);
            }
            finally
            {
                CurrentCount.Decrement();
            }
        }