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.