Files
w3dhub_linux_launcher/lib/network_manager.rb

97 lines
2.1 KiB
Ruby

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