Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Time Based Events with Changing Intervals

Solved!
Go to solution

I have several different cases where I need to send do something some time after an "event" has occured.  For this I would simply use a single copy Time-Delayed Send Message.  The problem arises when I want to change the time to wait between sends often.  A few examples:

 

After an event occurs I want to send a message 5 seconds, 25 seconds, 1 minute, 10 minutes and 100 minutes afterwards.  Would I need to create a seperate Time-Delayed Send Message for each of these?

 

What happens if I orginally want the event to fire after say 1 minute then because of some other event want it to instead occur after 2 minutes.  Do I have to discard the first and create a new one?  If so tracking when the event occured how long the current timer has been running and how long the new one should run is daunting.

 

I believe my best bet is to create my own custom asynchronous timer that allows me to modify its wait time.  It seems to be tricky however as I would prefer to avoid polling based timers but using them would certainly be easiest.

 

Thoughts or advice?

0 Kudos
Message 1 of 7
(4,184 Views)

Bump!  Is this not something anyone else has had to do?  Did I explain the situation poorly?

0 Kudos
Message 2 of 7
(4,119 Views)
Solution
Accepted by topic author jdaming

Sorry... missed this the first time.

 

No, I've never heard of anyone needing this functionality, nor have I ever needed it myself. But let's discuss what to do...

-------------------

Alternative 0

Obviously, having multiple time-delayed messages works. Set them each up as "send once" and you're done. So there's that.

---------------------

Alternative 1

I would just have one time-delayed message. Set it up to send once at the first delay. And I would record that delay in the message's own data payload. Then in the message's Do.vi, the message can do whatever it needs to the actor and then send itself again, ideally using the same time-delayed message sender. I would do it this way for multiple reasons:

  1. Less mechanism to have to control. I just need one time-delayed message stored in my actor that can be shut down if Stop message gets sent.
  2. Having only one time-delayed message at a time prevents some quirk of the system from sending two time-delays back-to-back. If I have multiple time-delay messages, I have to worry about that if the time delays get close together. Your times are spaced pretty far apart, but you don't know it'll stay that way -- requirements change.

The drawback to this approach is precision -- the first message is sent at 5 seconds, then it sits in the queue, gets handled, and then sends the next one to happen 25 seconds later. The time it sits in the queue is additional time delay. Maybe that's unacceptable to you? If you need the precision, you do need to use separate senders.

-----------------

Alternative 2

Do a Save As and make a copy of the existing Time Delayed Message VIs. Rewrite the internals of those VIs so that instead of taking a single scalar delay, you can pass in an array of delays. Then just process through the array. This solution has the advantage of you still only need one time-delayed message sender in your actor object AND you get the precision of message timing.

 

--------------------------

Anyone think of any others?

0 Kudos
Message 3 of 7
(4,116 Views)

Thanks for the reply!  I have had 3 different projects now that I have needed this on, but this is the first time I have had to do it in AF as the others just used QMH.

 

I went ahead and implemented Alternative 2.  It was fairly easy.  I like the option of including multiple times and this works in two different scenarios for me.  One is like a backoff algorithm that sends messages at progressively later times.  The other is two timed tasks following each other (think do something for 30 seconds then wait 10 minutes, repeat infinitely).

 

My only current concern is that we would like to allow the user to change the time during operation.  I think this requires that I record the "start time" and if the user wants to change the time I will send the current Time-Delayed Message a stop and create a new one with the difference in time from the new setpoint and the time elapsed.  Afterwards I would resume the new double cycle 

0 Kudos
Message 4 of 7
(4,110 Views)

@AristosQueue (NI) wrote:

--------------------------

Anyone think of any others?


Look at the guts of the Time Delay message, and use them to write an actor with similar functionality, but that also takes a "change timing" message.  If you use an event structure as the timing mechanism, instead of a notifier, you can probably manage to change the timing of a pending message, to within some small error.

 

You can also get away from the pesky drift issue in the current Time Delay message, which can be annoying to some.

0 Kudos
Message 5 of 7
(4,107 Views)

I like this idea cause I would like to do something that is reusable and I feel I'm not really doing that here.  What are the downsides of doing it with an Event Structure?  Any that might relate to using this on an RT system?

0 Kudos
Message 6 of 7
(4,105 Views)

You can get away from the drift even with the notifiers if you just track your base time and subtract out the drift each iteration. It's pretty much the same work you'd have if you did it with the event structure.

0 Kudos
Message 7 of 7
(4,103 Views)