3 ms·
An exception-safe C++ program can do the same through a std::bad_alloc exception. If the out-of-memory was caused by something simple like accidentally loading
by unilynx 7y ago
An exception-safe C++ program can do the same through a std::bad_alloc exception.
If the out-of-memory was caused by something simple like accidentally loading 2G of data because of some odd data in an network request or a user selected file, and it rolls back to the start of the UI action or the incoming network request, the application may still work fine.
(I usually connected other out-of-resource conditions such as pipe/socket/open failures to std::bad_alloc too. They're pretty comparable in effect and give a bigger chance of actually exercising those exception paths)
- lmm 7y ago> If the out-of-memory was caused by something simple like accidentally loading 2G of data because of some odd data in an network request or a user selected file, and it rolls back to the start of the UI action or the incoming network request, the application may still work fine. If you have a system that handles independent requests, it might be more robust to model each request as its own process, and then simply allow those processes to crash if they find themselves in an unexpected condition (and handle process crashes).
- unilynx 7y agoIt's certainly more robust, but a lot of overhead for what should be a very uncommon situation. In eg an application server, requests themselves may be independent, but still share a lot of cached data - and as long as locking overhead doesn't overwhelm you, a single process is still the fastest way to share data between (worker) threads.
- lmm 7y agoIf that data is read-only then a fork()ed child process will share it just as efficiently as a thread would. If your threads need to share interleaved modifications to some common state then that approach isn't viable. But in that case it will be very hard to "roll back"/"skip over" a failed request, as it's difficult to be confident that you haven't corrupted that shared data in a way that will cause the same problem for future requests.
- unilynx 7y agofork only works if the central cache never updates. Eg a cache of compiled bytecode for scripts gets filled as those scripts are requested. A cache of database results fills as those results are requested. I'm not sure why skipping over failed requests is hard. VMs associated with the request are aborted, the client gets a 500/503 and can retry later. Incomplete data doesn't get added to the caches at all, so no corruption of shared data.
- lmm 7y agoIt kind of goes both ways. If the data sharing pattern is simple then it's still quite simple to handle that at an inter-process level (e.g. perhaps you have to do cache updates via slower IPC, but if the cache updates only happen after the request has already been handled then they're not on the critical path. Or you might have the parent process handle the cache updates itself). If the data sharing pattern is complex and interleaved then it's hard to achieve with anything other than threads - but that's exactly the case that also makes it hard to avoid corrupting shared data.
- vbezhenar 7y agoYou can use pool of processes, so you don't have to launch new process for every request. Also you can and should use shared memory for shared data. In the end it's almost like threads, but with more safety.
- cesarb 7y agoUnfortunately, that only works well in the absence of threads. With multiple threads, the out-of-memory could have been caused by code in another thread allocating too much.