Add timeout for fetching latest event

This commit is contained in:
Râu Cao 2024-10-30 13:45:56 +01:00
parent c1b4665706
commit 6f8f60a9e2
Signed by: raucao
GPG Key ID: 37036C356E56CC51
2 changed files with 30 additions and 12 deletions

View File

@ -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

View File

@ -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