示例#1
0
        public void TestCancel()
        {
            #region Initialization
            object lockObject = new object();
            Timeout timeout = new Timeout(null);
            TimeoutTask[] tasks;

            timeout = new Timeout(lockObject);
            tasks = new TimeoutTask[10];

            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i] = new TimeoutTask();
                timeout.Now = 1000 + i * 100;
                timeout.Schedule(tasks[i]);
            }
            timeout.Now = 100;
            #endregion

            timeout.Duration = 200;
            timeout.Now = 1700;

            for (int i = 0; i < tasks.Length; i++)
                if (i % 2 == 1)
                    tasks[i].Cancel();

            timeout.Tick();

            for (int i = 0; i < tasks.Length; i++)
            {
                Assert.AreEqual(i % 2 == 0 && i < 6, tasks[i].IsExpired, "isExpired " + i);
            }
        }
示例#2
0
        public void TestDelay()
        {
            #region Initialization
            object lockObject = new object();
            Timeout timeout = new Timeout(null);
            TimeoutTask[] tasks;

            timeout = new Timeout(lockObject);
            tasks = new TimeoutTask[10];

            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i] = new TimeoutTask();
                timeout.Now = 1000 + i * 100;
                timeout.Schedule(tasks[i]);
            }
            timeout.Now = 100;
            #endregion

            TimeoutTask task = new TimeoutTask();

            timeout.Now = 1100;
            timeout.Schedule(task, 300);
            timeout.Duration = 200;

            timeout.Now = 1300;
            timeout.Tick();
            Assert.IsFalse(task.IsExpired, "delay");

            timeout.Now = 1500;
            timeout.Tick();
            Assert.IsFalse(task.IsExpired, "delay");

            timeout.Now = 1700;
            timeout.Tick();
            Assert.IsTrue(task.IsExpired, "delay");
        }
示例#3
0
        public void TestTouch()
        {
            #region Initialization
            object lockObject = new object();
            Timeout timeout = new Timeout(null);
            TimeoutTask[] tasks;

            timeout = new Timeout(lockObject);
            tasks = new TimeoutTask[10];

            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i] = new TimeoutTask();
                timeout.Now = 1000 + i * 100;
                timeout.Schedule(tasks[i]);
            }
            timeout.Now = 100;
            #endregion

            timeout.Duration = 200;
            timeout.Now = 1350;
            timeout.Schedule(tasks[2]);

            timeout.Now = 1500;
            timeout.Tick();
            for (int i = 0; i < tasks.Length; i++)
            {
                Assert.AreEqual(i != 2 && i < 4, tasks[i].IsExpired, "isExpired " + i);
            }

            timeout.Now = 1550;
            timeout.Tick();
            for (int i = 0; i < tasks.Length; i++)
            {
                Assert.AreEqual(i < 4, tasks[i].IsExpired, "isExpired " + i);
            }
        }
 public void Initialise()
 {
     isBlocking = false;
     job = null;
     jobResult = null;
     storedException = null;
     task = null;
     timeout = null;
     timeoutResult = false;
 }
