Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
dcrandall
Level 7

Is there a way to not 'wait' for AsyncPostFromString()?

I'll state the problem at a really high level, first:

I would like to issue a statement to a server, and I don't care if it takes 15ms or 15 minutes, I would like to hear whatever it has to say exactly or as close to exactly when it comes back.

So, the solution and where I have a problem:

if (request.AsyncPostFromString(dataRequestString))
msg = wait(timeoutRequest, port)


I'm waiting. ...on an asynchronous request. :?

Solutions and thoughts thus far:

viewtopic.php?f=34&t=49363&start=0&hilit=AsyncPostFromString

I could use the same port where I'm incidentally waiting on a message -- like for a string, for example

while true
msg = wait(0, screen.getmessageport())
if (msg.isscreenclosed())


The only problem is, say I've moved-on from that by using the screen-stack model:
http://sdkdocs.roku.com/display/sdkdoc/ ... th+Screens

In this case, I issue the async request in ShowPosterScreen (using ShowPosterScreen's message port), but I move onto ShowSpringboardScreen...and somewhat halting the 'while' loop in ShowPosterScreen until completion of ShowSpringboardScreen.

While that while loop (ShowPosterScreen) is stopped and waiting on ShowSpringboardScreen to finish, I won't get any acknowledgement from that async request, even if it has finished.


One could have both ShowPosterScreen and ShowSpringboardScreen waiting on the same port, but it seems like one would have to worry about consumption of messages meant for the other (although, if the one is waiting for completion anyway...)


TL;DR - Is there a "how the pros do it" for AsyncPostFromString? So far everything I've found oversimplifies the use, IMHO.
0 Kudos
4 Replies
belltown
Level 7

Re: Is there a way to not 'wait' for AsyncPostFromString()?

I don't see how you could do it without using the same port for all components.

I have one project that uses overlapping asynchronous requests to various servers, as well as multiple custom timer objects, doing stuff "behind the scenes" while standard poster/springboard components are in use. I use a single port for the whole project. I have one main loop that handles all completions on that port as well as checking which timers have expired. The loop then calls the appropriate function to handle each event/timer, etc. For my UI components, I just use the event type and current UI state to call the appropriate handler. For url transfers, roUrlTransfer.GetIdentity() and roUrlEvent.GetSourceIdentity() can be used. That particular project uses a finite state machine architecture in its main loop.

I've never had a problem using a single message port and losing requests or consuming messages meant for other components. The Roku seems to handle it well, and in at least one case requires a single port (roSystemLog). In the screen-stack model you shouldn't be getting requests for other UI components, just for the component you have on display, as long as you keep that component at the top of the stack until the close event is received.

I have another project using the screen-stack model you describe. In that project I still use the same port for all components. I create it in main () and pass it down as a parameter to each UI component handler. In that project I only have one potential outstanding async request, so in each of the UI handlers where I could be processing an async url completion, or a system log event, or a UI event, I do something like (oversimplified):


while true
msg = wait (waitTime, port)
if type (msg) = "Invalid"
handleTimeoutEvent ...
else if type (msg) = "roSystemLogEvent"
handleSystemLogEvent ...
else if type (msg) = "roAudioPlayerEvent"
handleAudioPlayerEvent ...
else if type (msg) = "roUrlEvent"
handleUrlEvent ...
else if type (msg) = "roSpringboardScreenEvent"
handleSpringBoardSreenEvent ...
else
handleUnexpectedEventType ...
endif
end while
https://github.com/belltown/
0 Kudos
EnTerr
Level 8

Re: Is there a way to not 'wait' for AsyncPostFromString()?

"belltown" wrote:
I don't see how you could do it without using the same port for all components.
...
I've never had a problem using a single message port and losing requests or consuming messages meant for other components. The Roku seems to handle it well, and in at least one case requires a single port (roSystemLog).

One can poll multiple ports like so:

while True:
canNap = True
msg = port1.getMessage()
if msg <> invalid:
canNap = False
... work on it
end if
msg = port2.getMessage()
if msg <> invalid:
canNap = False
... work it
end if
if canNap then sleep(50) 'give it a break
end while
I don't think roSystemLog requires a single port per se - rather the manual describes a way to ensure that said port will be regularly drained (i wonder if it's a quick YAWRR otherwise?).

I have asked the single vs multiple ports question before - viewtopic.php?f=34&t=65734&#p434039 - and TheEndless made good point that if all messages are merged into a single port, you lose the ability to prioritize them, i.e. process some ports with higher priority. Or at least make sure that all components will regularly be attended (which is what my example above does) even if one of them churns excessive amount of events.
0 Kudos
belltown
Level 7

Re: Is there a way to not 'wait' for AsyncPostFromString()?

Good points, EnTerr. I never considered polling multiple ports because in my cases the events didn't need to be prioritized and there was no excessive churning of events. I generally try to pick the simplest solution that meets my needs. I can see in principle where polled multiple ports might be appropriate. I just haven't felt the need for them yet.
https://github.com/belltown/
0 Kudos
EnTerr
Level 8

Re: Is there a way to not 'wait' for AsyncPostFromString()?

Right. I haven't done it either - mentally I have conceptualized a "framework" in which components register into a "grand central" that will spin a master loop and throw them events as needed. But... <yawn> am taking lazy implementation approach because... what if YAGNI?
0 Kudos