Skip to content

Instantly share code, notes, and snippets.

@film42
Created April 27, 2016 17:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save film42/ff6e5834888784beae53a3ecc394dafb to your computer and use it in GitHub Desktop.
Save film42/ff6e5834888784beae53a3ecc394dafb to your computer and use it in GitHub Desktop.
class YoloController < ApplicationController
include ::AsyncResponse
def index
async do
sleep 2
@yolo = "I AM ASYNC"
resume_render
end
end
end
# 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