Пример #1
0
            private int ReceiveFromPkgBuffer(byte[] buffer, int offset, int size)
            {
                //size > 0

                if (myPkg.Available > 0)
                {
                    var sizeToCopy = Math.Min(size, myPkg.Available);
                    myPkg.MoveTo(buffer, offset, sizeToCopy);
                    return(sizeToCopy);
                }
                else
                {
                    while (true)
                    {
                        myPkgHeaderBuffer.Clear();
                        if (!myPkgHeaderBuffer.Read(ref mySocketBuffer, ReceiveFromSocket))
                        {
                            return(0);
                        }

                        Int32 len  = UnsafeReader.ReadInt32FromBytes(myPkgHeaderBuffer.Data);
                        Int64 seqN = UnsafeReader.ReadInt64FromBytes(myPkgHeaderBuffer.Data, sizeof(Int32));

                        if (len == ACK_MSG_LEN)
                        {
                            SendBuffer.Acknowledge(seqN);
                        }
                        else
                        {
                            myPkg.Clear();
                            if (!myPkg.Read(ref mySocketBuffer, ReceiveFromSocket, len))
                            {
                                return(0);
                            }

                            if (seqN > myMaxReceivedSeqn || seqN == 1 /*TODO new client, possible duplicate problem if ack for seqN=1 from previous client's connection hasn't passed*/)
                            {
                                myMaxReceivedSeqn = seqN; //will be acknowledged when we read whole message
                                Assertion.Assert(myPkg.Available > 0, "myPkgBuffer.Available > 0");

                                var sizeToCopy = Math.Min(size, myPkg.Available);
                                myPkg.MoveTo(buffer, offset, sizeToCopy);
                                return(sizeToCopy);
                            }
                            else
                            {
                                myAcktor.SendAsync(seqN);
                            }
                        }
                    }
                }
            }
Пример #2
0
        public unsafe void StressTestWithAck()
        {
//      LogLog.SeverityFilter = LoggingLevel.VERBOSE;
//      LogLog.RecordsChanged += record => { Console.WriteLine(record.Format(true)); };

            long prev = 0;
            ByteBufferAsyncProcessor buffer = null;

            buffer = new ByteBufferAsyncProcessor("TestAsyncProcessor", 8,
                                                  delegate(byte[] data, int offset, int len, ref long seqN)
            {
                long l = 0;
                Log.Root.Catch(() =>
                {
                    fixed(byte *b = data)
                    {
                        l = UnsafeReader.CreateReader(b, 8).ReadLong();
                        Assert.True(l > prev);
                        prev = l;
                        if (l % 1 == 0)
                        {
                            Ack(l);
                        }
                    }
                });
                seqN = l;
            });
            buffer.ShrinkIntervalMs = 10;
            buffer.Start();

            void Ack(long seqn)
            {
                buffer?.Acknowledge(seqn);
            }

            var start = Environment.TickCount;

            bool Until() => Environment.TickCount - start < 1000;

            long next  = 0;
            var  tasks = new List <Task>();

            for (int i = 0; i < 4; i++)
            {
                tasks.Add(Task.Run(() =>
                {
                    var rnd = new Random();

                    while (Until())
                    {
                        lock (tasks)
                        {
                            using (var cookie = UnsafeWriter.NewThreadLocalWriter())
                            {
                                cookie.Writer.Write(++next);
                                buffer.Put(cookie);
                            }
                        }
                        if (rnd.Next(1000) < 1)
                        {
                            Thread.Sleep(1);
                        }
                        if (rnd.Next(1000) < 5)
                        {
                            buffer.Clear();
                        }
                    }
                }));
            }

            Task.WaitAll(tasks.ToArray());
//      Console.WriteLine(next);
//      Console.WriteLine(buffer.ChunkCount);
        }
