Skip to content

Commit

Permalink
added future:fawait to await a future to be resolved.
Browse files Browse the repository at this point in the history
  • Loading branch information
mdbergmann committed Mar 15, 2024
1 parent 535c41e commit c583a0a
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
5 changes: 2 additions & 3 deletions src/actor.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@
(defun finalize-initialization (actor message-box actor-context)
"Private API: finalize initialization of the actor with a `mesgb:message-box` and an `ac:actor-context`."
(setf (act:context actor) actor-context)
;; not fully sure is we allow to have the msgbox being setup or not.
(pre-start actor)
(setf (act-cell:msgbox actor) message-box))
(setf (act-cell:msgbox actor) message-box)
(pre-start actor))

(defmethod print-object ((obj actor) stream)
(print-unreadable-object (obj stream :type t)
Expand Down
18 changes: 18 additions & 0 deletions src/fcomputation.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#:futurep
#:complete-p
#:fcompleted
#:fawait
#:fresult
#:frecover
#:fmap
Expand Down Expand Up @@ -121,6 +122,23 @@ Example:
"
`(%fcompleted ,future (lambda (,result) ,@body)))

(defun fawait (fut &key timeout (sleep-time 0.1))
"Wait for the future `FUT` to be ready. Returns `VALUES` with `result' of the future and `FUT'.
If the future is not ready after `TIMEOUT` seconds the `result' is `NIL'.
The `SLEEP-TIME` parameter specifies the time to sleep between checks of the future.
The wait is based on attempts. To be accurate in terms of `TIMEOUT` the `SLEEP-TIME` should be a divisor of `TIMEOUT`.
Disclaimer: naive implementation. There may be better solutions."
(assert (and timeout (>= timeout 0)) (timeout) "Timeout must be greater or equal to 0")
(let* ((attempts (truncate timeout sleep-time))
(result
(loop :repeat attempts
:do
(let ((result (fresult fut)))
(unless (eq result :not-ready)
(return result))
(sleep sleep-time)))))
(values result fut)))

(defun fresult (future)
"Get the computation result. If not yet available `:not-ready` is returned."
(with-slots (promise) future
Expand Down
6 changes: 6 additions & 0 deletions tests/fcomputation-test.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,9 @@ mixed future, normal and async-future map-fun result."
(is-true (assert-cond (lambda ()
(= 1 completed-val))
1))))

(test await-fut
(multiple-value-bind (res fut)
(fawait (with-fut 0) :timeout 1)
(is (= 0 res))
(is (futurep fut))))

0 comments on commit c583a0a

Please sign in to comment.