network.request, fire and forget on app shutdown or suspend

I would like to call an async REST endpoint during system events.  Nothing is being returned from the method, the app just needs to call it when the events are fired.  I’ve tried a few different approaches, including nil listeners but the call never happens and adb provides no insight.  I know this is suggested against, but it still seems that it should be possible as long as I’m not expecting a response?

The code below produces the following output

System event name and type: system   applicationExit

AFTER REQUEST ****

I don’t expect the handler to be called, nor do I need for it to, but I would expect the network request to be made since it’s performing the 2nd print statement.

<lua>


– APP STATUS RESPONSE HANDLER


local function handleAppStatusUpdateResponse( event )

print(“INSIDE OF HANDLER ****”)

end


– SYSTEM EVENTS LISTENER


local function onSystemEvent( event )

print( "System event name and type: " … event.name, event.type )

local url = "http://54.###.###.##/api/UserApplicationStatus/updateStatus?userEmail=" … glo.userEmail … “&isRunning=”

if (nil ~= glo.userEmail ) then

if(event.name == “applicationStart” or event.name == “applicationResume”) then

network.request(url … “true”, “GET”, handleAppStatusUpdateResponse )

end

if(event.name == “applicationExit” or event.name == “applicationSuspend”) then

network.request(url … “false”, “GET”, handleAppStatusUpdateResponse )

end

end

print(“AFTER REQUEST ****”)

end

Runtime:addEventListener( “system”, onSystemEvent )

</lua>

Hi,
As per your code, you are trying to run a code while your app gets closed/suspended.

Remeber,

You can’t run the single line of code, once your Corona app has been suspended or exit. As Corona SDK didn’t support the app to be executed in the background.Every time the Lua execute it requires & assume that the user-interface should & must be there in the foreground of app/device.

Thus even if you try to print a single line, it will not execute it or even you try to send some data from another resource app like a native , Lua will not respond to it as there is no user-interface.

All that you can do is before the app gets closed/exit/suspended.

-** Assif**

Thanks.  So why does print(“AFTER REQUEST…”) execute, but the network request doesn’t?  I did find a flaw in my code, I was checking the value of event.name instead of event.type, so it never evaluated to true.  Once I changed that, I get a print statement from the handler. Which again begs the question, how is the event handler being called if the network request isn’t executed?  I fired up Fiddler and I can see that the call never happens.  What’s even more confusing is that it doesn’t fire on application start or resume.

Update : This actually does work  The code below is functional and seems to be dependable ~20 iterations of stopping and starting the app.  I had another bad equality check. My glo.userEmail is being initialized to “” ,  so ~= nil never evaluated to true.  I also added native.requestExit(), although I don’t know that it’s necessary.

<lua>

local function onSystemEvent( event )

– print( "System event name and type: " … event.name, event.type )

local url = "http://54.###.###.##/api/UserApplicationStatus/updateStatus?userEmail=" … glo.userEmail … “&isRunning=”

if(event.type == “applicationStart”) then

network.request(url … “true”, “GET”, nil )

end

if(event.type == “applicationExit”) then

native.requestExit()

network.request(url … “false”, “GET”, nil )

end

end

Runtime:addEventListener( “system”, onSystemEvent )

</lua>

When the system is suspending your app, it doesn’t shut it down immediately. They have to give apps some time to finish, just not a lot. In the example above, the print(“AFTER REQUEST”) is happening the same frame as the system event, that function will finish and the app will suspend.

Network options even if you’re not waiting on a response can take time, in particular if you’re uploading something over a slow connection. Your upload may not finish before you suspend and if you’re server isn’t outputting any output, it’s still going to output an HTTP status value like 200, 403, etc. Not handling that may be undefined.

Rob

Makes sense. Thanks as always Rob

Hi,
As per your code, you are trying to run a code while your app gets closed/suspended.

Remeber,

You can’t run the single line of code, once your Corona app has been suspended or exit. As Corona SDK didn’t support the app to be executed in the background.Every time the Lua execute it requires & assume that the user-interface should & must be there in the foreground of app/device.

Thus even if you try to print a single line, it will not execute it or even you try to send some data from another resource app like a native , Lua will not respond to it as there is no user-interface.

All that you can do is before the app gets closed/exit/suspended.

-** Assif**

Thanks.  So why does print(“AFTER REQUEST…”) execute, but the network request doesn’t?  I did find a flaw in my code, I was checking the value of event.name instead of event.type, so it never evaluated to true.  Once I changed that, I get a print statement from the handler. Which again begs the question, how is the event handler being called if the network request isn’t executed?  I fired up Fiddler and I can see that the call never happens.  What’s even more confusing is that it doesn’t fire on application start or resume.

Update : This actually does work  The code below is functional and seems to be dependable ~20 iterations of stopping and starting the app.  I had another bad equality check. My glo.userEmail is being initialized to “” ,  so ~= nil never evaluated to true.  I also added native.requestExit(), although I don’t know that it’s necessary.

<lua>

local function onSystemEvent( event )

– print( "System event name and type: " … event.name, event.type )

local url = "http://54.###.###.##/api/UserApplicationStatus/updateStatus?userEmail=" … glo.userEmail … “&isRunning=”

if(event.type == “applicationStart”) then

network.request(url … “true”, “GET”, nil )

end

if(event.type == “applicationExit”) then

native.requestExit()

network.request(url … “false”, “GET”, nil )

end

end

Runtime:addEventListener( “system”, onSystemEvent )

</lua>

When the system is suspending your app, it doesn’t shut it down immediately. They have to give apps some time to finish, just not a lot. In the example above, the print(“AFTER REQUEST”) is happening the same frame as the system event, that function will finish and the app will suspend.

Network options even if you’re not waiting on a response can take time, in particular if you’re uploading something over a slow connection. Your upload may not finish before you suspend and if you’re server isn’t outputting any output, it’s still going to output an HTTP status value like 200, 403, etc. Not handling that may be undefined.

Rob

Makes sense. Thanks as always Rob