Your Digital Media Has Never Looked So Good

 
tim_beynart
Topic Author
Posts: 98
Joined: Wed Jul 15, 2015 8:30 am

Best way to fire several http requests?

Wed Jul 12, 2017 2:50 pm

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:
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
 
User avatar
destruk
Posts: 2403
Joined: Sat Dec 18, 2010 4:58 pm

Re: Best way to fire several http requests?

Wed Jul 12, 2017 9:19 pm

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
Topic Author
Posts: 98
Joined: Wed Jul 15, 2015 8:30 am

Re: Best way to fire several http requests?

Thu Jul 13, 2017 7:17 am

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.
 
tim_beynart
Topic Author
Posts: 98
Joined: Wed Jul 15, 2015 8:30 am

Re: Best way to fire several http requests?

Thu Jul 13, 2017 7:20 am

I guess another approach is to write a queue and fire off the requests in series.
 
User avatar
destruk
Posts: 2403
Joined: Sat Dec 18, 2010 4:58 pm

Re: Best way to fire several http requests?

Thu Jul 13, 2017 8:29 am

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.
 
User avatar
RokuNB
Posts: 183
Joined: Fri Mar 31, 2017 2:22 pm

Re: Best way to fire several http requests?

Thu Jul 13, 2017 8:59 pm

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
Topic Author
Posts: 98
Joined: Wed Jul 15, 2015 8:30 am

Re: Best way to fire several http requests?

Fri Jul 14, 2017 7:24 am

We aren't using RAF.
 
tim_beynart
Topic Author
Posts: 98
Joined: Wed Jul 15, 2015 8:30 am

Re: Best way to fire several http requests?

Fri Jul 14, 2017 7:49 am

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?
 
User avatar
RokuNB
Posts: 183
Joined: Fri Mar 31, 2017 2:22 pm

Re: Best way to fire several http requests?

Fri Jul 14, 2017 10:21 am

tim_beynart wrote:
We aren't using RAF.

That's rather unfortunate then  8)

Who is online

Users browsing this forum: No registered users and 8 guests