示例#5
0
        public void TestStress()
        {
            #region Initialization
            object lockObject = new object();
            Timeout timeout = new Timeout(null);
            TimeoutTask[] tasks;

            timeout = new Timeout(lockObject);
            tasks = new TimeoutTask[10];

            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i] = new TimeoutTask();
                timeout.Now = 1000 + i * 100;
                timeout.Schedule(tasks[i]);
            }
            timeout.Now = 100;
            #endregion

            int LOOP = 500;
            bool[] running = new bool[] { true };
            int[] count = new int[] { 0, 0, 0 };

            timeout.Now = (DateTime.UtcNow.Ticks / 1000);
            timeout.Duration = 500;

            // Start a ticker thread that will tick over the timer frequently.
            System.Threading.Thread ticker = new System.Threading.Thread(

                new System.Threading.ThreadStart(
                  () =>
                  {
                      while (running[0])
                      {
                          try
                          {
                              // use lock.wait so we have a memory barrier and
                              // have no funny optimisation issues.
                              lock (lockObject)
                              {
                                  System.Threading.Monitor.Wait(lockObject, 30);
                              }
                              System.Threading.Thread.Sleep(30);
                              timeout.Tick((DateTime.UtcNow.Ticks / 1000));
                          }
                          catch (Exception e)
                          {
                              Console.Error.WriteLine(e.StackTrace);
                          }
                      }
                  }
                    )
                );
            ticker.Start();

            // start lots of test threads
            for (int i = 0; i < LOOP; i++)
            {
                //
                System.Threading.Thread th = new System.Threading.Thread(

                    new System.Threading.ThreadStart(
                  () =>
                  {
                      // count how many threads were started (should == LOOP)
                      lock (count)
                      {
                          count[0]++;
                      }

                      // create a task for this thread
                      TimeoutTask task = new TimeoutTask1(count);

                      // this thread will loop and each loop with schedule a
                      // task with a delay  on top of the timeouts duration
                      // mostly this thread will then cancel the task
                      // But once it will wait and the task will expire

                      int once = (int)(10 + ((DateTime.UtcNow.Ticks / 1000) % 50));

                      // do the looping until we are stopped
                      int loop = 0;
                      while (running[0])
                      {
                          try
                          {
                              long delay = 1000;
                              long wait = 100 - once;
                              if (loop++ == once)
                              {
                                  // THIS loop is the one time we wait 1000ms
                                  lock (count)
                                  {
                                      count[1]++;
                                  }
                                  delay = 200;
                                  wait = 1000;
                              }

                              timeout.Schedule(task, delay);

                              // do the wait
                              System.Threading.Thread.Sleep((int)wait);

                              // cancel task (which may have expired)
                              task.Cancel();
                          }
                          catch (Exception e)
                          {
                              Console.Error.WriteLine(e.StackTrace);
                          }
                      }
                  }
                ));
                th.Start();
            }

            // run test for 5s
            System.Threading.Thread.Sleep(8000);
            lock (lockObject)
            {
                running[0] = false;
            }
            // give some time for test to stop
            System.Threading.Thread.Sleep(2000);
            timeout.Tick((DateTime.UtcNow.Ticks / 1000));
            System.Threading.Thread.Sleep(1000);

            // check the counts
            Assert.AreEqual(LOOP, count[0], "count threads");
            Assert.AreEqual(LOOP, count[1], "count once waits");
            Assert.AreEqual(LOOP, count[2], "count expires");
        }
