mdbergmann / cl-gserver

Sento - Actor framework featuring actors and agents for easy access to state and asynchronous operations.

Home Page:https://mdbergmann.github.io/cl-gserver/index.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 asking 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.