From 6f8f60a9e2b7adfc7f9655845196244ada290a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Wed, 30 Oct 2024 13:45:56 +0100 Subject: [PATCH] Add timeout for fetching latest event --- app/controllers/settings_controller.rb | 7 +++- .../nostr_manager/fetch_latest_event.rb | 35 +++++++++++++------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index 6584c91..47e9b43 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -135,12 +135,17 @@ class SettingsController < ApplicationController def fetch_nostr_user_metadata if @user.nostr_pubkey.present? + outbox_relay_urls = nil + if @nip65_event = NostrManager::DiscoverUserRelays.call(pubkey: @user.nostr_pubkey) relay_tags = @nip65_event["tags"].select{ |t| t[0] == "r" } outbox_relay_urls = relay_tags&.select{ |t| t[2] != "read" }&.map{ |t| t[1] } end - @profile = NostrManager::DiscoverUserProfile.call(pubkey: @user.nostr_pubkey, relays: outbox_relay_urls) + @profile = NostrManager::DiscoverUserProfile.call( + pubkey: @user.nostr_pubkey, + relays: outbox_relay_urls + ) else @relays, @profile = [nil, nil] end diff --git a/app/services/nostr_manager/fetch_latest_event.rb b/app/services/nostr_manager/fetch_latest_event.rb index e40baca..5cff423 100644 --- a/app/services/nostr_manager/fetch_latest_event.rb +++ b/app/services/nostr_manager/fetch_latest_event.rb @@ -1,5 +1,6 @@ module NostrManager class FetchLatestEvent < NostrManagerService + TIMEOUT = 5 def initialize(relays:, filter:, max_events: 2) @relays = relays @@ -11,21 +12,33 @@ module NostrManager received_events = 0 events = [] - @relays.each do |url| - event = NostrManager::FetchEvent.call(filter: @filter, relay_url: url) + begin + Timeout.timeout(TIMEOUT) do + @relays.each do |url| + event = NostrManager::FetchEvent.call(filter: @filter, relay_url: url) - if event.present? - events << event if events.none? { |e| e["id"] == event["id"] } - received_events += 1 + if event.present? + events << event if events.none? { |e| e["id"] == event["id"] } + received_events += 1 + end + + if received_events >= @max_events + Rails.logger.debug "Found #{@max_events} events, ending the search" + break + end + end + + events.min_by { |e| e["created_at"] } end - - if received_events >= @max_events - Rails.logger.debug "Found #{@max_events} events, ending the search" - break + rescue Timeout::Error + if events.size == 1 + Rails.logger.debug "[nostr] Timeout: only found 1 event within #{TIMEOUT} seconds for filter: #{@filter.inspect}" + events.first + else + Rails.logger.debug "[nostr] Timeout: no events found within #{TIMEOUT} seconds for filter: #{@filter.inspect}" + nil end end - - events.min_by { |e| e["created_at"] } end end end