Break API calls in work towards moving all blocking io to ractors, dropped BackgroundWorker class

This commit is contained in:
2026-01-30 19:36:11 -06:00
parent 6e79c4639d
commit f98d8c3394
7 changed files with 134 additions and 207 deletions

96
lib/network_manager.rb Normal file
View File

@@ -0,0 +1,96 @@
class W3DHub
# all http(s) requests for API calls and downloading images run through here
class NetworkManager
NetworkEvent = Data.define(:context, :result)
Request = Struct.new(:context, :callback)
Context = Data.define(
:request_id,
:url,
:headers,
:body,
:bearer_token
)
def initialize
@requests = {}
@ractor = Ractor.new do
raise "Something has gone quite wrong!" if Ractor.main?
queue = []
api_client = ApiClient.new
# Ractor has no concept of non-blocking send/receive... :cry:
Thread.new do
while (context = Ractor.receive) # blocking
# we cannot (easily) ensure we always are receive expected data
next unless context.is_a?(Context)
queue << context
end
end
Async do
loop do
context = queue.shift
# goto sleep for an instant if there is no work to be doing
unless context
sleep 0.1
next
end
Sync do
result = api_client.handle(context)
Ractor.yield(NetworkEvent.new(context, result))
end
end
end
end
monitor
end
def add_request(url, headers, body, bearer_token, &block)
request_id = SecureRandom.hex
@requests << Request.new(
Context.new(
request_id,
url,
headers,
body,
bearer_token
),
block
)
@ractor.send(context)
request_id
end
def monitor
raise "Something has gone quite wrong!!!" unless Ractor.main?
# Thread that spends its days sleeping **yawn**
Thread.new do
while (event = @ractor.take)
pp event
next unless event.is_a?(NetworkEvent)
request = @request.find { |r| r.context.request_id == event.context.request_id }
next if request
@requests.delete(request)
result = event.result
Store.main_thread_queue << ->(result) { request.callback(result) }
end
end
end
end
end