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: 
SoN9ne
Level 7

[SOLVED] AsyncPostFromString is blocking

I am using
AsyncPostFromString
to do a non-blocking request.

This request is a logger service for analytics and we collect basic information to help troubleshoot customers with issues.

The service works as expected but there is an issue with
AsyncPostFromString
as it is suppose to be non-blocking but that does not seem to be the case. I have the service wait for 5 seconds to verify it's non-blocking but it always waits until the logger request is complete.

My logs show:
Channel Initialized - START Logger
Waiting for response...
Sucessful Response
END Logger
InitTheme Start - InitTheme End - MainContentList Start - MainContentList End


I am expecting:
Channel Initialized - START Logger
Waiting for response...
InitTheme Start - InitTheme End - MainContentList Start - MainContentList End
Sucessful Response
END Logger


It is obvious that it is waiting until the request is complete. The issue here seems to be the while loop. When I remove it, I get what I expect but then I have no way to gracefully handle a rogue request and that could cause many issues.

Hopefully I am missing something simple.

I am using
request.setport(port)
and I tested also with
request.setMessagePort(port)
but no change.

Thanks for any help you can provide.
Jeremy

The method I am using is below:
Sub Logger(event, value="")
print "START Logger"

' Get Device Info
di = CreateObject("roDeviceInfo")
' Make sure there is an active connection
if (di.GetLinkStatus()) then

' Define timeout
timeout = 2000

' Define URL
url="https://my.super.secret.url"

' Get Device Info
di = CreateObject("roDeviceInfo")

' Create transfer object
request=createobject("roURLTransfer")
request.SetCertificatesFile("common:/certs/ca-bundle.crt")
request.InitClientCertificates()
request.AddHeader("Content-Type", "application/json")
request.seturl(url)

' Event monitoring
port=createobject("roMessagePort")
request.setport(port)

' Timer for timeout
timer=createobject("roTimeSpan")
timer.mark()

' Build data object
data = {
"entityName": "Roku App",
"entityEvent": event,
' Device info (https://sdkdocs.roku.com/display/sdkdoc/ifDeviceInfo)
"entityID": di.GetDeviceUniqueId(),
"entityMeta": {
"modelDisplayName": di.GetModelDisplayName(),
"model": di.GetModel(),
"softwareVersion": di.GetVersion(),
"displayType": di.GetDisplayType(),
"displayMode": di.GetDisplayMode(),
"displayAspectRatio": di.GetDisplayAspectRatio(),
"timezone": di.GetTimeZone(),
"ip": di.GetIPAddrs(),
"locale": di.GetCurrentLocale(),
"countryCode": di.GetCountryCode(),
"timeSinceLastKeyPress": di.TimeSinceLastKeypress(),
"videoPlaybackResolution": di.GetVideoMode(),
"isHDMIConnected": di.IsHDMIConnected(),
"audioOutputChannel": di.GetAudioOutputChannel(),
"activeNetwork": di.GetLinkStatus(),
"connectionType": di.GetConnectionType()
}
}

' Only add value if provided
if (value <> "") then
data.entityValue = value
end if

' Format to JSON
jsonData = FormatJson(data)
print "jsonData: " ; jsonData

' Send Requests
request.AsyncPostFromString(jsonData)

print "Waiting for response..."

' Gracefully handle the request
while true
msg=wait(100,port) '100 millisecond pause
if type(msg)="roUrlEvent" then

if msg.getresponsecode()=200 then
print "Sucessful Response"
exit while
else
print "Response Code" ; msg.getresponsecode()
request.asynccancel()
end if

end if
' Set timeout
if timer.totalmilliseconds() > timeout then
print "timeout exceeded"
exit while
end if
end while

else
print "No active Internet connection. Logger is being skipped."
end if

print "END Logger"
End Sub
0 Kudos
4 Replies
RokuMarkn
Level 7

Re: AsyncPostFromString is blocking until it gets a response

What it means to say that AsyncPostFromString is asynchronous is that it returns immediately, before the request is complete. Your code verifies that this happens, since the "waiting for response" message appears and shows that AsyncPostFromString has returned. If you want to do other activity while waiting for the post to complete, you should call request.SetMessagePort with the same port you use in your main loop, rather than creating a new port. Then add the roUrlEvent handling code to your main loop.

--Mark
0 Kudos
SoN9ne
Level 7

Re: AsyncPostFromString is blocking until it gets a response

Thanks, I knew it had to be something simple.

One last question... I can no longer do a timeout since this is in the main loop. There are multiple roUrlEvent's so there isn't a way (that I noticed) to identify which is which. Is this something I need to handle in the code or does roUrlEvent handle this internally? Personally, I'd like to log the event for later use but that's not really an issue.

Thanks again
0 Kudos
TheEndless
Level 7

Re: AsyncPostFromString is blocking until it gets a response

"SoN9ne" wrote:
One last question... I can no longer do a timeout since this is in the main loop. There are multiple roUrlEvent's so there isn't a way (that I noticed) to identify which is which. Is this something I need to handle in the code or does roUrlEvent handle this internally? Personally, I'd like to log the event for later use but that's not really an issue.

roUrlTransfer has a GetIdentity() method that returns a unique identifier for that request. roUrlEvent has a companion GetSourceIdentity() method that returns that same ID, so you can identify which request the event is for.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
SoN9ne
Level 7

Re: AsyncPostFromString is blocking until it gets a response

Awesome, thank for your help
0 Kudos