示例#6
0
        protected override Task OnConnect()
        {
            _connectionCompleted      = false;
            _closeConnection          = false;
            _receivedSegments         = new List <byte[]>();
            _expectedSegments         = 0;
            _expectedSegmentsCheckSum = null;
            _incomingQueue            = new ProducerConsumerQueue <byte[]>();
            _conductorInitialized     = false;

            _connectionCompletionSource = new TaskCompletionSource <object>();

            _signalingTransporter.RegisterRequestHandler <WebRTCIceCandidateRequest, WebRTCIceCandidateResponse>(OnWebRTCCandidateRequest);

            Logger.LogDebug("Initializing adapter with role '{Role}'.", Role);

            if (Role == WebRTCAdapterRole.Accept)
            {
                ThreadFactory.StartNew(async() =>
                {
                    try
                    {
                        await InitConnection();

                        if (_offerRequest != null)
                        {
                            Logger.LogDebug("Adapter initialized by an offer request. sending answer...");
                            var response = await OnWebRTCOfferRequest(_offerRequest);
                            if (_closeConnection)
                            {
                                return;
                            }
                            _signalingTransporter.SendResponse(response.Response, _offerRequestToken);
                        }
                        else
                        {
                            Logger.LogDebug("Waiting for WebRTC offer...");
                        }
                    }
                    catch (Exception ex)
                    {
                        if (!_connectionCompleted)
                        {
                            _connectionCompleted = true;
                            _connectionCompletionSource.SetException(new ResonanceWebRTCConnectionFailedException(ex));
                            _closeConnection = true;
                        }
                    }
                });
            }
            else
            {
                ThreadFactory.StartNew(async() =>
                {
                    try
                    {
                        await InitConnection();

                        var offer = await CreateOffer();

                        var response = await _signalingTransporter.SendRequestAsync <WebRTCOfferRequest, WebRTCOfferResponse>(new WebRTCOfferRequest()
                        {
                            Offer = offer,
                        }, new ResonanceRequestConfig()
                        {
                            Timeout = TimeSpan.FromSeconds(30)
                        });

                        _conductor.OnOfferReply("answer", response.Answer.Sdp);

                        FlushIceCandidates();
                    }
                    catch (Exception ex)
                    {
                        if (!_connectionCompleted)
                        {
                            _connectionCompleted = true;
                            _connectionCompletionSource.SetException(new ResonanceWebRTCConnectionFailedException(ex));
                            _closeConnection = true;
                        }
                    }
                });
            }

            TimeoutTask.StartNew(() =>
            {
                if (!_connectionCompleted)
                {
                    _connectionCompleted = true;
                    _connectionCompletionSource.SetException(new ResonanceWebRTCConnectionFailedException(new TimeoutException("Could not initialize the connection within the given timeout.")));
                    _closeConnection = true;
                }
            }, ConnectionTimeout);

            return(_connectionCompletionSource.Task);
        }
示例#7
0
        public uint QueueTimeout(TimeSpan span, TimeoutTask task)
        {
            DelegateTask dTask = cache.Dequeue();
            dTask.Timeout = task;

            return dispatcher.Add(span, delegate {
                QueueWait(dTask);
                return dTask.TimeoutResult;
            });
        }
示例#8
0
        private async Task <bool> WaitForAcquireAsync(IReadOnlyDictionary <IDatabase, Task <bool> > tryAcquireTasks)
        {
            using var timeout = new TimeoutTask(this._primitive.AcquireTimeout, this._cancellationToken);
            var incompleteTasks = new HashSet <Task>(tryAcquireTasks.Values)
            {
                timeout.Task
            };

            var successCount = 0;
            var failCount    = 0;
            var faultCount   = 0;

            while (true)
            {
                var completed = await Task.WhenAny(incompleteTasks).ConfigureAwait(false);

                if (completed == timeout.Task)
                {
                    await completed.ConfigureAwait(false); // propagates cancellation

                    return(false);                         // true timeout
                }

                if (completed.Status == TaskStatus.RanToCompletion)
                {
                    var result = await((Task <bool>)completed).ConfigureAwait(false);
                    if (result)
                    {
                        ++successCount;
                        if (RedLockHelper.HasSufficientSuccesses(successCount, this._databases.Count))
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        ++failCount;
                        if (RedLockHelper.HasTooManyFailuresOrFaults(failCount, this._databases.Count))
                        {
                            return(false);
                        }
                    }
                }
                else // faulted or canceled
                {
                    // if we get too many faults, the lock is not possible to acquire, so we should throw
                    ++faultCount;
                    if (RedLockHelper.HasTooManyFailuresOrFaults(faultCount, this._databases.Count))
                    {
                        var faultingTasks = tryAcquireTasks.Values.Where(t => t.IsCanceled || t.IsFaulted)
                                            .ToArray();
                        if (faultingTasks.Length == 1)
                        {
                            await faultingTasks[0].ConfigureAwait(false); // propagate the error
                        }

                        throw new AggregateException(faultingTasks.Select(t => t.Exception ?? new TaskCanceledException(t).As <Exception>()))
                              .Flatten();
                    }

                    ++failCount;
                    if (RedLockHelper.HasTooManyFailuresOrFaults(failCount, this._databases.Count))
                    {
                        return(false);
                    }
                }

                incompleteTasks.Remove(completed);
                Invariant.Require(incompleteTasks.Count > 1, "should be more than just timeout left");
            }
        }
