From 0abd793fe7b6bd83d62a7b3f690a22d549723b55 Mon Sep 17 00:00:00 2001 From: Sebastian Crane Date: Tue, 22 Mar 2022 22:47:00 +0000 Subject: [PATCH] Use a Var instead of an Atom for system state The Atom's swap! function may run its provided function multiple times. Because of this, using an Atom for the system state can occasionally result in duplicate TCP connections being opened when the system is started. These connections remain open until they timeout (this is typically 5 minutes for IRC). This commit changes the container for the system state from an Atom to a Var, whose alter-var-root function (analogous to swap!) does not have this issue. Signed-off-by: Sebastian Crane --- README.md | 12 ++++++------ src/system.clj | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4ddee61..2670e33 100644 --- a/README.md +++ b/README.md @@ -66,18 +66,18 @@ Since `matchbot` uses Clojure's [tools.deps library](https://clojure.org/guides/ You can create, start and stop an instance of the chatbot process with the functions in the `system` namespace: ``` clojure -;; creating a new instance -(def my-instance (atom (system/system))) +;; creating a new instance - an empty Var +(def my-instance nil) ;; starting the instance -(swap! my-instance system/start) +(alter-var-root #'my-instance system/start) ;; restarting the instance -(system/restart my-instance) +(system/restart #'my-instance) ;; stopping and resetting the instance -(swap! my-instance stop) -(reset! my-instance (system/system)) +(alter-var-root #'my-instance system/stop) +(alter-var-root #'my-instance (constantly nil)) ``` Once you are familiar with nREPL, you can additionally use [tools.namespace.repl](https://github.com/clojure/tools.namespace) to make reevaluating (reloading) your changes easier: diff --git a/src/system.clj b/src/system.clj index d675a26..e317eea 100644 --- a/src/system.clj +++ b/src/system.clj @@ -55,11 +55,11 @@ (deref (:state system))) (irclj.core/quit (system :irc)))) -(defn restart [system-atom] +(defn restart [system-var] (do - (swap! system-atom stop) - (reset! system-atom (system)) - (swap! system-atom start))) + (alter-var-root system-var stop) + (alter-var-root system-var (constantly system)) + (alter-var-root system-var start))) (defn -main [& args] (let [main-system (system/start nil)]