Created
April 27, 2016 17:45
-
-
Save film42/ff6e5834888784beae53a3ecc394dafb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class YoloController < ApplicationController | |
include ::AsyncResponse | |
def index | |
async do | |
sleep 2 | |
@yolo = "I AM ASYNC" | |
resume_render | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# NOT DONE BUT A FUN CONCEPT | |
class AsyncResponseJob | |
include ::SuckerPunch::Job | |
workers 20 | |
def perform(wrapper_block) | |
# This block should be ready to fire with the right context | |
wrapper_block.call | |
end | |
end | |
module AsyncResponse | |
class MissingBlockError < ::StandardError; end | |
class NotInAsyncBlockError < ::StandardError; end | |
def async(&block) | |
fail MissingBlockError, "A block must be provided when using async routes" unless block_given? | |
@_can_use_render_template = true | |
env['rack.hijack'].call | |
@_socket = env['rack.hijack_io'] | |
context = self | |
job_wrapper = lambda do | |
begin | |
context.instance_eval { block.call } | |
ensure | |
@_socket && @_socket.close rescue nil | |
end | |
end | |
AsyncResponseJob.perform_async(job_wrapper) | |
render :text => nil, :status => -1 | |
# This ensures that a socket is cleaned up after any error. We can't | |
# "ensure" here because we want the job to clean itself up. | |
rescue | |
@_socket && @_socket.close rescue nil | |
raise | |
end | |
def resume_render(template = nil) | |
fail NotInAsyncBlockError, "You must be in an async block to use #resume_render" unless @_can_use_render_template | |
template ||= action_name | |
contoller_template_name = "#{controller_name}/#{template}" | |
response = render_to_string(:template => contoller_template_name) | |
return unless @_socket | |
_write_success_headers | |
_copy_response_headers | |
# Close header section and write response. | |
@_socket.write("\n") | |
@_socket.write(response) | |
end | |
def _copy_response_headers | |
response.headers.each do |key, value| | |
@_socket.write("#{key}: #{value}\n") | |
end | |
end | |
def _write_success_headers | |
@_socket.write("HTTP/1.1 200 OK\n") | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment