Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

How to create reply message on request

I feel like I'm painfully close to understanding this...let's say that I need to have Actor A change the current in the lightbulb N times, and then at each of the N currents measure the photodiode managed by actor B. This is a synchronous task. ABABAB...until AB has repeated N times.

 

With synchronous reply messaging, I could just put the sync reply A wired into sync reply B in a loop and do it N times. This would lock root until all N are done.

 

With asynchronous reply messaging would it go something like this? Root knows it wants to take N measurements, so its in a mode where it fires an async reply to A to change the current. When it receives A's async reply later with the new current, it uses A's async reply msg to fire off an async reply message to B. When B's async measurement comes back, it uses that reply to go to A...and so on until the N measuremetn pairs are done. After collecting N pairs, then it changes state to idle. 

 

Am I starting to understand how to achieve synchronous behavior using asynchronous messages? I could be wildly off base...


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

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 21 of 33
(1,754 Views)

Note that you can mix sync and Async.  If you have an M-step process to do N times, you can do the M steps synchronously except for the last step.  This will be a lot clearer, especially if M grows larger than 2 as in your simple example.

 

Also, I note that your "root/GUI" actor is doing two different jobs.  Three, actually: the Manager of subactors, the Sequencer, and the GUI.  If you separated these roles into more focused subactors, things might be easier, since your main problem is that sequencing things works well synchronously while your GUI needs to be Asynchronous.

0 Kudos
Message 22 of 33
(1,748 Views)

You have the idea, but let me clean up your language to make the point a little more clear:

 


@WavePacket wrote:

 

With asynchronous reply messaging would it go something like this? Root knows it wants to take N measurements, so its in a mode where it fires an async reply sends a message to A to change the current. When it receives A's async reply A sends a message later with the new current, it uses A's async reply msg to fire off an async reply Root responds to that by sending a message to B. When B's async measurement comes back, it uses that reply to go Root responds to that message by sending a message to A...and so on until the N measuremetn pairs are done. After collecting N pairs, then it changes state to idle. 

 

 


There are no replies (or commands).  There are requests and announcements, and I prefer announcements.  I apologize for being pedantic, but I find being precise about the language helps a lot with my thinking.

 

So does drawing out a sequence diagram with all your anticipated interactions between Root, A, and B.

 

Root knows everything about sequencing, and Root can be as synchronous as you need it to be, internally.  What we're trying to avoid is having that sequence bleed out into A and B.

 

As an aside, if you don't want to use state pattern actors, you could likely build some kind of sequence object into Root that lets you script Root's responses.  You'd likely still wind up with state pattern, but built in way you find more palatable.

0 Kudos
Message 23 of 33
(1,743 Views)

@drjdpowell wrote:

 

Also, I note that your "root/GUI" actor is doing two different jobs.  Three, actually: the Manager of subactors, the Sequencer, and the GUI.  If you separated these roles into more focused subactors, things might be easier, since your main problem is that sequencing things works well synchronously while your GUI needs to be Asynchronous.


Truth.  An actor should have one job.

 

(That way, when it fails, you can yell "you had one job!")

0 Kudos
Message 24 of 33
(1,740 Views)

Hi Dr. Powell,

 

I realize that I've asked a lot of questions, and I've already learned a lot. I'm not sure I yet grasp what your last message was meant to tell me though. Mind if I poke a bit? 

 

@drjdpowell wrote:

Note that you can mix sync and Async.  If you have an M-step process to do N times, you can do the M steps synchronously except for the last step. This will be a lot clearer, especially if M grows larger than 2 as in your simple example.

...


I didn't understand why the last step can be async? Isn't the first step of the M-step process waiting for the last step to finish? (Well, except for the last of the M steps of the very last of the N iterations, I suppose.) If I'm honest, I also don't know why this is especially of aid when M grows large.

 

@drjdpowell wrote:

...

Also, I note that your "root/GUI" actor is doing two different jobs.  Three, actually: the Manager of subactors, the Sequencer, and the GUI.  If you separated these roles into more focused subactors, things might be easier, since your main problem is that sequencing things works well synchronously while your GUI needs to be Asynchronous.


Mind sharing a few words about how the manager of subactors differs from the sequencer? At first site to me as I learn this, sequencing the steps of the subactors seems just to be one job of the manager of the subactors.

 

Thanks again,

 

-Wavepacket



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

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 25 of 33
(1,724 Views)

@justACS wrote:

You have the idea, but let me clean up your language to make the point a little more clear:

 


@WavePacket wrote:

 

With asynchronous reply messaging would it go something like this? Root knows it wants to take N measurements, so its in a mode where it fires an async reply sends a message to A to change the current. When it receives A's async reply A sends a message later with the new current, it uses A's async reply msg to fire off an async reply Root responds to that by sending a message to B. When B's async measurement comes back, it uses that reply to go Root responds to that message by sending a message to A...and so on until the N measuremetn pairs are done. After collecting N pairs, then it changes state to idle. 

 

 


There are no replies (or commands).  There are requests and announcements, and I prefer announcements.  I apologize for being pedantic, but I find being precise about the language helps a lot with my thinking.

 

...


No worries about pedantic, it's helping.

 

