Do not lose WebRegisterManager on retart

Stephen Paul Weber created

Store web registrations in redis.  Set an expiry so they don't grow in RAM
forever as they previously would have without a restart.

Change summary

lib/registration.rb               |  2 +-
lib/web_register_manager.rb       | 14 +++++++++-----
sgx_jmp.rb                        |  4 ++--
test/test_helper.rb               | 11 ++++++++++-
test/test_registration.rb         |  8 ++++----
test/test_web_register_manager.rb | 13 +++++++------
6 files changed, 33 insertions(+), 19 deletions(-)

Detailed changes

lib/registration.rb 🔗

@@ -17,7 +17,7 @@ class Registration
 			if registered
 				Registered.new(registered.phone)
 			else
-				web_register_manager[customer.jid].choose_tel.then do |tel|
+				web_register_manager[customer.jid].then(&:choose_tel).then do |tel|
 					Activation.for(customer, tel)
 				end
 			end

lib/web_register_manager.rb 🔗

@@ -1,16 +1,20 @@
 # frozen_string_literal: true
 
 class WebRegisterManager
-	def initialize
-		@tel_map = Hash.new { ChooseTel.new }
+	THIRTY_DAYS = 60 * 60 * 24 * 30
+
+	def initialize(redis: REDIS)
+		@redis = redis
 	end
 
-	def []=(jid, tel)
-		@tel_map[jid.to_s] = HaveTel.new(tel)
+	def set(jid, tel)
+		@redis.setex("pending_tel_for-#{jid}", tel, THIRTY_DAYS)
 	end
 
 	def [](jid)
-		@tel_map[jid.to_s]
+		@redis.get("pending_tel_for-#{jid}").then do |tel|
+			tel ? HaveTel.new(tel) : ChooseTel.new
+		end
 	end
 
 	class HaveTel

sgx_jmp.rb 🔗

@@ -547,8 +547,8 @@ command :execute?, node: "web-register", sessionid: nil do |iq|
 				cmd.form.fields = [var: "to", value: jid]
 				cmd.form.type = "submit"
 			}).then { |result|
-				final_jid = result.form.field("from")&.value.to_s.strip
-				web_register_manager[final_jid] = tel
+				web_register_manager.set(result.form.field("from")&.value.to_s.strip, tel)
+			}.then {
 				BLATHER << iq.reply.tap { |reply| reply.status = :completed }
 			}.catch { |e| panic(e, sentry_hub) }
 		end

test/test_helper.rb 🔗

@@ -133,10 +133,19 @@ class PromiseMock < Minitest::Mock
 end
 
 class FakeRedis
-	def initialize(values)
+	def initialize(values={})
 		@values = values
 	end
 
+	def set(key, value)
+		@values[key] = value
+		EMPromise.resolve("OK")
+	end
+
+	def setex(key, value, _expiry)
+		set(key, value)
+	end
+
 	def get(key)
 		EMPromise.resolve(@values[key])
 	end

test/test_registration.rb 🔗

@@ -35,8 +35,8 @@ class RegistrationTest < Minitest::Test
 	em :test_for_registered
 
 	def test_for_activated
-		web_manager = WebRegisterManager.new
-		web_manager["test@example.net"] = "+15555550000"
+		web_manager = WebRegisterManager.new(redis: FakeRedis.new)
+		web_manager.set("test@example.net", "+15555550000")
 		result = execute_command do
 			sgx = OpenStruct.new(registered?: EMPromise.resolve(nil))
 			Registration.for(
@@ -54,8 +54,8 @@ class RegistrationTest < Minitest::Test
 
 	def test_for_not_activated_with_customer_id
 		sgx = OpenStruct.new(registered?: EMPromise.resolve(nil))
-		web_manager = WebRegisterManager.new
-		web_manager["test@example.net"] = "+15555550000"
+		web_manager = WebRegisterManager.new(redis: FakeRedis.new)
+		web_manager.set("test@example.net", "+15555550000")
 		iq = Blather::Stanza::Iq::Command.new
 		iq.from = "test@example.com"
 		result = execute_command(iq) do

test/test_web_register_manager.rb 🔗

@@ -5,19 +5,20 @@ require "web_register_manager"
 
 class WebRegisterManagerTest < Minitest::Test
 	def setup
-		@manager = WebRegisterManager.new
+		@manager = WebRegisterManager.new(redis: FakeRedis.new)
 	end
 
 	def test_set_get
-		assert_kind_of WebRegisterManager::ChooseTel, @manager["jid@example.com"]
-		@manager["jid@example.com"] = "+15555550000"
-		assert_kind_of WebRegisterManager::HaveTel, @manager["jid@example.com"]
+		assert_kind_of WebRegisterManager::ChooseTel, @manager["jid@example.com"].sync
+		@manager.set("jid@example.com", "+15555550000").sync
+		assert_kind_of WebRegisterManager::HaveTel, @manager["jid@example.com"].sync
 	end
+	em :test_set_get
 
 	def test_choose_tel_have_tel
 		jid = "jid@example.com"
-		@manager[jid] = "+15555550000"
-		assert_equal "+15555550000", @manager[jid].choose_tel.sync
+		@manager.set(jid, "+15555550000").sync
+		assert_equal "+15555550000", @manager[jid].then(&:choose_tel).sync
 	end
 	em :test_choose_tel_have_tel
 end