One of my apps is hosted on Heroku and has one rou...
# http4k
a
One of my apps is hosted on Heroku and has one route that kicks off a long-running process. Heroku requires at least some data to be returned to the client within 30 seconds or it returns a timeout error. Is there a recommended pattern for periodically sending a small response back to the client (i.e. "waiting...") in order to avoid the connection timeout? I think this might be a case for using "server-sent events" but not sure how to integrate into a running route. thank you
t
Sometimes it can be done by streaming data. See https://github.com/http4k/http4k/issues/133 Not sure if it's helpful for your case.
j
Perhaps you could do with a different pattern? Http not really very suitable for waiting for a long running process. Try returning an ID that the client can poll for status later. This means the call will return immediately. Or perhaps the client doesn't care about the status of the job, only that it was kicked off successfully...?
a
@Tushar thanks for the link, I did a bunch of searching before posting but didn't see that one, thanks
@James Richardson This is an internal process run only once or twice per day via a cron job. It usually takes about 60-90 seconds. The cron service thinks every call fails because it gets a timeout error. Heroku actually continues to run the process to completion, my goal is to be able to return the results to the initial cron call.
j
Sure. But why does your client, a bash/python/whatever script invoked by cron, only have to make 1.single http call. It could make more, like.in the pattern above....
a
Right but then my app needs to maintain state. and since I'm on Heroku, I can't do something simple like an H2 or SQlite db or anything file-based, because they won't be available when Heroku switches dynos. So you're adding a lot of complexity and points of failure, vs. just extending the timeout to include the result in the initial http call. (oh... and the client needs to maintain state too)
s
it’s very simple, one call to initiate the job and get the jobid (which can be stored in memory), and then in a loop every X seconds check if job is done by that id and get results