Concurrency
How to write concurrent/asynchronous code in Emacs ?
Async processes
Accept that you can do a lot with just multiple async processes – this is the NodeJs approach; a single Emacs can ask another process to do something and use ProcessSentinels and ProcessFilterFunctions to do quite a lot of processing apparently concurrently but really just in an event loop. As long as the ProcessFilterFunction is not too slow this is fine. Elnode takes this approach to making a scalable webserver in EmacsLisp.
emacs-async
Spawn more Emacs processes to do work for you – JohnWiegley’s Async takes this approach, Elnode has an alternative and Elpakit another alternative. No one has unified this approach yet.
Some async applications are provided as well with emacs-async:
- Dired-async
- smtp-mail-async
- async-bytecomp
Example code:
(async-start
;; What to do in the child process
(lambda ()
(message "This is a test")
(sleep-for 3)
222)
;; What to do when it finishes
(lambda (result)
(message "Async process done, result should be 222: %s" result)))
Examples:
- in Nikola.el
emacs-deferred
Defer asynchronous tasks – this is what the emacs-deferred library does. It provides facilities to manage asynchronous tasks. The API and implementations were translated from JSDeferred and Mochikit.Async in Javascript. concurrent.el is a higher level library for concurrency, based on `deferred.el’.
Example:
This is a basic deferred chain. This code puts some outputs into message buffer, and then require a number from minibuffer.
(deferred:$
(deferred:next
(lambda () (message "deferred start")))
(deferred:nextc it
(lambda ()
(message "chain 1")
1))
(deferred:nextc it
(lambda (x)
(message "chain 2 : %s" x)))
(deferred:nextc it
(lambda ()
(read-minibuffer "Input a number: ")))
(deferred:nextc it
(lambda (x)
(message "Got the number : %i" x)))
(deferred:error it
(lambda (err)
(message "Wrong input : %s" err))))
Async/Await
Async/Await for Emacs is based on promise.el.
Example of code:
(async-defun example2 ()
(print (await (wait-async 0.5)))
(message "---")
(print (await (wait-async 1.0)))
(message "---")
(print (await (wait-async 1.5)))
(message "---")
(message "await done"))
Emacs 25's Thread
Thread support has been added to Emacs.
See the discussion at http://thread.gmane.org/gmane.emacs.devel/120530/focus=122664 or the info manual at Thread.