Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Rails 4 ActionController::Live example not working with Apache + Passenger

I am attempting to get ready to move our environment to Rails 4 and working through all the issues. Regretfully we are currently on Centos 5.5 so there were some hurdles to jump through just to get Rails up and running. This included installing python 2.6 and node.js in order to get extjs working.

And now I am stuck. With a fresh rails 4.0.2 app I have simple ActionController::Live example working fine in development with Puma. But in production with Apache + Passenger it simply doesn't send the data back to the browser (Firefox)

production.rb has

config.allow_concurrency = true

Here is the HTML/JS in index.html.

<script>
jQuery(document).ready(function(){
   var source = new EventSource("/feed");
   source.addEventListener('update', function(e){
     console.log(e.data);
   });

});
</script>

Here is the controller:

class LiveController < ApplicationController
  include ActionController::Live
  respond_to :html
  def feed
    response.headers['Content-Type']      = 'text/event-stream'
    response.headers['X-Accel-Buffering'] = 'no'

    while true do 
      response.stream.write "id: 0\n"
      response.stream.write "event: update\n"
      data = {time: Time.now.to_s}.to_json
      response.stream.write "data: #{data}\n\n"
      sleep 2
    end
  end
end

I can see the request go out to the server in Firebug notice the spinner on /feed :

Firebug Request notice the spinner

Apache/Passenger Config has this:

LoadModule passenger_module /usr/local/ordernow/lib/ruby/gems/2.0.0/gems/passenger-4.0.27/buildout/apache2/mod_passenger.so
PassengerRoot /usr/local/ordernow/lib/ruby/gems/2.0.0/gems/passenger-4.0.27
PassengerDefaultRuby /usr/local/ordernow/bin/ruby
RailsAppSpawnerIdleTime 0
PassengerMinInstances 1

The Apache logs don't show anything. Like it never connects to the server. Another weird thing is that curl from the command line works:

     curl -k -i -H "Accept: text/event-stream" https://10.47.47.44:8446/feed
HTTP/1.1 200 OK
Date: Thu, 27 Mar 2014 16:52:52 GMT
Server: Apache/2.2.20 (Unix) mod_ssl/2.2.20 OpenSSL/1.0.0e Phusion_Passenger/4.0.27
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-UA-Compatible: chrome=1
X-Accel-Buffering: no
Cache-Control: no-cache
X-Request-Id: 46fca6bb-4c6a-49f4-b0d6-2cbc5f0a63a5
X-Runtime: 0.002065
X-Powered-By: Phusion Passenger 4.0.27
Set-Cookie: request_method=GET; path=/
Status: 200 OK
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/event-stream

id: 0
event: update
data: {"time":"2014-03-27 10:52:52 -0600"}

id: 0
event: update
data: {"time":"2014-03-27 10:52:54 -0600"}

I figure it must be something in Apache , but I am not sure.

like image 354
digidigo Avatar asked Mar 17 '14 03:03

digidigo


1 Answers

Okay I finally figured this out by a pile of googling that lead me to an indication that mod_deflate ( used for compressing responses to the browser ) will interfere with non-buffered responses like text/event-stream.

Looking at my httpd.conf I found this:

SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI \.(?:gif|jpg|png|ico|zip|gz)$ no-gzip

# Restrict compression to these MIME types
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css

# Level of compression (Highest 9 - Lowest 1)
DeflateCompressionLevel 9

SetOutputFilter DEFLATE turns on compression for all responses making the rest of the AddOutputFilterByType directives unnecessary. This was obviously a bug in the httpd.conf . I removed this line, and verified that compression was still working for html pages.

And now everything works great! As well as the dashing dashboard tool that I was trying to get going in the first place.

like image 96
digidigo Avatar answered Nov 15 '22 00:11

digidigo