- (call-with-prompt (hive-prompt hive)
- (lambda ()
- (define message-handler (actor-message-handler actor))
- ;; @@: Should a more general error handling happen here?
- (message-handler actor message))
-
- (lambda (kont actor message)
- (let ((hive (actor-hive actor)))
- ;; Register the coroutine
- (hash-set! (hive-waiting-coroutines hive)
- (message-id message)
- (cons (actor-id actor) kont))
- ;; Send off the message
- (8sync (hive-process-message hive message)))))))
+ actor))
+
+ (define (call-catching-coroutine thunk)
+ (define queued-error-handling-thunk #f)
+ (define (call-catching-errors)
+ ;; TODO: maybe parameterize (or attach to hive) and use
+ ;; maybe-catch-all from agenda.scm
+ ;; @@: Why not just use with-throw-handler and let the catch
+ ;; happen at the agenda? That's what we used to do, but
+ ;; it ended up with a SIGABRT. See:
+ ;; http://lists.gnu.org/archive/html/bug-guile/2016-05/msg00003.html
+ (catch #t
+ thunk
+ ;; In the actor model, we don't totally crash on errors.
+ (lambda _ #f)
+ ;; If an error happens, we raise it
+ (lambda (key . args)
+ (if (message-needs-reply? message)
+ ;; If the message is waiting on a reply, let them know
+ ;; something went wrong.
+ ;; However, we have to do it outside of this catch
+ ;; routine, or we'll end up in an unrewindable continuation
+ ;; situation.
+ (set! queued-error-handling-thunk
+ (hive-reply-with-error hive message key args)))
+ ;; print error message
+ (apply print-error-and-continue key args)))
+ ;; @@: This is a kludge. See above for why.
+ (if queued-error-handling-thunk
+ (8sync (queued-error-handling-thunk))))
+ (call-with-prompt (hive-prompt hive)
+ call-catching-errors
+ (lambda (kont actor message)
+ ;; Register the coroutine
+ (hash-set! (hive-waiting-coroutines hive)
+ (message-id message)
+ (cons (actor-id actor) kont))
+ ;; Send off the message
+ (8sync (hive-process-message hive message)))))
+
+ (define (process-local-message)
+ (let ((actor (resolve-actor-to)))
+ (call-catching-coroutine
+ (lambda ()
+ (define message-handler (actor-message-handler actor))
+ ;; @@: Should a more general error handling happen here?
+ (let ((result
+ (message-handler actor message)))
+ (maybe-autoreply actor)
+ ;; Returning result allows actors to possibly make a run-request
+ ;; at the end of handling a message.
+ ;; ... We do want that, right?
+ result)))))