(defvar *mutex* (sb-thread:make-mutex))
(defvar *waitq* (sb-thread:make-waitqueue))
-(defvar *job-system*)
-(defgeneric process-job-in-system (job-system job))
+(defvar *job-system* nil
+ "*JOB-SYSTEM*
+
+VALUE TYPE:
+
+ A keyword
+
+INITIAL VALUE:
+
+ NIL
+
+DESCRIPTION:
+
+ The job system the server is running under. When implementing a job
+ system, the generics PROCESS-JOB-IN-SYSTEM and SHUTDOWN-SYSTEM must
+ be implemented. Is set by the command line when the server is started.")
+
+(defgeneric process-job-in-system (job-system job)
+ (:documentation
+ "PROCESS-JOB-IN-SYSTEM JOB-SYSTEM JOB => SUCCESS, LOG
+
+ARGUMENTS AND VALUES:
+
+ JOB-SYSTEM: a keyword representing an installed system
+ JOB: A job to be run
+ SUCCESS: A boolean, whether the job was successful
+ LOG: The log from the job
+
+DESCRIPTION:
+
+ Runs a job in the specified system. The code will be checked out,
+ so any defining system should copy the code from the job's project's
+ code dir to wherever it will run, and then ran `candle run` inside
+ that directory, capturing the output."))
+
+(defgeneric shutdown-system (job-system)
+ (:documentation
+ "SHUTDOWN-SYSTEM JOB-SYSTEM => UNUSED
+
+ARGUMENTS AND VALUES:
+
+ JOB-SYSTEM: a keyword representing an installed system
+ UNUSED: the result is unused
+
+DESCRIPTION:
+
+ Shuts down the specified system. Sometimes this will be an empty
+ method, as the system requires no special shutdown instructions.
+ This is run when the candle server is shutdown for the job system
+ that's specified."))
(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"))
+ (log:info "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 ()
+ (log:info "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*)