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 <seabass-labrax@gmx.com>
This commit is contained in:
Sebastian Crane 2022-03-22 22:47:00 +00:00
parent 56094478db
commit 0abd793fe7
2 changed files with 10 additions and 10 deletions

View File

@ -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: You can create, start and stop an instance of the chatbot process with the functions in the `system` namespace:
``` clojure ``` clojure
;; creating a new instance ;; creating a new instance - an empty Var
(def my-instance (atom (system/system))) (def my-instance nil)
;; starting the instance ;; starting the instance
(swap! my-instance system/start) (alter-var-root #'my-instance system/start)
;; restarting the instance ;; restarting the instance
(system/restart my-instance) (system/restart #'my-instance)
;; stopping and resetting the instance ;; stopping and resetting the instance
(swap! my-instance stop) (alter-var-root #'my-instance system/stop)
(reset! my-instance (system/system)) (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: 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:

View File

@ -55,11 +55,11 @@
(deref (:state system))) (deref (:state system)))
(irclj.core/quit (system :irc)))) (irclj.core/quit (system :irc))))
(defn restart [system-atom] (defn restart [system-var]
(do (do
(swap! system-atom stop) (alter-var-root system-var stop)
(reset! system-atom (system)) (alter-var-root system-var (constantly system))
(swap! system-atom start))) (alter-var-root system-var start)))
(defn -main [& args] (defn -main [& args]
(let [main-system (system/start nil)] (let [main-system (system/start nil)]