On Thursday, March 6, 2014 9:06:18 PM UTC-8, François Beausoleil wrote:
>
> Hi all,
>
> How can I force a connection to be disconnected? I'm running a Padrino 
> application (very similar to Sinatra) and use code similar to the following:
>
> attr_reader :db
>
> before do
>   options = {
>     test: true,
>     max_connections: 1,
>     sslmode: "prefer",
>     logger: Padrino.logger,
>     user: user.username,
>     password: user.password}
>
>   Padrino.logger.debug "Connecting to #{user.dburl} as 
> #{user.username.inspect}"
>   Sequel.connect(user.dburl, options)
> end
>
> after do
>   db.disconnect if db
> end
>
> # in a controller
> get "/" do
>   db[:parties].count.to_s
> end
>

Assuming that the code written is exactly what is executed, I'm not sure 
how db is set to the Sequel connection.  I think it should be `@db = 
Sequel.connect(...)`, but that's just a guess.
 

>
> What I notice is that after each HTTP request, pg_stat_activity reports 
> one more open connection. The documentation for #disconnect specifically 
> say "Any connections currently in use will not be disconnected."
>

I've tested the following code with Sinatra and it works as expected (no 
new database connections per web request):

require 'sinatra'
require 'sequel'

before do
  @db = Sequel.connect('postgres:///?user=sequel_test')
end

after do
  @db.disconnect if @db
end

get "/" do
  @db.tables.inspect
end
 

> I've tried switching to the single threaded pool, but I still get a new 
> connection per HTTP request. If I pass test: false, I still get a new 
> connection because the controller issues database requests.
>
> I would like for the connection pool to completely disconnect all database 
> connections. Is there a way to enforce that?
>

I think you are going about this the wrong way.  Even in the code I wrote 
above (which successfully disconnects the database connections), you are 
going to be acquiring Sequel::Database objects in memory (they are stored 
in the Sequel::DATABASES array), so you still have a memory leak.  You 
could fix that by removing the connection from Sequel::DATABASES manually, 
but the better approach is to use a shared database object with the 
server_block and arbitrary_servers extensions in conjunction with a rack 
middleware.  Something like this (untested, for example purposes only):

require 'sinatra'
require 'sequel'

DB = Sequel.connect('postgres:///?user=sequel_test', max_connections: 1, 
sslmode: "prefer", :servers=>{})
DB.extension :server_block
DB.extension :arbitrary_servers

class ArbitraryServers
  def initialize(app)
    @app = app
  end

  def call(env)
    DB.with_server(:user=>user.username, :password=>user.password) do
      DB.synchronize do
        @app.call(env)
      end
    end
  end
end
use ArbitraryServers

get "/" do
  DB.tables.inspect
end

The only issue here is that user.username and user.password are probably 
not available in the rack middleware, so you'll need to find a way to 
determine that information from env.

Thanks,
Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to