I’m working on a simple “web” server (to be run only locally) which allows other programs running locally to request solutions to optimization problems.
Firstly, and most importantly, solving these optimization problems can take a prohibitively long time. If an optimization problem runs for too long, it’s best to just give up on it.
Question 1: What’s the idiomatic way to start a job (be it via
@spawn or something else) and wait until either that job is completed or a certain amount of time has elapsed, aborting the job if it has not completed in time?
I see two ways, both of which feel clunky and therefore likely wrong:
Have the master process start the job, e.g. with
@spawn, and then sleep in short chunks. In each wake between sleeps, check of the job is completed and if so exit the sleep loop; also exit the loop if the total sleep time exceeds the limit.
Have the master process wait on a
Condition. The worker process triggers the condition when work is complete, and an additional process sleeps the allotted amount of time before triggering the condition.
Either way, a long-running job is aborted with
I have a simple version using
HttpServer running with approximately the following code:
using HttpServer function process_request(req::Request, res::Response) x = extract_data_from_request y = solve_optimization_problem(x) # takes a few seconds return Response(200, answer_to_json(y)) end server = Server(process_request) run(server, 8000)
This works well as long as requests aren’t coming in too fast, at which point things really slow down. I’ve tried code like the following, which seems to help.
@everywhere function solve_optimization_problem(x) ... function process_request(req::Request, res::Response) x = extract_data_from_request y = @fetch solve_optimization_problem(x)) # takes a few seconds return Response(200, answer_to_json(y)) end server = Server(process_request) run(server, 8000)
Question 2: is this the ‘right’ way?
Intuitively, it seems like we want the master process to be able to say to a worker “you answer this request,” which would free the master up for other requests; the master never has to revisit the current request. Something like
@everywhere function optimize_and_package(x) y = solve_optimization_problem(x) return Response(200, answer_to_json(y)) end function process_request(req::Request, res::Response) x = extract_data_from_request @return_when_complete @spawn optimize_and_package(x) end
Question 3: Is there a way to do this / is it even desirable?
Preemptive thanks for the help!