Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

How to flush AF queue?

I can't figure it out, but I am 100% sure it is needed.

Let's say I have 2 actors, Root-A <-> Nested-B

 

Root-A has a "helper UI loop", in the actor core, and front panel visible.

Nested-B is a "controller".

 

So I see the Nested-B as a "controller", and I interact via Root-A to send messaged to its queue, for example:

1) set parameters

2) run the test

 

the "run test" inside Nested-B, just "batch send" to ITSELF some messages (they are the "test-steps", because a test is made up by N steps.

Right?

 

so

 

Imagine each test step is just a wait (N) seconds.

 

Suppose I want to ABORT the test.

 

  1. I want to send abort message in front of queue. But how?
  2. how can I flush the queue? After abort, the actor should not quit, but stay alive for another test run.
  3. In my root I should avoid sending other messages to the Actor-B loop, what is the best strategy? Disable UI controls? I a user click 5 times "run test" button, I don't want to queue 5 runs of course.

 

 

0 Kudos
Message 1 of 11
(4,566 Views)

It sounds like a significant fraction of your problem might be possible to solve using the Message Priority field available when sending a message.

 

If you queue the test steps at a low or normal priority, you could send a high priority message to block steps.

 

To then skip through remaining messages, you could either change the VI called by the test messages to check some value (boolean or into, perhaps) to determine if it should proceed, or you could provide an implementation of Receive Message (I think that's the name) to drop messages of the specific type based on a similar boolean or int flag.


GCentral
0 Kudos
Message 2 of 11
(4,560 Views)

Nope, you can't drop messages like you say.

A message class can override "drop message core":

"Defines what a message does if it is in the message queue when the queue is released. At this point, the actor has shut down, so it will never process the message."

It's not my case.

 

As for message priority, documentation doesn't say anything about priority politic :///

0 Kudos
Message 3 of 11
(4,550 Views)

You can store the AF messages as objects in a separate job queue. After each step is done, check the queue for the next step and send the message to the actor's self-enqueuer. That way you can use the regular LV queue vis to manipulate the job queue, and a stop message won't have to wait behind all the test steps (except for if one is currently executing). 

Message 4 of 11
(4,545 Views)

@Ironman_ wrote:

Nope, you can't drop messages like you say.

A message class can override "drop message core":

"Defines what a message does if it is in the message queue when the queue is released. At this point, the actor has shut down, so it will never process the message."

It's not my case.

 

As for message priority, documentation doesn't say anything about priority politic :///


Respectfully, you're wrong. You can drop messages like I say. Attached are a small example project I wrote for you showing dropping by the two criteria I mentioned (although if you wanted to use this, you should take more care regarding the error code value, connecting error wires, and probably remove the front panel updates in the calling actor because the UI switch is slow and likely unnecessary except for demo purposes).

 

It's saved for 2017 and 2014, and I wrote it in 2017. I haven't tested the 2014 version. If you need an older version, let me know.

 

As you mention, "Drop Message Core.vi" is for handling messages remaining in the queue when the Actor stops - "Receive Message.vi" (as I said) is the one called when messages are about to be processed.

 

All of that being said, as Colin pointed out, if your messages take a long time to run then you should consider passing them off to a separate queue for handling, so that your messages to that actor can always be handled in a timely manner. In the example project I attach, the actor will still take the remaining wait time for the current message before changing behaviour or exiting when Stop is clicked. Depending on how quickly you need to interrupt your tasks, you might need to additionally allow communication with an executing VI to stop the execution mid-step.


GCentral
Download All
0 Kudos
Message 5 of 11
(4,532 Views)

thank you very much, I'll do my test then will return for conclusions

0 Kudos
Message 6 of 11
(4,509 Views)

I can't use the solution with "receive message" override, because it's too dangerous and doesn't scale.

 

1) It doesn't scale bc of "preserve runtime class". Your example works but it's too simple, and I don't want to add more msg classes to the "test if it's a class"....

The receice msg triggers for *every* msg, and it's VERY dangerous, I got locked out for the first time (you know: actor stop, but libs are locked means something is still running), and I don't like it.

 

2) I used "send batch msg", passing the msg array ["run test 1 msg", "run test 2 msg", "run test 3 msg"], and I noticed that this doesn't correspond to 3 messages! but it is indeed a SINGLE message, that will call 3 methods on the actor.

So this is much different than send 3 separates msgs, and bypasses the "receive msg" overload shenaningans.

 

Now I will try the solution with the "embedded queue"

 

PS: I also noticed how dangerous is to (mis)click "run continuosly" on the laucher.vi Smiley Mad

 

 

0 Kudos
Message 7 of 11
(4,497 Views)

Some interesting points indeed.

 

Regarding scalability, you could consider having your test messages inherit from some specific message class and test against that - I haven't checked but it should be you can just make the change via the inheritance page in class properties after using the Message maker like usual.

 

Regarding batch messages - I hadn't considered that. Probably if you use batch messages (sounds like you do) you'd need to include that as a type to check against, possibly separately, then do the work of unpacking the batch message yourself. I agree this is messy (and I don't remember from the top of my head exactly how it is unpacked - presumably in Batch Msg:Do.vi).

 

An alternative would be to provide a message to a "My Batched Action.vi" which called the three parts together. This is effectively the same as a batch message, but if you frequently create different collections of messages it isn't really feasible...

 

Regarding the launcher - yes, probably not a good choice for run continuously. Normally I'd remove those options and/or add a dialog to the launcher, but for forum demo code... Sorry you had a bad experience with it.


GCentral
0 Kudos
Message 8 of 11
(4,486 Views)

Ok so finally I've come up with a solution that satisfies me.

 

In the "controller actor" (the actor that manages the test sequence), I include a bool "abort" into class data.

Then I don't use "send batch" because this has a big drawback in this case: I can't receive other messages.

When I receive the abort msg, the controller abort.vi will set the abort=true.

Then in every test (each "case" of the QMH equivalent of an actor) I check abort, if true, I do nothing.

 

Abort msg is sent by GUI actor with High priority, so it will be dequeued immediately after the current test.

 

So technically I don't skip or flush any messages.

I've verified the messages with Actor monitor.

 

Thanks for the inputs, I will come up with other discussions.

0 Kudos
Message 9 of 11
(4,476 Views)

@colin.campbell wrote:

You can store the AF messages as objects in a separate job queue. After each step is done, check the queue for the next step and send the message to the actor's self-enqueuer. That way you can use the regular LV queue vis to manipulate the job queue, and a stop message won't have to wait behind all the test steps (except for if one is currently executing). 


One can extend this idea by having a helper loop dedicated to handling work on the job queue, allowing the Actor’s main message handler to be instantly responsive to all messages, even if the individual jobs take a long time.  One could even abort in the middle of a long job, by having something like an “Abort” notifier that the helper loop periodically checks as it runs through a job.   Any time-delays needed by the job can be performed by a wait-on-notification with timeout on the Abort notifier, making time delays abortable too.

 

I think people tend to be too quick to "push complexity into the messaging queue”.  Trying to mix messaging an actor with a jobs backlog could make using an actor less obvious.  For example, if I send “Abort”, and then immediately send an new set of Tests, will those new Tests be executed or dropped?  How do I know when it is finished aborting?  

0 Kudos
Message 10 of 11
(4,465 Views)