@@ -12,9 +12,9 @@ def reset_connection
1212 @connection = create_connection
1313 end
1414
15- def render_code ( path , js_code , send_bundle )
15+ def render_code ( path , js_code , send_bundle , live_response = nil )
1616 Rails . logger . info { "[ReactOnRailsPro] Perform rendering request #{ path } " }
17- perform_request ( path , form_with_code ( js_code , send_bundle ) )
17+ perform_request ( path , form_with_code ( js_code , send_bundle ) , live_response )
1818 end
1919
2020 def upload_assets
@@ -34,43 +34,84 @@ def connection
3434 @connection ||= create_connection
3535 end
3636
37- def perform_request ( path , form )
38- available_retries = ReactOnRailsPro . configuration . renderer_request_retry_limit
39- retry_request = true
40- while retry_request
41- begin
42- response = connection . request ( Net ::HTTP ::Post ::Multipart . new ( path , form ) )
43- retry_request = false
44- rescue Timeout ::Error => e
45- # Testing timeout catching:
46- # https://github.com/shakacode/react_on_rails_pro/pull/136#issue-463421204
47- if available_retries . zero?
48- raise ReactOnRailsPro ::Error , "Time out error when getting the response on: #{ path } .\n " \
37+ # TODO: Fix Metrics/AbcSize
38+ # rubocop:disable Metrics/AbcSize
39+ def perform_request ( path , form , live_response = nil )
40+ if live_response
41+ date = Time . now . httpdate
42+
43+ live_response . headers [ "Content-Type" ] = "text/x-component"
44+ live_response . headers [ "Date" ] = date
45+ live_response . headers [ "Connection" ] = "keep-alive"
46+ live_response . headers [ "Keep-Alive" ] = "timeout=5"
47+ live_response . headers [ "Last-Modified" ] = date
48+ end
49+
50+ response_code = nil
51+ response_body = ""
52+
53+ cache_key = Digest ::MD5 . hexdigest ( form [ "renderingRequest" ] )
54+ cached_response = Rails . cache . read ( cache_key )
55+
56+ if cached_response
57+ response_code = "200"
58+ response_body = cached_response
59+ live_response . status = 200
60+ live_response . stream . write ( response_body )
61+ else
62+ available_retries = ReactOnRailsPro . configuration . renderer_request_retry_limit
63+ retry_request = true
64+
65+ while retry_request
66+ begin
67+ connection . request ( Net ::HTTP ::Post ::Multipart . new ( path , form ) ) do |res |
68+ response_code = res . code
69+ if response_code == "200"
70+ if live_response
71+ live_response . status = res . code
72+ end
73+ res . read_body do |chunk |
74+ response_body += chunk
75+ if live_response
76+ live_response . stream . write ( chunk )
77+ end
78+ end
79+ Rails . cache . write ( cache_key , response_body )
80+ end
81+ end
82+ retry_request = false
83+ rescue Timeout ::Error => e
84+ # Testing timeout catching:
85+ # https://github.com/shakacode/react_on_rails_pro/pull/136#issue-463421204
86+ if available_retries . zero?
87+ raise ReactOnRailsPro ::Error , "Time out error when getting the response on: #{ path } .\n " \
88+ "Original error:\n #{ e } \n #{ e . backtrace } "
89+ end
90+ Rails . logger . info do
91+ "[ReactOnRailsPro] Timed out trying to connect to the Node Renderer. " \
92+ "Retrying #{ available_retries } more times..."
93+ end
94+ available_retries -= 1
95+ next
96+ rescue StandardError => e
97+ raise ReactOnRailsPro ::Error , "Can't connect to NodeRenderer renderer: #{ path } .\n " \
4998 "Original error:\n #{ e } \n #{ e . backtrace } "
5099 end
51- Rails . logger . info do
52- "[ReactOnRailsPro] Timed out trying to connect to the Node Renderer. " \
53- "Retrying #{ available_retries } more times..."
54- end
55- available_retries -= 1
56- next
57- rescue StandardError => e
58- raise ReactOnRailsPro ::Error , "Can't connect to NodeRenderer renderer: #{ path } .\n " \
59- "Original error:\n #{ e } \n #{ e . backtrace } "
60100 end
61101 end
62102
63103 Rails . logger . info { "[ReactOnRailsPro] Node Renderer responded" }
64104
65- case response . code
105+ case response_code
66106 when "412"
67107 # 412 is a protocol error, meaning the server and renderer are running incompatible versions
68108 # of React on Rails.
69- raise ReactOnRailsPro ::Error , response . body
109+ raise ReactOnRailsPro ::Error , response_body
70110 else
71- response
111+ OpenStruct . new ( code : response_code , body : response_body )
72112 end
73113 end
114+ # rubocop:enable Metrics/AbcSize
74115
75116 def form_with_code ( js_code , send_bundle )
76117 form = common_form_data
0 commit comments