Hi shepherds!
I recently tried to use the task-spooler package, and realized that it
shouldn't be too hard to have the same kind of queue extending the GNU
Shepherd API.
I came up with that, which is not complete, at least because I have no
clue as to how to launch the next transient once one is done. WDYT ?
Could that be added in Shepherd or as a dependent extension ?
(use-modules (shepherd service)
(shepherd support)
(srfi srfi-1)
(srfi srfi-9)
(srfi srfi-26)
(srfi srfi-71)
(ice-9 match))
(define (task-spooler-service)
(service
'(task-spooler)
#:documentation
(l10n "Task spooler service for queueing and executing commands
sequentially.")
#:requirement '(transient)
#:start (lambda ()
(define running #f)
(define queue '())
(define counter 0)
#t)
#:stop (lambda ()
(set! queue '())
(set! counter 0)
(perform-service-action transient-service 'stop))
#:actions
(list
(action 'add
"Add a command to the task queue."
(lambda (command)
(set! counter (+ counter 1))
(set! queue (cons (cons counter command) queue))))
(action 'list
"List all tasks in the queue."
identity)
(action 'remove
"Remove a task from the queue if it's not running."
(match-lambda
(running
(perform-service-action transient-service 'stop))
((? (cut member <> (map car queue)) id)
(set! queue (remove (lambda (t) (= (car t) id)) queue)))
(other
(format #f "Unrecognized task ~a!~%" other)))))))
(define (run-next-task!)
"Run the next queued task."
(and (not (null? queue))
(let* ((rev (reverse queue))
(id (car rev))
(command (cadr rev)))
(set! queue (reverse (cdr rev)))
(perform-service-action transient-service 'spawn command))))
--
Best regards,
Nicolas Graves