tim_beynart
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-12-2017
02:50 PM
Best way to fire several http requests?
I have to fire off ad beacons from an SG app at specific points in a stream. In practice this means I can have over a dozen HTTP calls at once. I do not care about the responses.
Right now I have a task to handle the HTTP requests, and I create a new task for each request.
However I ran into a problem that plagued me in SDK1, where the task is garbage collected before the HTTP request is made.
To get around this I append the tasks to a list, then every now and then trim the list of completed requests. This feels like a kludge. Is there a best practice for spinning up a task and keeping it around until it completes, and only then allowing it to be garbage collected?
Here's the task code:
Here's my first stab at the code that uses it:
Right now I have a task to handle the HTTP requests, and I create a new task for each request.
However I ran into a problem that plagued me in SDK1, where the task is garbage collected before the HTTP request is made.
To get around this I append the tasks to a list, then every now and then trim the list of completed requests. This feels like a kludge. Is there a best practice for spinning up a task and keeping it around until it completes, and only then allowing it to be garbage collected?
Here's the task code:
Sub dorequest()
url = m.top.url
? "[HTTP Request] ", url
request = createobject("roUrlTransfer")
port = createobject("roMessagePort")
msgfailurereason="n/a"
msgcode="n/a"
request.setmessageport(port)
request.setcertificatesfile("common:/certs/ca-bundle.crt")
request.initclientcertificates()
request.enablehostverification(false)
request.enablepeerverification(false)
request.retainbodyonerror(true)
request.seturl(url)
if (request.asyncgettostring())
while (true)
msg = wait(5000, port)
if (type(msg) = "roUrlEvent")
if (msg.getresponsecode() > 0 OR msg.getresponsecode() < 400)
? "[HTTP Request] SUCCESS. ",msg.getresponsecode()
else
msgfailureresponse = msg.getstring()
if msg.getresponsecode() <> invalid
msgcode = msg.getresponsecode()
end if
if msg.getfailurereason() <> invalid
msgfailurereason = msg.getfailurereason()
end if
? "[HTTP Request] REQUEST FAILED: ",url
? "[HTTP Request] CODE: ",msgcode, "REASON: ",msgfailurereason
end if
request.asynccancel()
exit while
else if (msg = invalid)
? "[HTTP Request] BEACON REQUEST FAILED: ",url
request.asynccancel()
end if
end while
end if
m.top.complete=true
End Sub
Here's my first stab at the code that uses it:
Sub fireBeacon(url as String)
? "Fire Beacon. ", url
task = CreateObject("roSGNode", "http_request")
task.url = url
task.control = "RUN"
'keep task from getting garbage collected
m.http_tasks.AddReplace(url,task)
cleanup_requests()
End Sub
sub cleanup_requests()
? "m.http_tasks 1: ",m.http_tasks.count()
for each t in m.http_tasks
? m.http_tasks[t].state
if m.http_tasks[t].complete
m.http_tasks.delete(t)
end if
end for
? "m.http_tasks 2: ",m.http_tasks.count()
end sub
8 REPLIES 8
destruk
Streaming Star
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-12-2017
09:19 PM
Re: Best way to fire several http requests?
If you have 12 calls, you might consider having 12 discrete individual task nodes. That way you have enough time for each to complete before needing to launch another volley.
tim_beynart
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-13-2017
07:17 AM
Re: Best way to fire several http requests?
I thought I was creating a discrete task node for each call using CreateObject("roSGNode", "http_request") ?
The number of calls can vary, there can be anywhere from 2 to 30 for an event.
EDIT:
The issue is that "task" is a local variable for that function, so once the function returns it gets nuked. I was hoping task nodes, once spawned, stayed alive until they finished.
The number of calls can vary, there can be anywhere from 2 to 30 for an event.
EDIT:
The issue is that "task" is a local variable for that function, so once the function returns it gets nuked. I was hoping task nodes, once spawned, stayed alive until they finished.
tim_beynart
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-13-2017
07:20 AM
Re: Best way to fire several http requests?
I guess another approach is to write a queue and fire off the requests in series.
destruk
Streaming Star
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-13-2017
08:29 AM
Re: Best way to fire several http requests?
That is what they say (a task node spawns a new process). I have noticed with event observers if you have an always notify on change callback set, as soon as it changes at all the callback is executed. This means when you get a string from a server you need to wait for the entire string to be received before setting the field to it. But then perhaps I was just doing it wrong - when I changed to storing it as a variable first and then setting the field to the variable value it worked better for me.
NB_
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-13-2017
08:59 PM
Re: Best way to fire several http requests?
"tim_beynart" wrote:
I guess another approach is to write a queue and fire off the requests in series.
The real question is why are you re-inventing the wheel?
RAF already has a facility for firing beacons automatically - or you can do it manually by calling raf.fireTrackingEvents()
That code is solid and vetted in production, can handle hundreds of beacons simultaneously in an app (and does handle many millions per day). It's a non-blocking call, takes care handling async requests behind the scenes and avoids the "nuclear option". Do you have special needs it can't cover?
tim_beynart
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-14-2017
07:24 AM
Re: Best way to fire several http requests?
We aren't using RAF.
tim_beynart
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-14-2017
07:49 AM
Re: Best way to fire several http requests?
I guess I should have made my real question more clear:
Are tasks kept in memory until they complete?
My experience tells me "no", since my generated task stops logging as soon as the function that created it returns. So the next question is, what is a clean technique for running tasks in the background without babysitting the garbage collector?
Are tasks kept in memory until they complete?
My experience tells me "no", since my generated task stops logging as soon as the function that created it returns. So the next question is, what is a clean technique for running tasks in the background without babysitting the garbage collector?
NB_
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-14-2017
10:21 AM
Re: Best way to fire several http requests?
"tim_beynart" wrote:
We aren't using RAF.
That's rather unfortunate then 8-)