Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

? Bug in synchro message ?

Solved!
Go to solution

I have an actor that performs an addition

I send it a synchro wait msg.

Inside the method call I put a wait(10000) so that I get a timeout (I want to simulate a long synchro operation, and see what happens).

 

It turns out that the addition actor crash with error=1 (saw from handle last ack in the caller actor).

This crash happens after the timeout, exactly when the 10sec ticks.

 

Why?

0 Kudos
Message 1 of 15
(4,615 Views)

It seems the error is in the enqueue in the do.vi of reply message.

When I have a timeout, the error out is still (False, 0, "").

So I need to investigate why reply queue refnum is invalid

 

 

 

Clipboard01.jpgClipboard02.jpg

0 Kudos
Message 2 of 15
(4,590 Views)

Found the cause.

see diagram.

in the public vi "Send msg and wait for response" a queue is created, then msg is enqueued (so it goes into another loop...imagine it takes 10 sec to complete, stuck there BUT program continues here), then you have a dequeue with wait.... now if you set a timeout less than 10sec, it will pop here, then you see the close queue ref.

In the Do.vi, there is an enqueue using the just closed queue, so that's easy invalid ref as soon as the vi of the actor finishes its long operation.

 

This is something to deal with, it's built it into the framework.

 

Clipboard03.jpg

0 Kudos
Message 3 of 15
(4,589 Views)

@Ironman_ wrote:
This is something to deal with, it's built it into the framework.

 


And it is correct behavior. The caller sent a message and said it wanted a reply. The nested actor did the work and tried to reply, but the caller timed out waiting. What should the nested actor do? When you create a new Reply Msg, your child class needs to put code in its Do.vi to decide what the right response is. In most cases, it will be to throw away the result and clear the error, but possibly it can do something else. The framework cannot make that decision.

 

Note that if you're using timeouts on Reply Msg, you may need to package additional timeout information into the message itself so that the nested actor knows to stop doing the work after a certain amount of time. Otherwise, when the caller times out waiting for the result, the nested actor keeps computing the result, no matter how long it takes.

 

Add to the list of gotchas that come up with Reply Msg. 🙂

Message 4 of 15
(4,582 Views)

It occurs to me that I could augment the framework to return a more explicit error at that point to explain this stuff. I'll give it some thought.

0 Kudos
Message 5 of 15
(4,581 Views)

@AristosQueue (NI) wrote:
In most cases, it will be to throw away the result and clear the error, but possibly it can do something else. The framework cannot make that decision.

 


In "Messenger Library" I did make the decision.  Replying to a Request never throws an error to the replier.  Making sure the reply gets where it needs to go is the responsibility of the Requester.

 


@AristosQueue (NI) wrote:
Note that if you're using timeouts on Reply Msg, you may need to package additional timeout information into the message itself so that the nested actor knows to stop doing the work after a certain amount of time. Otherwise, when the caller times out waiting for the result, the nested actor keeps computing the result, no matter how long it takes.

 Use the Queue reference.  If it is no-longer valid then you can stop doing the work.  

 

Message 6 of 15
(4,579 Views)
Solution
Accepted by topic author Ironman_

I think this text would be more helpful for future users. Yes?

Untitled.png

 

Message 7 of 15
(4,577 Views)

AristosQueue:

I think this text would be more helpful for future users. Yes?

Yes, much better than "error 1".

 


AristosQueue:

Note that if you're using timeouts on Reply Msg, you may need to package additional timeout information into the message itself so that the nested actor knows to stop doing the work after a certain amount of time. Otherwise, when the caller times out waiting for the result, the nested actor keeps computing the result, no matter how long it takes.

I was using a simple Wait(ms) and I noticed also this issue, for example if the actor remains "stuck" into a method, it can't process any following message, or if the actor talks to a real device, it should always ends up in a clean state, or the actor could become useless (I don't know a strategy to "force shutdown" a nested stuck actor)

 


Drjpowell
Use the Queue reference. If it is no-longer valid then you can stop doing the work.

But I need to create a property accessors in Reply Msg class (so modify the AF), in order to access the queue from any derived class.

0 Kudos
Message 8 of 15
(4,563 Views)

Ironman_ wrote: 

Drjpowell
Use the Queue reference. If it is no-longer valid then you can stop doing the work.

But I need to create a property accessors in Reply Msg class (so modify the AF), in order to access the queue from any derived class.


"Reply Msg" isn't part of the core AF; just copy and modify or make a different one from scratch.  Add a "Reply Address Still Valid" (or "Caller waiting", or "Reply Cancelled") method that tests to see if the Caller is still waiting.

 

 

You should also create a "Wait (with cancel)" method that uses the Queue to do the timing.  So, wait for a message (that will never come) with timeout; then the Caller destroying the Queue will cause the waiting to terminate early with an error.  Use this in place of any Waits you need.

Message 9 of 15
(4,556 Views)

I've said this before, but it seems a mistake to have a "Reply Message" that is synchronous in the AF without a similarly easy-to-use Async "Reply Message" available somehow.  People will be guided towards using blocking wait on reply in cases where the information should be coming back asynchronously.  

0 Kudos
Message 10 of 15
(4,553 Views)