Stephen R. van den Berg wrote:
Marcus Comstedt (ACROSS) (Hail Ilpalazzo!) @ Pike (-) developers forum wrote:
My variant with Concurrent.all does work as intended though, and does not require a Promise in.
I'll do some more tests to see what happens when, and will see if I can devise a testsuite entry.
Ok, revised it, reworked it, optimised the timeout_call_out_handle out of the standard Future class footprint along the way, and included four testsuite tests to test both delay() and timeout().
The total implementation of both timeout() and delay() member functions now consists of just:
private this_program setup_call_out(int|float seconds, void|int tout) { array call_out_handle; Promise p = promise_factory(); void cancelcout(mixed value) { (backend ? backend->remove_call_out : remove_call_out)(call_out_handle); p->try_success(0); } on_failure(cancelcout); call_out_handle = (backend ? backend->call_out : call_out) (p[tout ? "try_failure" : "try_success"], seconds, tout && ({ "Timeout.\n", backtrace() })); if (tout) on_success(cancelcout); return p->future(); }
//! Return a @[Future] that will either be fulfilled with the fulfilled //! result of this @[Future], or be failed after @[seconds] have expired. this_program timeout(int|float seconds) { return first_completed( ({ this_program::this, setup_call_out(seconds, 1) }) ); }
//! Return a @[Future] that will be fulfilled with the fulfilled //! result of this @[Future], but not until at least @[seconds] have passed. this_program delay(int|float seconds) { return results( ({ this_program::this, setup_call_out(seconds) }) )->map(`[], 0); }