From b090819483854cbfcce64659ad5e97bb35a4065f Mon Sep 17 00:00:00 2001 From: James Brechtel Date: Thu, 11 Jun 2026 12:43:12 -0400 Subject: [PATCH] feat: add SSE connection state and reconnection logic --- noise-sse.el | 24 ++++++++++++++++++++++++ test/noise-sse-test.el | 26 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/noise-sse.el b/noise-sse.el index fd76c52..c5fa6cf 100644 --- a/noise-sse.el +++ b/noise-sse.el @@ -11,6 +11,30 @@ (require 'json) (require 'cl-lib) +(defvar noise-sse--process nil + "Active SSE network process, or nil.") + +(defvar noise-sse--reconnect-timer nil + "Timer for reconnection attempts, or nil.") + +(defvar noise-sse--reconnect-delay 1 + "Current delay in seconds before next reconnection attempt.") + +(defcustom noise-sse-max-reconnect-delay 60 + "Maximum delay in seconds between reconnection attempts." + :type 'integer + :group 'noise) + +(defun noise-sse--increase-reconnect-delay () + "Increase reconnect delay with exponential backoff, capped at max." + (setq noise-sse--reconnect-delay + (min (* noise-sse--reconnect-delay 2) + noise-sse-max-reconnect-delay))) + +(defun noise-sse--reset-reconnect-delay () + "Reset reconnect delay to initial value after successful connection." + (setq noise-sse--reconnect-delay 1)) + (defun noise-sse--parse-event (event-string) "Parse an SSE EVENT-STRING into a hash table. Returns nil for empty or invalid events." diff --git a/test/noise-sse-test.el b/test/noise-sse-test.el index ee054e1..baade5f 100644 --- a/test/noise-sse-test.el +++ b/test/noise-sse-test.el @@ -29,5 +29,31 @@ (let ((event "\n\n")) (should (null (noise-sse--parse-event event))))) +(ert-deftest noise-sse--initial-state () + "SSE client starts in disconnected state." + (let ((noise-sse--process nil) + (noise-sse--reconnect-timer nil) + (noise-sse--reconnect-delay 1)) + (should (null noise-sse--process)) + (should (null noise-sse--reconnect-timer)) + (should (= 1 noise-sse--reconnect-delay)))) + +(ert-deftest noise-sse--reconnect-delay-backoff () + "Reconnect delay doubles on each attempt." + (let ((noise-sse--reconnect-delay 1)) + (noise-sse--increase-reconnect-delay) + (should (= 2 noise-sse--reconnect-delay)) + (noise-sse--increase-reconnect-delay) + (should (= 4 noise-sse--reconnect-delay)) + (noise-sse--increase-reconnect-delay) + (should (= 8 noise-sse--reconnect-delay)))) + +(ert-deftest noise-sse--reconnect-delay-max () + "Reconnect delay caps at max value." + (let ((noise-sse--reconnect-delay 32) + (noise-sse-max-reconnect-delay 60)) + (noise-sse--increase-reconnect-delay) + (should (= 60 noise-sse--reconnect-delay)))) + (provide 'noise-sse-test) ;;; noise-sse-test.el ends here