ExpiringLock helper

Stephen Paul Weber created

For things we want to do only so often, set up a helper to push expiring keys to
Redis and check for them.

Change summary

lib/expiring_lock.rb | 18 ++++++++++++++++++
sgx_jmp.rb           | 31 +++++++++++++++----------------
2 files changed, 33 insertions(+), 16 deletions(-)

Detailed changes

lib/expiring_lock.rb 🔗

@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class ExpiringLock
+	def initialize(name, expiry: 60 * 60 * 24)
+		@name = name
+		@expiry = expiry
+	end
+
+	def with(els=nil)
+		REDIS.exists(@name).then do |exists|
+			next els&.call if exists == 1
+
+			EMPromise.resolve(yield).then do |rval|
+				REDIS.setex(@name, @expiry, "").then { rval }
+			end
+		end
+	end
+end

sgx_jmp.rb 🔗

@@ -67,6 +67,7 @@ require_relative "lib/command_list"
 require_relative "lib/customer"
 require_relative "lib/customer_repo"
 require_relative "lib/electrum"
+require_relative "lib/expiring_lock"
 require_relative "lib/em"
 require_relative "lib/payment_methods"
 require_relative "lib/registration"
@@ -249,23 +250,21 @@ message do |m|
 			id: customer.customer_id, jid: m.from.stripped.to_s
 		)
 		EMPromise.all([
-			customer, (customer.incr_message_usage if billable_message(m)),
-			REDIS.exists("jmp_usage_notify-#{customer.customer_id}"),
+			(customer.incr_message_usage if billable_message(m)),
 			customer.stanza_from(m)
-		])
-	}.then { |(customer, _, already, _)|
-		next if already == 1
-
-		customer.message_usage((today..(today - 30))).then do |usage|
-			next unless usage > 500
-
-			BLATHER.join(CONFIG[:notify_admin], "sgx-jmp")
-			BLATHER.say(
-				CONFIG[:notify_admin],
-				"#{customer.customer_id} has used #{usage} messages since #{today - 30}",
-				:groupchat
-			)
-			REDIS.set("jmp_usage_notify-#{customer.customer_id}", ex: 60 * 60 * 24)
+		]).then { customer }
+	}.then { |customer|
+		ExpiringLock.new("jmp_usage_notify-#{customer.customer_id}").with do
+			customer.message_usage((today..(today - 30))).then do |usage|
+				next unless usage > 500
+
+				BLATHER.join(CONFIG[:notify_admin], "sgx-jmp")
+				BLATHER.say(
+					CONFIG[:notify_admin],
+					"#{customer.customer_id} has used #{usage} messages since #{today - 30}",
+					:groupchat
+				)
+			end
 		end
 	}.catch { |e| panic(e, sentry_hub) }
 end