4 ms·
So what's the alternative to Timeout? Or does it mean that if I think I Timeout is the solution then my approach is wrong?
by Alifatisk 2y ago
So what's the alternative to Timeout? Or does it mean that if I think I Timeout is the solution then my approach is wrong?
- masklinn 2y agoTimers / cooperative timeouts. AFAIK they’re the only way to ensure that effectful code will never end with a corrupted state.
- mijoharas 2y agoThe other answer is correct I believe, but I think the most common recommendation I've seen for rails boils down to "Use Timeout, and then kill and restart the process" (ref: [0], [1]), which obviously doesn't feel great for performance when a timeout in one thread can cause all other threads to need to be killed. [0] https://www.schneems.com/2017/02/21/the-oldest-bug-in-ruby-why-racktimeout-might-hose-your-server/ https://www.schneems.com/2017/02/21/the-oldest-bug-in-ruby-w... [1] https://github.com/zombocom/rack-timeout https://github.com/zombocom/rack-timeout (c.f. term_on_timeout)
- baggy_trough 2y agoFor web workers, use a single thread per process model, then kill the worker if there's a timeout.
- Asmod4n 2y ago(Almost) Every OS kernel has an API to handle timeouts. poll, select, kqueue, epoll etc. just use that.
- simonw 2y agoThe word "just" is doing a lot of work there!
- immibis 2y agoYou can replace every blocking call with a timed one. In Python you can just call settimeout on a socket. In C you might want to write your own recv_timeout function, but it's not that difficult.
- simonw 2y agoI have no idea how I would use settimeout with a socket to solve any of my problems that involve causing a piece of code to terminate early if it takes longer than a specific amount of time.
- immibis 2y agoWhat is the code doing? Most of the time it's waiting for a socket. If it's not doing that, do the equivalent for whatever it is waiting for. If it's CPU-bound, add interrupt checks.
- simonw 2y agoPlaces I've wanted to implement this in the past include: - Run a subprocess such as "rg" and terminate early if necessary - Run a SQLite SQL a query that errors if it takes more than a second - Same but for other DBs - MySQL, PostgreSQL, Elastic, Mongo etc - Execute a fragment of JavaScript in something like QuickJS with a time limit - Brute force some kind of algorithm with a time limit - using a library I did not write myself
- Asmod4n 2y agoIf you are using a piece of software which has a part that can take a long time to execute and doesn't allow it to set timeouts for long running operations then i would send a PR to solve that issue. When said software is closed source and doesn't have that feature then that company sells a problem and not a solution.
- ape4 2y agoEven Windows has WaitForMultipleObjects() https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitformultipleobjects https://learn.microsoft.com/en-us/windows/win32/api/synchapi...
- maxlybbert 2y agoIn .Net, use CancellationToken ( https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken?view=net-8.0 https://learn.microsoft.com/en-us/dotnet/api/system.threadin... , https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource?view=net-8.0 https://learn.microsoft.com/en-us/dotnet/api/system.threadin... ). The two big benefits are (1) if you pass the cancellation token to the task that might be canceled, hopefully it will be obvious that the task might be canceled; and (2) the task that might be canceled has a way to find out it’s being canceled and, if that ever happens, it can clean up.
- Alifatisk 2y agoAnd in Rubys case?
- vidarh 2y agoDepends heavily how trusted/untrusted the process is. If you trust the process won't actively try to circumvent you, just fork and call alarm() as the first thing is often enough. You can cancel it, so it's not a precaution against malice. If you can't trust the process, fork, wait in the parent, and kill the child if it hasn't terminated. I don't think alarm() is exposed in Ruby, unless it's been added recently, but it's easy enough to add. However since fork + kill is more reliable anyway, it's often a better choice.
- dragonwriter 2y ago> Depends heavily how trusted/untrusted the process is. Timeout is for threads not processes, and not everything that would be done on a thread can be conveniently rewritten to be a separate process.
- vidarh 2y agoIf you want reliable timeouts, that is your tradeoff. There are too many awful failure scenarios to resolve with threads.
- regularfry 2y agoYou want something patterned like select. Structure the application around threads blocking on queues and avoiding exceptions entirely makes things far more sane.
- nijave 2y agoYou can manually check an "is timed out" object and ensure that you're configuring timeouts that are smaller on any blocking code (basically I/O) Say you're looping over 1m items, maybe every 1k you check to see if you're out of time and return or raise