forcible

Thread- and exception aware, lazy-looking synchronization with timeouts - extending srfi-45.

  1. forcible
  2. Rationale
  3. Requirements
  4. Timeouts
  5. API
    1. Low Level
  6. About this egg
    1. Source
    2. Version History
    3. Authors
    4. License

Rationale

Force and delay from CHICKEN core as well as SRFI-45 exhibit unintuitive behavior in the presence of SRFI-18 threads and when exceptions are raised. The srfi-45 egg extends the srfi-45 reference implementation to support multiple values but is still unintuitive wrt. threads and exceptions.

This egg builds and extends those, explicit aiming on the following objectives:

Requirements

Requires pigeon-hole, simple-timer.

The implementation of expectable currently (2016-01-10) depends on a CHICKEN having the fix for Ticket 1231 applied.

Timeouts

Timeouts come at negligible runtime overhead – the cost of being coarse grained. It is assumed that most timeouts never "fire" hence the are deferred for the sake of optimization. Timeouts fire only if they are not canceled before at least a full timeout-period passed. A timeout-period defaults to one second.

API

[procedure] (timeout-condition? x) -> boolean

Test x to be a timeout condition object.

[procedure] (eager . vals) -> PROMISE

Returns a promise which, when forced returns the values vals.

[syntax] (lazy EXPRESSION) -> PROMISE

Returns a promise for EXPRESSION.

[syntax] (delay EXPRESSION) -> PROMISE

Returns a promise, a delayed evaluation of EXPRESSION.

[syntax] (delay/timeout TIMEOUT EXPRESSION) -> PROMISE

Same as delay EXPRESSION. Promise may fail raising an object for which timeout-condition? returns #t.

[syntax] (future EXPRESSION) -> PROMISE
[syntax] (&begin BODY ...) -> PROMISE

Returns a promise, a delayed evaluation of EXPRESSION. The evaluation of expression is started immediately in another thread. PROMISE will cache exceptions returned by EXPRSSION.

&begin is analogous to future with BODY ... wraped in begin.

[syntax] (future/timeout TIMEOUT EXPRESSION) -> PROMISE
[syntax] (&begin/timeout TIMEOUT BODY ...) -> PROMISE

Variation of future. The evaluation of EXPRESSION receives an exceptions for which timeout-condition? holds after TIMEOUT.

&begin/timeout is the same as future/timeout with BODY ... waped in begin.

[syntax] (order EXPRESSION) -> PROMISE

Returns a promise, a delayed evaluation of EXPRESSION. The evaluation of expression is ordered from another thread in a threadpool. PROMISE will cache exceptions returned by EXPRSSION.

[syntax] (order/timeout TIMEOUT EXPRESSION) -> PROMISE

Variation of order. The evaluation of EXPRESSION receives an exceptions for which timeout-condition? holds after TIMEOUT.

[syntax] (lazy-future EXPRESSION) -> PROMISE

Same as future however the thread is NOT started. Use demand to start it prior to force. Use of force will also start it if not demanded before.

[procedure] (demand PROMISE) -> boolean

If the PROMISE was created by lazy-future and the thread is not yet started, start it. Returns #t if the thread was started only now, otherwise returns #f.

[procedure] (force OBJECT [FAIL]) -> . *

Force OBJECT. Returns OBJECT if it is NOT a promise. Otherwise returns the values the suspended EXPRESSION returned.

If FAIL is provided it must be a procedure of one argument. Exceptions raised from the EXPRESSION are passed to FAIL.

This is equivalent to (but more efficiently implemented)

(handle-exceptions ex (FAIL ex) (force OBJECT))
[procedure] (expectable [NAME] [THUNK]) -> PROCEDURE PROMISE

NAME is any object and used for debug purposes only (currently passed as name of an internal mutex). Returns two values. PROCEDURE takes a flag indicating whether the PROMISE shall return successful (if #t) or fail and values to return from forceing the PROMISE. If the flag is #f only the first of those values is used and passed to the exception handler as the exception raised from the PROMISE.

When THUNK is given the resulting promise behaves like a promise created by lazy.

Low Level

[procedure] (fulfil! PROMISE TYPE . ARGS) -> boolean

Mutate PROMISE to be fulfilled. TYPE must be a boolean. If #t the PROMISE is set to return successfully the values ARGS. If TYPE is #f the PROMISE will raise the first value of ARGS as exception.

Note: This procedure MAY be removed in future versions (if it proves to be questionable).

About this egg

Source

Latest version: forcible from askemos.org

Version History

0.3.9: Ported to CHICKEN 5 and factor out and use simple-timer.

0.3.8: Bugfix.

0.3.6: Attempted fix implementation wrt. execution in bounded space actally creating a leak.

0.3: Added /timeout.

0.2: Added optional THUNK to expectable.

0.1: Initial version.

Authors

Jörg F. Wittenberger

License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.