Blackbird-base:promise instead of result (on emacs slime repl)
heylisp opened this issue · comments
Hi,
if I run this on my emacs-slime repl:
(future:on-completed (act:ask *answerer* "Buzz") (lambda (result) (format t "Received result: ~a~%" result)))
I get something like this:
#<BLACKBIRD-BASE:PROMISE name: "attach: PROMISE" finished: NIL errored: NIL forward: NIL {10025761C3}>
(if I hit enter again I get ;no value)
And if I run something like this:
(act:tell *answerer* "hello")
I get :STOPPED as result.
Is there a problem or should I use another method to capture the result?
Thanks!
Hi.
How does your *answerer*
implementation look like?
Since you are ask
ing something *answerer*
should respond with something.
See:
CL-USER> (defparameter *sys* (asys:make-actor-system))
*SYS*
CL-USER> (defparameter *answerer* (act:actor-of (*sys*)
:receive (lambda (self msg state)
(cons (str:concat msg " Reply") state))))
*ANSWERER*
CL-USER> (future:on-completed (act:ask *answerer* "Buzz")
(lambda (result) (format t "Received: ~a~%" result)))
#<PROMISE name: "attach: PROMISE" finished: NIL errored: NIL forward: NIL #x302002E5886D>
Received: Buzz Reply
This is the asynchronous way to get a result. There is also ask-s
which will block on the caller site for a result.
This is all the output I get on the repl (only last line is actual final output). I get Received: Buzz Reply
only as last "console-logs" (because of the line of code (format t "Received: ~a~%" result)
. But actual output doesn't contain it:
<INFO> [11:25:27] cl-gserver.messageb message-box.lisp (submit message-box/dp) -
mesgb-737: enqueuing... withreply-p: NIL, time-out: NIL, message: Buzz
<INFO> [11:25:27] cl-gserver.messageb message-box.lisp (submit message-box/dp) -
waiter-mb/dp-738: enqueuing... withreply-p: NIL, time-out: NIL, message: Buzz Reply
<INFO> [11:25:27] cl-gserver.actor actor.lisp (ask actor) -
Result: Buzz Reply, timed-out:NIL
Received: Buzz Reply
#<BLACKBIRD-BASE:PROMISE name: "attach: PROMISE" finished: T errored: NIL forward: NIL {1002E55C63}>
Well, on-completed
is a callback handler to handle a received result. So whatever you want to do with the result, it has to happen within the lambda. The return of on-completed
should be ignored and should in fact be nil
.
If you want to actively poll for a result you can use:
CL-USER> (act:ask *answerer* "Buzz")
#<FUTURE promise: #<PROMISE finished: NIL errored: NIL forward: NIL #x302002FD8F1D>>
CL-USER> (future:get-result *)
"Buzz Reply"
However, get-result
doesn't block and you have to repeatedly check until the result from *answerer*
is received and the future
fulfilled.
For this case however, where you block the caller thread, ask-s
is more efficient.
Great! Thank you!
Btw: if you have questions like this you can also use the 'Discussions' GitHub feature instead.