A note on interprocess communication with the async
package:
In spite of the fact that async.el
defines a function async-send
that is not used in that file I assume that the package is not really intendedfit for interprocess communication.
The reason forThere exists a test case async-test-5
for async-send
.
I modified that assumptiontest case a bit to make debugging easier:
- Only
async-start
andasync-start-process
are mentioned in the doc string of the package async-ready
returnst
for the process statesexit
andsignal
of the child process -- both leading to the termination of the child process -- andasync-wait
just waits forasync-ready
to become trueasync-get
usesasync-ready
- Emacs is invoked with command line option
--batch
byasync-start
. So Emacs exists when thePROGRAM
has finished.
(defun async-test-5 ()
(interactive)
(message "Starting async-test-5...")
(let ((proc
(async-start
;; What to do in the child process
(lambda ()
(with-temp-buffer
(insert (format "Value of `async-callback': %S\n" async-callback))
(async-send :hello "world")
;; wait for messages
(while (let* ((msg (async-receive))
(str (plist-get msg :goodbye)))
(insert (format "Child got message: %s\n" str))
(sleep-for 1)
(null (string-equal str "goodbye"))))
(buffer-string)))
;; What to do when it finishes
(lambda (result)
(if (async-message-p result)
(message "Got hello from child process: %s"
(plist-get result :hello))
(message "Async process done, result: %s"
result))))))
(setq async-message-from-child nil)
(async-send proc :goodbye "everyone")
(sleep-for 1)
(async-send proc :goodbye "just for you")
(sleep-for 1)
(async-send proc :goodbye "goodbye"))
(message "Starting async-test-5...done"))
Running async-test-5
interactively outputs following message:
Async process done, result: Value of `async-callback': nil
Child got message: everyone
Child got message: just for you
Child got message: goodbye
As one sees one can send messages from the mother process to the child but sending messages from the child to the mother process (the (async-send :hello "world")
thing) fails.
async-send
uses the value of async-callback
in the child and that variable is never set in the child.
The output string Value of 'async-callback': nil
proves that.
For completeness the code of async-send
in version 1.9 of async.el
:
(defun async-send (&rest args)
"Send the given messages to the asychronous Emacs PROCESS."
(let ((args (append args '(:async-message t))))
(if async-in-child-emacs
(if async-callback
(funcall async-callback args))
(async--transmit-sexp (car args) (list 'quote (cdr args))))))