Handle quitting more gracefully in worker and pipeline threads
ci/woodpecker/push/woodpecker Pipeline failed Details

WIP-cache
Hugo Thunnissen 9 months ago
parent 54679b616f
commit 1031cd929d

@ -1,5 +1,4 @@
export EMACS ?= $(shell which emacs)
CASK_DIR := $(shell cask package-directory)
ELC_FILES = $(patsubst %.el, %.elc, $(shell ls -1 ./*.el ./test/*.el ./benchmarks/*.el))
DEP_DIRECTORY = $(CURDIR)/.deps
@ -34,7 +33,11 @@ stub-index: ./data/builtin-stubs-index.eld.gz
.PHONY: clean
clean:
rm -f $(ELC_FILES) ./stubs/builtins.php ./data/builtin-stubs-index.eld.gz
rm -f $(ELC_FILES) ./data/builtin-stubs-index.eld.gz
.PHONY: clean-all
clean-all: clean
rm -f ./stubs/builtins.php
.PHONY: compile
compile: ./.deps

@ -179,31 +179,35 @@ directories."
(condition-case-unless-debug err
(progn
(phpinspect-pipeline-pause)
(setq ,incoming (phpinspect-pipeline-receive ,inc-queue))
(if (phpinspect-pipeline-end-p ,incoming)
(progn
(setq ,incoming-end ,incoming)
(when (phpinspect-pipeline-end-value ,incoming)
(progn
(setq ,incoming (phpinspect-pipeline-end-value ,incoming)
,outgoing (phpinspect--read-pipeline-emission ,statement))
(phpinspect-pipeline--enqueue ,out-queue ,outgoing 'no-notify)))
;; Prevent quitting during step execution, as this could
;; break data integrity.
(let ((inhibit-quit t))
(setq ,incoming (phpinspect-pipeline-receive ,inc-queue))
(if (phpinspect-pipeline-end-p ,incoming)
(progn
(setq ,incoming-end ,incoming)
(when (phpinspect-pipeline-end-value ,incoming)
(progn
(setq ,incoming (phpinspect-pipeline-end-value ,incoming)
,outgoing (phpinspect--read-pipeline-emission ,statement))
(phpinspect-pipeline--enqueue ,out-queue ,outgoing 'no-notify)))
(setq ,end (phpinspect-make-pipeline-end :thread (current-thread)))
(phpinspect-pipeline-ctx-register-end ,pctx-sym ,end)
(setq ,continue-running nil)
(phpinspect-pipeline--enqueue ,out-queue ,end))
;; Else
(setq ,outgoing (phpinspect--read-pipeline-emission ,statement))
(when (phpinspect-pipeline-end-p ,outgoing)
(setq ,end (phpinspect-make-pipeline-end :thread (current-thread)))
(phpinspect-pipeline-ctx-register-end ,pctx-sym ,end)
(setq ,continue-running nil)
(phpinspect-pipeline--enqueue ,out-queue ,end))
;; Else
(setq ,outgoing (phpinspect--read-pipeline-emission ,statement))
(when (phpinspect-pipeline-end-p ,outgoing)
(setq ,end (phpinspect-make-pipeline-end :thread (current-thread)))
(phpinspect-pipeline-ctx-register-end ,pctx-sym ,end)
(setq ,continue-running nil))
(phpinspect-pipeline--enqueue ,out-queue ,outgoing)))
(setq ,continue-running nil))
(phpinspect-pipeline--enqueue ,out-queue ,outgoing))))
(quit (ignore-error phpinspect-pipeline-incoming
(phpinspect-pipeline-pause)))
(phpinspect-pipeline-incoming)
(quit)
(t (phpinspect--log "Pipeline thread errored: %s" err)
(setq ,end (phpinspect-make-pipeline-end :thread (current-thread) :error err))
(setq ,continue-running nil)

@ -133,34 +133,43 @@ already present in the queue."
(cl-defgeneric phpinspect-worker-make-thread-function (worker)
"Create a function that can be used to start WORKER's thread.")
(defun phpinspect--worker-pause ()
(let* ((mx (make-mutex))
(continue (make-condition-variable mx)))
(phpinspect-thread-pause phpinspect-worker-pause-time mx continue)))
(cl-defmethod phpinspect-worker-make-thread-function ((worker phpinspect-worker))
(lambda ()
(while (phpinspect-worker-continue-running worker)
;; This error is used to wake up the thread when new tasks are added to the
;; queue.
(condition-case err
(ignore-error phpinspect-wakeup-thread
(progn
(phpinspect--log "Dequeueing next task")
(let* ((task (phpinspect-queue-dequeue (phpinspect-worker-queue worker)))
(mx (make-mutex))
(continue (make-condition-variable mx)))
(if task
;; Execute task if it belongs to a project that has not been
;; purged (meaning that it is still actively used).
(if (phpinspect-project-purged (phpinspect-task-project task))
(phpinspect--log "Projecthas been purged. Skipping task")
(phpinspect--log "Executing task")
(phpinspect-task-execute task worker))
;; else: join with the main thread until wakeup is signaled
(phpinspect--log "No tasks, joining main thread")
(thread-join main-thread))
;; Pause for a second after indexing something, to allow user input to
;; interrupt the thread.
(unless (or (not (phpinspect--input-pending-p))
(phpinspect-worker-skip-next-pause worker))
(phpinspect-thread-pause phpinspect-worker-pause-time mx continue))
(setf (phpinspect-worker-skip-next-pause worker) nil)))
(ignore-error phpinspect-wakeup-thread
;; Prevent quitting during tasks, as this can break data integrity
(let* ((inhibit-quit t)
(task (phpinspect-queue-dequeue (phpinspect-worker-queue worker))))
(if task
;; Execute task if it belongs to a project that has not been
;; purged (meaning that it is still actively used).
(if (phpinspect-project-purged (phpinspect-task-project task))
(phpinspect--log "Projecthas been purged. Skipping task")
(phpinspect--log "Executing task")
(phpinspect-task-execute task worker))
;; else: join with the main thread until wakeup is signaled
(phpinspect--log "No tasks, joining main thread")
(thread-join main-thread))))
;; Pause for a second after indexing something, to allow user input to
;; interrupt the thread.
(unless (or (not (phpinspect--input-pending-p))
(phpinspect-worker-skip-next-pause worker))
(phpinspect--worker-pause))
(setf (phpinspect-worker-skip-next-pause worker) nil))
(quit (ignore-error phpinspect-wakeup-thread
(phpinspect--worker-pause)))
(phpinspect-wakeup-thread)
((debug error) (thread-signal main-thread 'phpinspect-worker-error err))
(t (phpinspect--log "Phpinspect worker thread errored :%s" err))))
(phpinspect--log "Worker thread exiting")

Loading…
Cancel
Save