Re: Lahman, how ya doing?



Responding to Hansen...

I also need jobs that do task 1 at time interval 1, and task 2 at time interval 2. But it won't be hard to add a
time.add_task(&c3, 5, 20);

At the risk of being picky, doesn't this do the /same/ task twice?

I am a little nervous about the notion of 'interval'. That sounds like a hard real-time constraint. I assume this is a delay for settling times or something. But first let me digress to look at the vanilla precedence view where all one needs to do is ensure some task completes before another starts.

You kind of get that for free if you use a single event queue and popping an event doesn't return in the event queue manager until the task is completed. If, though, the timer event is only one of several events that may be issued to complete tasks, one needs a different mechanism.

The approach you suggest here assumes you know <fairly> exactly how long the preceding task will take to execute. That delay then gets parameterized into the Timer. IOW, task0 goes at t0, task1 goes at t0 + interval1, and task2 goes at t0 + interval2. That may work fine if the intervals have a lot of safety in them, but there are some potential pitfalls.

Mainly you at the mercy of the accuracy of intervalN, which is cumulative with the N-1 previous tasks. If the processing times or the order or processing change it may not be obvious that the Timer parameters need to change. Another possible problem is a race condition if there is another set of dependent tasks that are triggered from a different t0 in the timer. Yet another problem is that if the intervalNs have lots of builtin safety, the application may be sitting on its thumbs a lot of the time and that might reduce your accuracy because you are effectively reducing the sample size. (Obviously less of a problem if you /need/ a delay for settling or whatever.)

A more rigorous approach that gets around these problems is simple daisy-chaining of the tasks. When a prerequisite task finishes, it generates the trigger event for the next task rather than the timer. Now the Timer just needs to generate events for the initial task in each set of dependent tasks or an event for some overall periodicity.

Note that one can even change the role of the Timer from doling out events based on clock ticks to a arbitrator. Suppose you have an Activity Diagram with multiple dependencies among tasks like

Task1       task2      task3
  |           |          |
  +----+ +----+          |
       | |               |
      =====              |
        |                |
      task4              |
        |                |
        +-------+ +------+
                | |
               =====
                 |
               task5

Now the Timer can manage a suite of semaphores for the tasks. It starts off with one task, say task2 and sends it a trigger event. When task2 completes, it sends back an I'm done event to Timer. Timer then sets the task2 semaphore and and checks its rules (each task has a bitmap of semaphores that must be set for it to execute). It selects some task whose prerequisites are done, say task3. And so on... When all the semaphores are set, Timer clears them and starts over.]

So what about delays? I went through this because life is rarely simple. I see the inherent sequencing as a distinct problem from the delays. The delay is something one does /after/ deciding one could do something. So on general principle I am not comfortable with Timer addressing both issues. If one separates the delay concern, then it doesn't matter which approach above is used to determine when the delay should start counting.

Let Timer send an event to a Delay instance for the relevant task once that tasks' prerequisites are in place. The Delay does it own tick counting for the interval and then issues the actual event that triggers the relevant task. IOW, I could see the state machine for Delay looking something like:

                   E1:start
         [Reset] <------------------- [Idle]
            |                            |
            | E2:timer tick              | E4:task completed
            |                            |
            V                            |
+----- [Counting] ---------------> [Delay Completed]
|           ^       E3:trigger
|           |
+-----------+
 E2:timer tick

Timer sends the E1:start event when the task is eligible to execute. It also sends E2:timer tick events that are ignored unless the current state is [Reset] or [Counting]. The [Counting] state just counts the ticks until the predefined number for the delay, in which case it generates E3:trigger to itself. The [Delay Completed] state just generates the actual processing triggering event to the task object. When the task is completed it sends back the E4:task completed event. If Timer is being fancy with dependencies, then the [Idle] state sends an event to Timer to announce the task is done so it can set its semaphore or whatever.

This might seem like overkill, especially when one realizes the only things these states do is send events and initialize, increment, and check a counter attribute. But the state machine is actually capturing rules statically and one has completely isolated all the delay logic from both the Timer and the relevant Task. That is reflected in the fact that the Timer and Task know nothing about delays; the only "logic" they have is issuing the E1, E2, and E4 events. So one can insert or remove a delay by just changing where the events go. As a bonus, all delays have exactly the same processing (modified parametrically by providing a tick count to compare when the Delay object is instantiated). IOW, it is statically significantly more complicated but dynamically simpler and more robust.


************* There is nothing wrong with me that could not be cured by a capful of Drano.

H. S. Lahman
hsl@xxxxxxxxxxxxxxxxx
Pathfinder Solutions  -- Put MDA to Work
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
(888)OOA-PATH



.



Relevant Pages

  • Re: Lahman, how ya doing?
    ... I assume this is a delay for settling ... It's a simulation, so simulated time will be frozen until all tasks ... If, though, the timer event is only one of several ... Heat goes from the heater to thermal block 1, ...
    (comp.object)
  • RE: Timed and blinking messages
    ... Warning procedure that is located in the Userform code as well. ... Private Sub UserForm_Click ... Do While Timer < Delay ...
    (microsoft.public.excel.programming)
  • RE: Timed and blinking messages
    ... the Warning macro will loop endlessly. ... Private Sub UserForm_Click ... Do While Timer < Delay ...
    (microsoft.public.excel.programming)
  • RE: Timed and blinking messages
    ... below Warning procedure. ... Do While Timer < Delay ... display a self-closing message in the form when a certain condition is met, ...
    (microsoft.public.excel.programming)
  • Implementation issue in State Machine
    ... I am facing an implementation issue while trying to acheive a delay ... input Trigger event CLK? ... I intend that the other Inputs & Outputs of ... signal and assign it to a local event and check delay based on the ...
    (comp.soft-sys.matlab)

Loading