There is currently no general way to handle multiple system threads with different timeouts pre-emptively, to the best of my knowledge.
Be aware, also, that there is also no general way to correctly clean-up resources and take care of integrity of state when asynchronous exceptions are used, without a small risk of a race condition. I mention this because you say that your use-case is similar to client handles on a server. The way I understand this situation is that asynchronous exceptions are a feature used mainly in the historical domain of OCaml of language and logic applications, where the worst that can happen is to have to restart an interactive session or to leave behind corrupted temporary files. They did not evolve when OCaml started to be applied to more diverse application domains, and it is common in the systems programming side to assume that the program does not use them.
Is there a recommended way of writing a server application that supports concurrency + timeout? Based on my understanding right now I have the following options:
Use Lwt for socket communication, but that seems to require me changing my potentially blocking functions (the ones whose implementations involve reading from socket) to return a x Lwt.t instead of x.
Use the Async library. I never really looked into it but it seems to induce similar issues as (1).
I guess I should spell out the scenario Iām facing:
I have a server that runs a tournament with potentially remote or local AI players.
Each tournament consists of round(s) of games, and in each round, the players will be divided up into groups and handed to referees, which manages individual games.
The player is a virtual class that roughly looks like this:
class virtual t :
method virtual request_some_response : ... -> Response.t
Now from the refereeās point of view, it doesnāt know whether the player it requests response from is a local AI player or remote player, so it needs a timeout operation to make sure the game wonāt get stuck.
Iām also considering using system threads (or some other mechanisms) to run games concurrently, so the timeout function needs to accommodate that. Currently Iām using signal to implement timeout, but apparently it wonāt satisfy this requirement.
Iām also curious how a serious OCaml server would be implemented in general, as Iām pretty new both to Lwt/Async and server programming.
forking can be ācheap enoughā (itās as fast as, faster, or slower than starting a new hardware thread depending on a ton of factors), and yes, you might have to work out how to communicate results and/or control signals between parent and child processes.
On the other hand, itās one of the few reliable ways to achieve preemptive termination without forcing your units of work into e.g. an internal/embedded interpreted environment, which doesnāt sound like what youāre after.