예제 #1
0
        /**
         * Creates a new FuzzyEvent, Schedules it and returns it
         * @param todo the method to call
         * @param from_now_ms the TimeSpan from now to call the method
         * @param latency_ms the acceptable latency for this call in milliseconds
         */
        public FuzzyEvent DoAt(System.Action <DateTime> todo, DateTime at,
                               int latency_ms)
        {
            DateTime   end       = at + new TimeSpan(0, 0, 0, 0, latency_ms);
            FuzzyEvent new_event = new FuzzyEvent(todo, at, end);

            Schedule(new_event);
            return(new_event);
        }
예제 #2
0
        public void Schedule(FuzzyEvent e)
        {
#if BRUNET_SIMULATOR
            int         delay = (int)(e.End - DateTime.UtcNow).TotalMilliseconds;
            SimpleTimer st    = new SimpleTimer(FuzzyEventRunner, e, delay, 0);
            st.Start();
#else
            _incoming_events.Enqueue(e);
#endif
        }
예제 #3
0
        protected static void FuzzyEventRunner(object o)
        {
            FuzzyEvent fe = o as FuzzyEvent;

            if (o == null)
            {
                throw new Exception("o is not a FuzzyEvent!");
            }
            fe.TryRun(DateTime.UtcNow);
        }
예제 #4
0
        /**
         * Creates a new FuzzyEvent, Schedules it and returns it
         * @param todo the method to call
         * @param from_now_ms the TimeSpan from now to call the method in milliseconds
         * @param latency_ms the acceptable latency for this call in milliseconds
         */
        public FuzzyEvent DoAfter(System.Action <DateTime> todo,
                                  int from_now_ms, int latency_ms)
        {
            DateTime   start     = DateTime.UtcNow + new TimeSpan(0, 0, 0, 0, from_now_ms);
            DateTime   end       = start + new TimeSpan(0, 0, 0, 0, latency_ms);
            FuzzyEvent new_event = new FuzzyEvent(todo, start, end);

            Schedule(new_event);
            return(new_event);
        }
예제 #5
0
 /**
  * There can only safely be one of these threads running
  */
 protected void AnnounceThread()
 {
     Brunet.Util.FuzzyEvent fe = null;
     try {
         int     millisec_timeout = 5000; //log every 5 seconds.
         IAction queue_item       = null;
         bool    timedout         = false;
         if (ProtocolLog.Monitor.Enabled)
         {
             IAction           log_act  = new LogAction(_packet_queue);
             Action <DateTime> log_todo = delegate(DateTime dt) {
                 EnqueueAction(log_act);
             };
             fe = Brunet.Util.FuzzyTimer.Instance.DoEvery(log_todo, millisec_timeout, millisec_timeout / 2);
         }
         while (1 == _running)
         {
             queue_item = _packet_queue.Dequeue(millisec_timeout, out timedout);
             if (!timedout)
             {
                 _current_action = queue_item;
                 queue_item.Start();
             }
         }
     }
     catch (System.InvalidOperationException x) {
         //This is thrown when Dequeue is called on an empty queue
         //which happens when the BlockingQueue is closed, which
         //happens on Disconnect
         if (1 == _running)
         {
             ProtocolLog.WriteIf(ProtocolLog.Exceptions, String.Format(
                                     "Running in AnnounceThread got Exception: {0}", x));
         }
     }
     catch (Exception x) {
         ProtocolLog.WriteIf(ProtocolLog.Exceptions, String.Format(
                                 "ERROR: Exception in AnnounceThread: {0}", x));
     }
     finally {
         //Make sure we stop logging:
         if (fe != null)
         {
             fe.TryCancel();
         }
     }
     ProtocolLog.Write(ProtocolLog.Monitor,
                       String.Format("Node: {0} leaving AnnounceThread",
                                     this.Address));
 }
예제 #6
0
        protected void TimerThread()
        {
            Heap <FuzzyEvent>   events            = new Heap <FuzzyEvent>();
            List <FuzzyEvent>   next_todos        = new List <FuzzyEvent>();
            Interval <DateTime> next_schedule_int = null;
            int  wait_interval = -1;
            bool run           = true;
            bool timedout;

            while (run)
            {
                FuzzyEvent fe = _incoming_events.Dequeue(wait_interval, out timedout);
                if (!timedout)
                {
                    //We got a new event
                    if (fe != null)
                    {
                        events.Add(fe);
                    }
                    else
                    {
                        //Got a null event, that means stop:
                        break;
                    }
                }
                DateTime now = DateTime.UtcNow;

                /*
                 * Since we've already been awakened, let's check to see if we can run:
                 */
                if (next_schedule_int != null)
                {
                    if (next_schedule_int.CompareTo(now) <= 0)
                    {
                        //We are safe to go ahead and run:
                        Interlocked.Exchange(ref _last_run, now.Ticks);
                        foreach (FuzzyEvent feitem in next_todos)
                        {
                            try {
                                feitem.TryRun(now);
                            }
                            catch (Exception x) {
                                Console.WriteLine(x);
                                //Something bad happened
                            }
                        }
                        //Now reset and reschedule below:
                        next_todos.Clear();
                        next_schedule_int = null;
                    }
                    else
                    {
                        //It's not yet time to run.
                    }
                }
                //Time to schedule the next wait:
                Interval <DateTime> overlap;
                do
                {
                    if (events.Count > 0)
                    {
                        overlap = events.Peek();
                        if (next_schedule_int != null)
                        {
                            //We already have something scheduled:
                            var new_overlap = next_schedule_int.Intersection(overlap);
                            if (new_overlap == null)
                            {
                                if (overlap.CompareTo(next_schedule_int) <= 0)
                                {
                                    /*
                                     * If there is no overlap, but next_schedule_int is after,
                                     * overlap, we need to reorder things:
                                     */
                                    //Put the next_todos back:
                                    var new_next = events.Pop();
                                    foreach (FuzzyEvent fev in next_todos)
                                    {
                                        events.Add(fev);
                                    }
                                    next_todos.Clear();
                                    next_todos.Add(new_next);
                                    next_schedule_int = new_next;
                                    overlap           = new_next;
                                }
                                else
                                {
                                    //we'll deal with overlap later:
                                    overlap = null;
                                }
                            }
                            else
                            {
                                //There is an overlap
                                //We can combine the old and new event:
                                overlap           = new_overlap;
                                next_schedule_int = overlap;
                                next_todos.Add(events.Pop());
                            }
                        }
                        else
                        {
                            //There was nothing scheduled:
                            next_schedule_int = overlap;
                            next_todos.Add(events.Pop());
                        }
                    }
                    else
                    {
                        overlap = null;
                    }
                } while(overlap != null);

                if (next_schedule_int != null)
                {
                    //Wait as long as possible, we may be able to combine later:
                    TimeSpan to_wait = next_schedule_int.End - now;
                    wait_interval = (int)to_wait.TotalMilliseconds;
                    if (wait_interval < 0)
                    {
                        //Well, we should be able to go ahead and run, so do it:
                        wait_interval = 0;
                    }
                }
                else
                {
                    //Nothing to do, just wait for the next scheduled operation
                    wait_interval = -1;
                }
            }
        }