Concurrency

From WikEmacs
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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))))

Examples:

  • emacs-traad, a way to use rope, the python refactoring library.

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.