I'm wondering for the quoted section if we actually describing the same thing, just using different language. How I was using "async reply" was that in as a part of A receiving the message, it also sends a message to root a message that it's finished. Here, we aren't using the send and wait for response vi. ("Sync reply" was how I was trying to describe a reply message which uses send and wait for response vi.)

 

Perhaps you were describing a different scheme, which is that A is always announcing its current current. Root requests a change in current, and then detects when A's broadcast changes to the new current? Not sure if we are on the same page here yet, though I think we're now in the same chapter at-least ;D.

 


@justACS wrote:

You have the idea, but let me clean up your language to make the point a little more clear:

 


@WavePacket wrote:

 

...

 

 


...

As an aside, if you don't want to use state pattern actors, you could likely build some kind of sequence object into Root that lets you script Root's responses.  You'd likely still wind up with state pattern, but built in way you find more palatable.


I'm not really opposed to using state pattern actors if they are the solution to this issue, I guess I feel like right now that I'm treading water right now just with messaging in AF in general.

 

 

 


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

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 26 of 33
(1,721 Views)

You can do some "sorta-sync" messages too. As one option, you could send actor B a regular message with payload containing a queue and an interface or abstract message. When B takes its measurement, it will send that measurement back on the specified queue. This is sort of like a synchronous message, but actor A now can do whatever it wants until actor B's message comes back. Since A is describing a message that will later be sent to itself, it can create that message with all of the "next step", "next state", etc stuff built in. The difference is that actor A doesn't simply lock up waiting on the new message. You do have to maintain state in A with this paradigm though and can't do a simple loop like you would otherwise.

 

If you've used Time Delayed Send Message this will be familiar. With TDSM, you specify a message to send to a particular actor (it could be itself or it could be another actor). TDSM then launches a background process that either sends that message n times after a delay, or indefinitely until stopped, etc. It's a great metronome tool for repeated tasks and I like it better than a helper loop.

 

TDSM sends the message after a certain time is elapsed. With my method above, the message is sent when a new bit of data is obtained.

 

Of course, I admit you lose some functionality, like timeouts, going this route, but you avoid the synchronous message issues too.

0 Kudos
Message 27 of 33
(1,711 Views)

@WavePacket wrote:

Hi Dr. Powell,

 

I realize that I've asked a lot of questions, and I've already learned a lot. I'm not sure I yet grasp what your last message was meant to tell me though. Mind if I poke a bit? 

 

@drjdpowell wrote:

Note that you can mix sync and Async.  If you have an M-step process to do N times, you can do the M steps synchronously except for the last step. This will be a lot clearer, especially if M grows larger than 2 as in your simple example.

...


I didn't understand why the last step can be async? Isn't the first step of the M-step process waiting for the last step to finish? 



I mean you don't have to do every step by Asynchronous replies.  Synchronous waiting for reply, because it is just like calling a subvi, has a lot of advantages, such as in readability.  By making one step an asynchronous reply, you give the actor a chance to handle other messages.  Doesn't have to be the last step.  

0 Kudos
Message 28 of 33
(1,669 Views)
 
@drjdpowell wrote:

...

Also, I note that your "root/GUI" actor is doing two different jobs.  Three, actually: the Manager of subactors, the Sequencer, and the GUI.  If you separated these roles into more focused subactors, things might be easier, since your main problem is that sequencing things works well synchronously while your GUI needs to be Asynchronous.


Mind sharing a few words about how the manager of subactors differs from the sequencer? At first site to me as I learn this, sequencing the steps of the subactors seems just to be one job of the manager of the subactors.

 



Managers delegate.  You could delegate the sequencing role to a specialized actor, one that can go though complex sequences without needing to fill any other roles the root actor may need to do.

0 Kudos
Message 29 of 33
(1,667 Views)

@BertMcMahan wrote:

You can do some "sorta-sync" messages too. As one option, you could send actor B a regular message with payload containing a queue and an interface or abstract message. When B takes its measurement, it will send that measurement back on the specified queue. This is sort of like a synchronous message, but actor A now can do whatever it wants until actor B's message comes back. Since A is describing a message that will later be sent to itself, it can create that message with all of the "next step", "next state", etc stuff built in. The difference is that actor A doesn't simply lock up waiting on the new message. You do have to maintain state in A with this paradigm though and can't do a simple loop like you would otherwise.

 

If you've used Time Delayed Send Message this will be familiar. With TDSM, you specify a message to send to a particular actor (it could be itself or it could be another actor). TDSM then launches a background process that either sends that message n times after a delay, or indefinitely until stopped, etc. It's a great metronome tool for repeated tasks and I like it better than a helper loop.

 

TDSM sends the message after a certain time is elapsed. With my method above, the message is sent when a new bit of data is obtained.

 

Of course, I admit you lose some functionality, like timeouts, going this route, but you avoid the synchronous message issues too.


What you describe is what I call an "Asynchronous Request-Reply with Continuation" (the message A provides to send to itself represents the "continuation" of the action).  

 

You can do this with a timeout, BTW, and there is a subvi to do that in Messenger Library.  On timeout, one is sent a "Timed out" error message.  

0 Kudos
Message 30 of 33
(1,664 Views)