Пример #3
0
        public unsafe void TestReprocess()
        {
            long prev = 0;
            ByteBufferAsyncProcessor buffer = null;
            List <long> log = new List <long>();

            buffer = new ByteBufferAsyncProcessor("TestAsyncProcessor", 8,
                                                  delegate(byte[] data, int offset, int len, ref long seqN)
            {
                try
                {
                    fixed(byte *b = data)
                    {
                        long l = UnsafeReader.CreateReader(b, 8).ReadLong();
                        if (seqN != 0)
                        {
                            Assert.AreEqual(l, seqN);
                        }
                        seqN = l;
                        log.Add(l);

                        Assert.True(l > prev);
                        prev = l;
                    }
                }
                catch (Exception e)
                {
                    Log.Root.Error(e);
                }
            });

            buffer.ShrinkIntervalMs = 10;
            buffer.Start();

            PutLong(buffer, 1);
            PutLong(buffer, 2);
            PutLong(buffer, 3);
            PutLong(buffer, 4);

            SpinWait.SpinUntil(() => buffer.AllDataProcessed);
            Assert.AreEqual(new List <int> {
                1, 2, 3, 4
            }, log);

            buffer.Acknowledge(2);
            prev = 2;
            buffer.ReprocessUnacknowledged();

            PutLong(buffer, 5);
            SpinWait.SpinUntil(() => buffer.AllDataProcessed);
            Assert.AreEqual(new List <int> {
                1, 2, 3, 4, 3, 4, 5
            }, log);

            buffer.Acknowledge(5);
            buffer.ReprocessUnacknowledged();
            SpinWait.SpinUntil(() => buffer.AllDataProcessed);
            Assert.AreEqual(new List <int> {
                1, 2, 3, 4, 3, 4, 5
            }, log);
        }
Пример #4
0
            private int ReceiveFromPkgBuffer(byte[] buffer, int offset, int size)
            {
                //size > 0

                if (myPkg.Available > 0)
                {
                    var sizeToCopy = Math.Min(size, myPkg.Available);
                    myPkg.MoveTo(buffer, offset, sizeToCopy);
                    return(sizeToCopy);
                }
                else
                {
                    while (true)
                    {
                        myPkgHeaderBuffer.Clear();
                        if (!myPkgHeaderBuffer.Read(ref mySocketBuffer, ReceiveFromSocket))
                        {
                            return(0);
                        }

                        Int32 len = UnsafeReader.ReadInt32FromBytes(myPkgHeaderBuffer.Data);

                        if (len == PING_LEN)
                        {
                            Int32 receivedTimestamp            = UnsafeReader.ReadInt32FromBytes(myPkgHeaderBuffer.Data, sizeof(Int32));
                            Int32 receivedCounterpartTimestamp = UnsafeReader.ReadInt32FromBytes(myPkgHeaderBuffer.Data, sizeof(Int32) + sizeof(Int32));
                            Log.Trace()?.Log($"{Id}: Received PING package " +
                                             $"receivedTimestamp={receivedTimestamp}, " +
                                             $"receivedCounterpartTimestamp={receivedCounterpartTimestamp}, " +
                                             $"currentTimeStamp={myCurrentTimeStamp}, " +
                                             $"counterpartTimestamp={myCounterpartTimestamp}, " +
                                             $"counterpartNotionTimestamp={myCounterpartNotionTimestamp}");
                            myCounterpartTimestamp       = receivedTimestamp;
                            myCounterpartNotionTimestamp = receivedCounterpartTimestamp;

                            if (ConnectionEstablished(myCurrentTimeStamp, myCounterpartNotionTimestamp))
                            {
                                HeartbeatAlive.Value = true;
                            }

                            continue;
                        }

                        Int64 seqN = UnsafeReader.ReadInt64FromBytes(myPkgHeaderBuffer.Data, sizeof(Int32));
                        if (len == ACK_MSG_LEN)
                        {
                            SendBuffer.Acknowledge(seqN);
                        }
                        else
                        {
                            myPkg.Clear();
                            if (!myPkg.Read(ref mySocketBuffer, ReceiveFromSocket, len))
                            {
                                return(0);
                            }

                            if (seqN > myMaxReceivedSeqn || seqN == 1 /*TODO new client, possible duplicate problem if ack for seqN=1 from previous client's connection hasn't passed*/)
                            {
                                myMaxReceivedSeqn = seqN; //will be acknowledged when we read whole message
                                Assertion.Assert(myPkg.Available > 0, "myPkgBuffer.Available > 0");

                                var sizeToCopy = Math.Min(size, myPkg.Available);
                                myPkg.MoveTo(buffer, offset, sizeToCopy);
                                return(sizeToCopy);
                            }
                            else
                            {
                                myAcktor.SendAsync(seqN);
                            }
                        }
                    }
                }
            }