From a84cce2850dfce357ed5e37a3fb5ebba6ccad5bc Mon Sep 17 00:00:00 2001 From: Uko Kokņevičs Date: Sun, 19 Oct 2025 07:49:30 +0300 Subject: Introduce locking in config --- src/config.lisp | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) (limited to 'src/config.lisp') diff --git a/src/config.lisp b/src/config.lisp index cf04c1c..7d841a2 100644 --- a/src/config.lisp +++ b/src/config.lisp @@ -3,7 +3,7 @@ (defpackage :ukkoclot/src/config (:documentation "Stuff for loading the configuration of the bot") (:nicknames :conf) - (:use :c2cl :iterate) + (:use :c2cl :iterate :ukkoclot/src/rw-lock) (:export #:*config* #:config @@ -20,6 +20,7 @@ (in-package :ukkoclot/src/config) (defstruct config + (lock (make-rw-lock :name "config's lock") :type rw-lock) (bot-name "Ukko's Clot" :type string) (bot-token "123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi" :type string) (db-path #P"./data.db" :type (or pathname string)) @@ -31,41 +32,53 @@ (defun bot-name (&optional (config *config*)) "Get the desired name for the bot" - (config-bot-name config)) + (with-slots (lock bot-name) config + (with-read-lock (lock) + bot-name))) (defun bot-token (&optional (config *config*)) "Get the API token for the bot" - (config-bot-token config)) + (with-slots (lock bot-token) config + (with-read-lock (lock) + bot-token))) (defun db-path (&optional (config *config*)) "Get the path to the bot's database" - (config-db-path config)) + (with-slots (lock db-path) config + (with-read-lock (lock) + db-path))) (defun dev-group (&optional (config *config*)) "Get the ID of the dev/testing group" - (config-dev-group config)) + (with-slots (lock dev-group) config + (with-read-lock (lock) + dev-group))) (defun owner (&optional (config *config*)) "Get the ID of the bot's owner" - (config-owner config)) + (with-slots (lock owner) config + (with-read-lock (lock) + owner))) (defun load-config (filename &optional (config *config*)) "Load config from the given `filename'." (prog1 config (let ((data (with-open-file (f filename) (read f)))) - (iter - (for (kw-name value) on data by #'cddr) - (let ((name (intern (symbol-name kw-name) :ukkoclot/src/config))) - (setf (slot-value config name) value)))))) + (with-write-lock ((config-lock config)) + (iter + (for (kw-name value) on data by #'cddr) + (let ((name (intern (symbol-name kw-name) :ukkoclot/src/config))) + (setf (slot-value config name) value))))))) (defun serialize (config) "Serializes the config to a plist." - (iter - (for slot in (class-direct-slots (class-of config))) - (appending - (let* ((name (slot-definition-name slot)) - (kw-name (intern (symbol-name name) :keyword))) - (list kw-name (slot-value config name)))))) + (with-read-lock ((config-lock config)) + (iter + (for slot in (class-direct-slots (class-of config))) + (let ((name (slot-definition-name slot))) + (unless (eql name 'lock) + (let ((kw-name (intern (symbol-name name) :keyword))) + (appending (list kw-name (slot-value config name))))))))) (defun print-default (filename) "Prints the default config to the given `filename'." -- cgit v1.2.3