branch: externals/el-job
commit 183ff2e77549ce32a4d4e1cd4037c37b119b61c9
Author: Martin Edström <[email protected]>
Commit: Martin Edström <[email protected]>
Polish
---
README.org | 17 +++++++++++++----
el-job.el | 31 ++++++++++++++++++++++---------
2 files changed, 35 insertions(+), 13 deletions(-)
diff --git a/README.org b/README.org
index 2fe63f2849..40857d2013 100644
--- a/README.org
+++ b/README.org
@@ -36,18 +36,27 @@ Users who tend to run system commands such as =pkill emacs=
may find that the co
*** Emacs 30 =fast-read-process-output=
Some other libraries, like the popular
[[https://github.com/jwiegley/emacs-async/][async.el]], are designed around a
custom process filter.
-Since Emacs 30, it's a good idea to instead use the /built-in/ process filter
when performance is critical, and el-job does so.
+Since Emacs 30, it's a good idea to instead use the /built-in/ process filter
when performance is critical, and el-job does so. Quoting
[[https://github.com/emacs-mirror/emacs/blob/master/etc/NEWS.30][NEWS.30]]:
-A corollary: if you're testing this on Emacs 29 or below, you don't see this
library at its best performance.
+#+begin_src org
+,** The default process filter was rewritten in native code.
+The round-trip through the Lisp function
+'internal-default-process-filter' is skipped when the process filter is
+the default one. It is reimplemented in native code, reducing GC churn.
+To undo this change, set 'fast-read-process-output' to nil.
+#+end_src
** News 2.1.0
- DROP SUPPORT Emacs 28
- - It likely has not been working for a while anyway. May work if you
downgrade to [[https://github.com/meedstrom/el-job/tree/v0.3][v0.3 branch]].
+ - It likely has not been working for a while anyway. Maybe works on the
[[https://github.com/meedstrom/el-job/tree/v0.3][v0.3 branch]], from 0.3.26+.
** News 2.0.0
-- Jobs must now have :id (no more anonymous jobs)
+- Jobs must now have =:id= (no more anonymous jobs).
- Pruned many code paths.
+** News 1.1.0
+- Changed internals so that all builds of Emacs can be expected to perform
similarly well.
+
** News 1.0.0
- No longer keeps processes alive forever. All jobs are kept alive for up to
30 seconds of disuse, then reaped.
- Pruned many code paths.
diff --git a/el-job.el b/el-job.el
index 90f076e828..592c40f4e8 100644
--- a/el-job.el
+++ b/el-job.el
@@ -409,7 +409,7 @@ For debugging, see these commands:
(unless (and .busy (eq if-busy 'noop))
(plist-put .timestamps :launched (current-time))
;; TODO: Can we somehow defer this to even later?
- ;; Maybe if-busy=wait means don't funcall?
+ ;; Maybe if-busy=wait could inhibit funcalling it?
(when (functionp inputs)
(setq inputs (funcall inputs)))
(if .busy
@@ -422,6 +422,14 @@ For debugging, see these commands:
(setq do-exec t))
(when do-exec
(setf .callback callback)
+ ;; TODO: Complicate the code-base with this?
+ ;; (let ((machine-cores (max 1 (1- (num-processors)))))
+ ;; (setf .n-cores-to-use (if (length< inputs machine-cores)
+ ;; (length inputs)
+ ;; machine-cores)))
+ ;; (when (or (length< .ready .n-cores-to-use)
+ ;; (not (seq-every-p #'process-live-p .ready)))
+ ;; (setq do-respawn t))
(unless (and .ready (seq-every-p #'process-live-p .ready))
(setq do-respawn t))
(let ((new-spawn-args (list job
@@ -441,7 +449,8 @@ For debugging, see these commands:
(defvar-local el-job-here nil)
(defun el-job--spawn-processes (job load-features inject-vars
funcall-per-input)
"Spin up processes for JOB, standing by for input.
-For the rest of the arguments, see `el-job-launch'."
+For arguments LOAD-FEATURES INJECT-VARS FUNCALL-PER-INPUT,
+see `el-job-launch'."
(el-job--with job (.stderr .id .ready .spawn-args)
(let* ((print-length nil)
(print-level nil)
@@ -557,8 +566,11 @@ should trigger `el-job--handle-output'."
;; but spread out the last 7 polls between T-minus-20s and T-minus-30s.
(defun el-job--poll (n bufs)
+ "Check process buffers BUFS for complete output.
+For each where it is complete, handle it. For the rest, check again
+after a short delay. N is the count of checks done so far."
(cl-assert (not (null bufs)))
- (let (busy-bufs id)
+ (let (busy-bufs)
(save-current-buffer
(dolist (buf bufs)
(if (not (buffer-live-p buf))
@@ -567,12 +579,12 @@ should trigger `el-job--handle-output'."
(if (eq (char-before) ?\n)
(el-job--handle-output)
(push buf busy-bufs))))
- (when bufs
- (if (and busy-bufs (<= n 42))
- (setf (el-job:poll-timer el-job-here)
- (run-with-timer
- (/ n (float (ash 1 5))) nil #'el-job--poll (1+ n)
busy-bufs))
- (setq id (el-job:id el-job-here))
+ (cl-assert el-job-here)
+ (if (and busy-bufs (<= n 42))
+ (setf (el-job:poll-timer el-job-here)
+ (run-with-timer
+ (/ n (float (ash 1 5))) nil #'el-job--poll (1+ n) busy-bufs))
+ (let ((id (el-job:id el-job-here)))
(el-job--disable el-job-here)
(if busy-bufs
(message "el-job: Timed out, was busy for 30+ seconds: %s" id)
@@ -653,6 +665,7 @@ same ID still has the benchmarks table and possibly queued
input."
;;; Tools / public API
(defun el-job-cycle-debug-level ()
+ "Increment `el-job--debug-level'."
(interactive)
(message "Variable `el-job--debug-level' set to %d"
(setq el-job--debug-level (% (1+ el-job--debug-level) 3))))