Handle shutdown gracefully
authorFrank Duncan <frank@kank.net>
Fri, 17 Dec 2021 19:56:48 +0000 (13:56 -0600)
committerFrank Duncan <frank@kank.net>
Fri, 17 Dec 2021 19:56:48 +0000 (13:56 -0600)
src/main/aws/aws.lisp
src/main/local/local.lisp
src/main/package.lisp
src/main/processor.lisp
src/main/server.lisp

index 1d3745b27cd59886ad20722d5332710c0ca5b3ad..2913d3244492dc5f9ca8c259c2ad4a8eff6c521b 100644 (file)
@@ -26,6 +26,7 @@
    (values-list retn))))
 
 (defun start-shutdown-thread ()
+ (format t "Starting AWS shutdown thread~%")
  (sb-thread:make-thread
   (lambda ()
    (loop
     (sleep 30)))
   :name "AWS Shutdown Thread"))
 
+(defmethod candle:shutdown-system ((job-system (eql :aws)))
+ (format t "Shutting down AWS box for exit~%")
+ ; If there's a job going, we need to wait for it to finish
+ (sb-thread:with-mutex (*aws-mutex*))
+ (stop-aws-box))
+
 (defun aws-command (cmd &rest args)
  (with-output-to-string (out)
  (sb-ext:run-program
index 8eded5aa4f42eedcb905ea05a04b04dc96ce275d..c06bde89459e41e72dfde3b16b1a95a64fe37c72 100644 (file)
@@ -27,3 +27,6 @@
        :error out-str
        :wait t)))))
   (values (zerop code) out)))
+
+; NOOP as there is no service that needs to be cleaned up
+(defmethod candle:shutdown-system ((job-system (eql :local))))
index 5e2263e0c4cd0c0f4ab39c9a88f03801af3e1199..f9a1d70613aecd7824a36ce92fea1da2c80adfdc 100644 (file)
@@ -2,7 +2,8 @@
  (:export
   #:server #:add-project #:delete-project #:refresh-project #:list-projects
   #:project-branch-information #:run #:*candle-dir* #:*job-system* #:*candle-dir* #:failures
-  #:project-job-information #:get-job-log #:retry-job #:job-project #:project-dir #:process-job-in-system))
+  #:project-job-information #:get-job-log #:retry-job #:job-project #:project-dir #:process-job-in-system
+  #:shutdown-system))
 
 (defpackage #:candle-cli (:use :cl) (:export :run))
 (defpackage #:candle-aws (:use :cl))
index af65aa03946089780831cf5de48b0100851f4a5e..0d6ec1ec075a258699aa69c91370163f518f4fd0 100644 (file)
@@ -5,20 +5,35 @@
 
 (defvar *job-system*)
 (defgeneric process-job-in-system (job-system job))
+(defgeneric shutdown-system (job-system))
 
 (defun start-processor-thread ()
- (sb-thread:make-thread
-  (lambda ()
-   (loop
-    (let
-     ((job (find :queued *all-job* :key #'job-status)))
-     (if job
-      (process-job job)
-      ; We just wait here until the processor is released, which is usually done
-      ; when a project is refreshed.
-      (sb-thread:with-mutex (*mutex*)
-       (sb-thread:condition-wait *waitq* *mutex*))))))
-  :name "Processor"))
+ (format t "Starting processor in ~(~A~) mode~%" *job-system*)
+ (let*
+  ((active t)
+   (processor-thread
+    (sb-thread:make-thread
+     (lambda ()
+      (loop
+       :while active
+       :do
+       (let
+        ((job (find :queued *all-job* :key #'job-status)))
+        (if job
+         (process-job job)
+         ; We just wait here until the processor is released, which is usually done
+         ; when a project is refreshed.
+         (sb-thread:with-mutex (*mutex*)
+          (sb-thread:condition-wait *waitq* *mutex*))))))
+     :name "Processor")))
+  (push
+   (lambda ()
+    (format t "Shutting down processor thread~%")
+    (setf active nil)
+    (awaken-processor-thread)
+    (sb-thread:join-thread processor-thread)
+    (shutdown-system *job-system*))
+   sb-ext:*exit-hooks*)))
 
 (defun awaken-processor-thread ()
  (sb-thread:with-mutex (*mutex*)
index 19780e24bed72a0baa095cafef23ef02da654b14..ffd6e82ce1749f66093a62a210bce636b68f7ab5 100644 (file)
@@ -2,22 +2,48 @@
 
 (defun server (port &optional (background t))
  (when (not *candle-dir*) (error "Need a candle dir"))
- (let
+ (let*
   ((data-dir (format nil "~Adata" *candle-dir*)))
   (ensure-directories-exist *candle-dir*)
   (ensure-directories-exist data-dir)
   (lame-db:load-known-dbs data-dir)
-  (sb-thread:make-thread
-   (lambda ()
-    (do () (nil)
-     (progn
-      (sleep (* 5 60))
-      (lame-db:save-known-dbs data-dir))))
-   :name "Save Thread")
   (format t "Starting processor in ~(~A~) mode~%" *job-system*)
+  (start-save-thread data-dir)
   (start-processor-thread)
   (communication:start-listener port background)))
 
+(defun start-save-thread (data-dir)
+ (format t "Starting Save Thread~%")
+ (let*
+  ((mutex (sb-thread:make-mutex))
+   (waitq (sb-thread:make-waitqueue))
+   (active t)
+   (save-thread
+    (sb-thread:make-thread
+     (lambda ()
+      (loop
+       :while active
+       :do
+       (sb-thread:with-mutex (mutex)
+        (sb-thread:condition-wait waitq mutex)))
+      (lame-db:save-known-dbs data-dir))
+     :name "Save Thread")))
+  (sb-thread:make-thread
+   (lambda ()
+    (loop
+     (sleep (* 1 60))
+     (sb-thread:with-mutex (mutex)
+      (sb-thread:condition-broadcast waitq))))
+   :name "Save Thread Trigger")
+  (push
+   (lambda ()
+    (format t "Shutting down save thread~%")
+    (sb-thread:with-mutex (mutex)
+     (setf active nil)
+     (sb-thread:condition-broadcast waitq))
+    (sb-thread:join-thread save-thread))
+   sb-ext:*exit-hooks*)))
+
 (defun add-project (name src)
  (when
   (not (cl-ppcre:scan "^[0-9A-Za-z-]*$" name))