示例#9
0
        /// <summary>
        /// Called when the adapter is connecting.
        /// </summary>
        /// <returns></returns>
        protected override Task OnConnect()
        {
            bool completed = false;

            TaskCompletionSource <object> completionSource = new TaskCompletionSource <object>();

            Task.Factory.StartNew(() =>
            {
                try
                {
                    _client = SignalRClientFactory.Default.Create(Mode, Url);
                    _client.StartAsync().GetAwaiter().GetResult();

                    if (Role == SignalRAdapterRole.Connect)
                    {
                        _client.On(ResonanceHubMethods.Connected, () =>
                        {
                            try
                            {
                                if (!completed)
                                {
                                    completed = true;
                                    completionSource.SetResult(true);
                                }
                            }
                            catch (Exception ex)
                            {
                                if (!completed)
                                {
                                    Logger.LogError(ex, "Error occurred after successful connection.");
                                    completed = true;
                                    completionSource.SetException(ex);
                                }
                            }
                        });

                        _client.On(ResonanceHubMethods.Declined, () =>
                        {
                            try
                            {
                                if (!completed)
                                {
                                    completed = true;

                                    var ex = new ConnectionDeclinedException();

                                    Logger.LogError(ex, "Error occurred after session created.");
                                    completionSource.SetException(ex);
                                }
                            }
                            catch (Exception ex)
                            {
                                if (!completed)
                                {
                                    Logger.LogError(ex, "Error occurred after session created.");
                                    completed = true;
                                    completionSource.SetException(ex);
                                }
                            }
                        });
                    }

                    _client.On(ResonanceHubMethods.Disconnected, () =>
                    {
                        if (State == ResonanceComponentState.Connected)
                        {
                            //OnDisconnect(false); //Don't know what to do here.. We already have the resonance disconnection message.
                            //Maybe just raise an event..
                        }
                    });

                    _client.On(ResonanceHubMethods.ServiceDown, () =>
                    {
                        OnFailed(new ServiceDownException());
                    });

                    Logger.LogInformation("Authenticating with the remote hub {HubUrl}...", _client.Url);
                    _client.InvokeAsync(ResonanceHubMethods.Login, Credentials).GetAwaiter().GetResult();

                    if (Role == SignalRAdapterRole.Connect)
                    {
                        Logger.LogInformation("Connecting to service {ServiceId}...", ServiceId);
                        SessionId = _client.InvokeAsync <String>(ResonanceHubMethods.Connect, ServiceId).GetAwaiter().GetResult();
                    }
                    else
                    {
                        Logger.LogInformation("Accepting connection {SessionId}...", SessionId);
                        _client.InvokeAsync(ResonanceHubMethods.AcceptConnection, SessionId).GetAwaiter().GetResult();

                        if (!completed)
                        {
                            completed = true;
                            completionSource.SetResult(true);
                        }
                    }

                    _client.On <byte[]>(ResonanceHubMethods.DataAvailable, (data) => { OnDataAvailable(data); });

                    _client.Error        += OnError;
                    _client.Reconnecting += OnReconnecting;
                    _client.Reconnected  += OnReconnected;
                }
                catch (Exception ex)
                {
                    completed = true;
                    Logger.LogError(ex, "Error occurred while trying to connect.");
                    completionSource.SetException(ex);
                }
            });

            TimeoutTask.StartNew(() =>
            {
                if (!completed)
                {
                    completed = true;
                    completionSource.SetException(new TimeoutException("Could not connect after the given timeout."));
                }
            }, ConnectionTimeout);

            return(completionSource.Task);
        }
