title: Rails app hangs when there's a server sent event (SSE) that requires database actions
body: <p>I'm learning &amp; doing SSE for the first time in rails! My controller code:</p>
  
  <pre><code>  def update
      response.headers['Content-Type'] = 'text/event-stream'
      sse = SSE.new(response.stream, event: 'notice')
      begin
        User.listen_to_creation do |user_id|
          sse.write({id: user_id})
        end
      rescue ClientDisconnected
      ensure
        sse.close
      end
    end
  </code></pre>
  
  <p>Front end:</p>
  
  <pre><code>  var source = new EventSource('/site_update');
    source.addEventListener('notice', function(event) {
      var data = JSON.parse(event.data)
      console.log(data)
    });
  </code></pre>
  
  <p>Model pub/sub</p>
  
  <pre><code>class User
    after_commit :notify_creation, on: :create
  
    def notify_creation
        ActiveRecord::Base.connection_pool.with_connection do |connection|
          self.class.execute_query(connection, ["NOTIFY user_created, '?'", id])
        end
    end
  
    def self.listen_to_creation
      ActiveRecord::Base.connection_pool.with_connection do |connection|
        begin
          execute_query(connection, ["LISTEN user_created"])
          connection.raw_connection.wait_for_notify do |event, pid, id|
            yield id
          end
        ensure
          execute_query(connection, ["UNLISTEN user_created"])
        end
      end
    end
  
    def self.clean_sql(query)
      sanitize_sql(query)
    end
  
    private
  
    def self.execute_query(connection, query)
      sql = self.clean_sql(query)
      connection.execute(sql)
    end
  end
  </code></pre>
  
  <p>I've noticed that if I'm writing to SSE, something trivial like in a tutorial like... <code>sse.write({time_now: Time.now})</code>, everything works great. In command line, <code>CTRL+C</code> successfully shuts down the local server.</p>
  
  <p>However, whenever I need to write something that requires some kind of database action, for example when I'm doing a postgres pub/sub as in this <a href="https://www.twilio.com/blog/2016/06/real-time-rails-4-using-server-sent-events-with-authy-onetouch.html" rel="nofollow noreferrer">tutorial</a>, then <code>CTRL+C</code> doesn't shut down the local server, it's just stuck and hangs and requires me to manually kill the <code>PID</code>.</p>
  
  <p>On the actual spun up server, sometimes a page refresh will hang forever as well. Other times, it will throw a timeout error:</p>
  
  <pre><code>ActiveRecord::ConnectionTimeoutError (could not obtain a connection from the pool within 5.000 seconds (waited 5.001 seconds); all pooled connections were in use):
  </code></pre>
  
  <p>Unfortunately this issue persists in production as well, where i'm using Heroku. I just get lots of timeout errors. But I think I have Heroku properly configured, and also local settings... my understanding is I just need to have a sizable pool (I have <code>5</code>) to pull connections from and allow multiple threads. Below you'll find some config code.</p>
  
  <p><strong>THERE ARE NO ENV VARIABLES, DEFAULTS USED!</strong></p>
  
  <pre><code># config/database.yml
  default: &amp;default
    adapter: postgresql
    pool: &lt;%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %&gt;
    timeout: 5000
  
  development:
    &lt;&lt;: *default
    database: proper_development
  
  
  # config/puma.rb
  workers Integer(ENV['WEB_CONCURRENCY'] || 1)
  
  threads_count = Integer(ENV['MAX_THREADS'] || 5)
  threads threads_count, threads_count
  
  preload_app!
  
  rackup      DefaultRackup
  port        ENV['PORT']     || 3000
  environment ENV['RACK_ENV'] || 'development'
  
  on_worker_boot do
    # Worker specific setup for Rails 4.1+
    # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
    ActiveRecord::Base.establish_connection
  end
  </code></pre>
  
  <p>If it's helpful here's the output when I run <code>rails s</code></p>
  
  <pre><code>=&gt; Booting Puma
  =&gt; Rails 5.0.2 application starting in development on http://localhost:3000
  =&gt; Run `rails server -h` for more startup options
  Puma starting in single mode...
  * Version 4.3.3 (ruby 2.4.0-p0), codename: Mysterious Traveller
  * Min threads: 0, max threads: 16
  * Environment: development
  * Listening on tcp://127.0.0.1:3000
  * Listening on tcp://[::1]:3000
  Use Ctrl-C to stop
  </code></pre>