Reputation: 315
I'm writing an app that sometimes requires very long-running DB requests. I'd like to execute some code if the client reloads or closes the page to do things with the DB requests.
I was hoping that Rack would have hooks into this sorta thing, but apparently from what I've seen this is a level deeper than Rack goes.
So far, the only hook I can find is into thin itself, by monkey-patching the unbind function in the thin Connection class:
module Thin
class Connection < EventMachine::Connection
def unbind
# DO something here
@request.async_close.succeed if @request.async_close
@response.body.fail if @response.body.respond_to?(:fail)
@backend.connection_finished(self)
end
end
end
This overrides Thin's unbind function and lets me hook into the disconnect called by EventMachine.
Is there a better way?
Upvotes: 3
Views: 497
Reputation: 315
After some digging, I've found that Thin provides a mechanism for replacing the 'backend', or how the server connects to the client. I'm using that, combined with values in the rack env to deal with specific request instances and know if I need to kill a query or not:
class Backend < Thin::Backends::TcpServer
def initialize(host, port, options={})
super(host, port)
end
def connection_finished(connection)
super(connection)
if connection.request.env["query_killer"]
connection.request.env["query_killer"].kill
end
end
end
This can be included into thin via command-line arguments:
thin start -r 'my_module/backend' --backend MyModule::Backend
Upvotes: 1