示例#10
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="task">task</param>
        /// <param name="delay">A delay in addition to the default duration of the timeout</param>
        public void Schedule(TimeoutTask task,long delay)
        {
            lock (_lock)
            {
                if (task._timestamp!=0)
                {
                    task.Unlink();
                    task._timestamp=0;
                }
                task._timeout=this;
                task._expired=false;
                task._delay=delay;
                task._timestamp = _now+delay;

                TimeoutTask last=_head._prev;
                while (last!=_head)
                {
                    if (last._timestamp <= task._timestamp)
                        break;
                    last=last._prev;
                }
                last.Link(task);
            }
        }
示例#11
0
 public void Schedule(TimeoutTask task)
 {
     Schedule(task,0L);
 }
示例#12
0
        public void TestStress()
        {
            #region Initialization
            object        lockObject = new object();
            Timeout       timeout    = new Timeout(null);
            TimeoutTask[] tasks;


            timeout = new Timeout(lockObject);
            tasks   = new TimeoutTask[10];

            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i]    = new TimeoutTask();
                timeout.Now = 1000 + i * 100;
                timeout.Schedule(tasks[i]);
            }
            timeout.Now = 100;
            #endregion


            int    LOOP    = 500;
            bool[] running = new bool[] { true };
            int[]  count   = new int[] { 0, 0, 0 };

            timeout.Now      = (DateTime.UtcNow.Ticks / 1000);
            timeout.Duration = 500;

            // Start a ticker thread that will tick over the timer frequently.
            System.Threading.Thread ticker = new System.Threading.Thread(

                new System.Threading.ThreadStart(
                    () =>
            {
                while (running[0])
                {
                    try
                    {
                        // use lock.wait so we have a memory barrier and
                        // have no funny optimisation issues.
                        lock (lockObject)
                        {
                            System.Threading.Monitor.Wait(lockObject, 30);
                        }
                        System.Threading.Thread.Sleep(30);
                        timeout.Tick((DateTime.UtcNow.Ticks / 1000));
                    }
                    catch (Exception e)
                    {
                        Console.Error.WriteLine(e.StackTrace);
                    }
                }
            }
                    )
                );
            ticker.Start();

            // start lots of test threads
            for (int i = 0; i < LOOP; i++)
            {
                //
                System.Threading.Thread th = new System.Threading.Thread(

                    new System.Threading.ThreadStart(
                        () =>
                {
                    // count how many threads were started (should == LOOP)
                    lock (count)
                    {
                        count[0]++;
                    }

                    // create a task for this thread
                    TimeoutTask task = new TimeoutTask1(count);

                    // this thread will loop and each loop with schedule a
                    // task with a delay  on top of the timeouts duration
                    // mostly this thread will then cancel the task
                    // But once it will wait and the task will expire


                    int once = (int)(10 + ((DateTime.UtcNow.Ticks / 1000) % 50));

                    // do the looping until we are stopped
                    int loop = 0;
                    while (running[0])
                    {
                        try
                        {
                            long delay = 1000;
                            long wait  = 100 - once;
                            if (loop++ == once)
                            {
                                // THIS loop is the one time we wait 1000ms
                                lock (count)
                                {
                                    count[1]++;
                                }
                                delay = 200;
                                wait  = 1000;
                            }

                            timeout.Schedule(task, delay);

                            // do the wait
                            System.Threading.Thread.Sleep((int)wait);

                            // cancel task (which may have expired)
                            task.Cancel();
                        }
                        catch (Exception e)
                        {
                            Console.Error.WriteLine(e.StackTrace);
                        }
                    }
                }
                        ));
                th.Start();
            }

            // run test for 5s
            System.Threading.Thread.Sleep(8000);
            lock (lockObject)
            {
                running[0] = false;
            }
            // give some time for test to stop
            System.Threading.Thread.Sleep(2000);
            timeout.Tick((DateTime.UtcNow.Ticks / 1000));
            System.Threading.Thread.Sleep(1000);

            // check the counts
            Assert.AreEqual(LOOP, count[0], "count threads");
            Assert.AreEqual(LOOP, count[1], "count once waits");
            Assert.AreEqual(LOOP, count[2], "count expires");
        }