We are using Sinatra and Sequel for a small API implementation. The problem we have however is that on every page request Sequel opens new connections to MySQL, and keeps them open till they timeout, or you restart Apache.
There's not a lot of documentation on how to reuse connections, so any help, explanations, and/or pointers in the right direction would help.
I wrapped the Sequel stuff in a tiny wrapper and reuse this wrapper, like this:
get '/api/:call' do
##api ||= SApi.new
##api.call(params[:call])
end
class SApi
def initialize
connect
end
def connect
#con = Sequel.connect("...")
end
def call(x)
#handle call using #con
end
end
Alternatively, you can call #con.disconnect once you're finished or call Sequel.connect using a block:
Sequel.connect("...") do |c|
# work with c
end #connection closed
We figured out what we were doing wrong. It was rather stupid, we initialized Sequel in a before filter in Sinatra.
So instead we do:
DB = Sequel.mysql("...")
Then we simply use the DB constant to use Sequel.
Related
I'm working on ROR 3 app . I have added the following observer but I dont see any output as expected in the console or log file ( i have tried in both development and production modes)
cmd : rails g observer auditor
models:
class AuditorObserver < ActiveRecord::Observer
observe :excel_file
def after_update(excel_file)
excel_file.logger.info('New contact added!')
AuditTrail.new(execl_file, "UPDATED")
puts "*******************"
logger.info "********************************************"
end
end
application.rb:
config.active_record.observers = :auditor_observer
What am I missing in here? When I change the database (thru Mysql workbench/command line) I don't see any of the above lines getting executed.. neither after_update/after_save. But after_save works if I'm executing a query thru the app itself and do #excel.save
How else are we supposed to update data in DB so that we see the observer working????
When you bypass activerecord by modifying the database directly, you naturally bypass all of the activerecord callbacks.
So the answer is to update the data through the application, or to use database triggers instead.
I am a ruby beginner and I have a question about how to use mysql with grape.
Do I have to call Mysql.new() everytime I want to use my database or is there a better way to do this?
I tried to make the new in initialize of my class API < Grape::API but it doesn't seem to work...
Any suggestion?
EDIT: Here is some code of something i did and that works fine, but i would like to improve this by not connecting to sql everytime if possible:
class API < Grape::API
before do
header "Access-Control-Allow-Origin", "*"
#db_co = Mysql.new("localhost", "root", "toto", "youfight_userapp")
end
resource :users do
get :toto do
result = #db_co.query("SELECT username FROM users WHERE id = 104")
result.fetch_row
end
end
end
I would strongly recommend you to use some kind of ORM. We ran into a lot of issues when we were trying to write ours API the way you are yours and in the end we switched to ORM. We choose datamapper, but there are lots of other choices. For example sequel seems to be quite solid.
I perodicially need to access a mysql database, my primary data store is mongo, which I access with mongoid. I want to know the best way to manage connections to mysql (with the mysql2 gem - 0.2.7) without using active record.
I current do the following ...
# In config/initializers/mysql.rb
class MySqlConnection
def self.client
#client ||= Mysql2::Client.new(host: ENV['mysql_host'],
username: ENV['mysql_username'],
password: ENV['mysql_password'],
database: ENV['mysql_database'])
end
end
and then I use connection, like so ...
rows_q = "SELECT * FROM amaizng_table WHERE great_column = '#{cool_value}' "
rows = ::MySqlConnection.client.query(rows_q)
And everything is working okay -- but I have a sneaking suspicion that I am doing something horribly wrong, and things are going to explode down the road.
Also Note, the application is hosted on heroku
Anyone know the best way to approach this?
Thanks!
Jonathan
why, just WHY would you get rid of ActiveRecord's awesomeness (or any other ORM, really) ?
class Amazing < ActiveRecord::Base
establish_connection :mysql_database
end
so simple it hurts. See this for more details.
I am encountering the 'mysql has gone away' error in Ruby after a certain amount of time that the script has been running.
I want to try to tell the mysql gem to auto-reconnect when the connection is lost.
My current code looks like the following:
def self.connect()
begin
if !##dbh.nil?
self.disconnect
end
##dbh = Mysql.real_connect(##server, ##user, ##pass, ##db)
puts "[+] Connected to the " + ##db + " database with user '" + ##user + "'"
rescue Mysql::Error => e
# log error
end
end
The following guide [0] says that the mysql gem has a 'reconnect' object variable, however, I am unsure of how to use it within my code.
How do I implement this option into the code above?
Thanks in advance,
Ryan
[0] http://www.tmtm.org/en/mysql/ruby/
EDIT ---
OK. I think I have figured it out.
I need to add ##dbh.reconnect = true after the ##dbh = Mysql.real_connect(##server, ##user, ##pass, ##db) line.
Note: According to a 'nice' chapy on IRC the mysql gem may not be the best Ruby gem to use.
If you're starting on a new project, the mysql2 gem is the way to go. It's an enormous improvement over the old version.
An attempt to Ruby-ize your example is:
def connect
begin
if (#dbh)
self.disconnect
end
#dbh = Mysql.real_connect(#server, #user, #pass, #db)
puts "[+] Connected to the #{#db} database with user '#{#user}'"
rescue Mysql::Error => e
# log error
end
end
The reason for using traditional # variables is you can use attr_accessor if you design your interface properly.
It's better to use a singleton instance than to wreck around with a singleton class. For instance:
class MyApp
def self.db
#db ||= Database.new
end
class Database
# Instance methods like initialize, connect, disconnect, etc.
end
end
You can use this like:
MyApp.db.connect
The advantage of using an instance of a class instead of a class directly is you can support more than one connection at a time.
We have a Rails application that is running in a MySQL master-slave set-up for a while now, using the master_slave_adapter plugin. Recently, there was a need for background processing of long running tasks. So we settled on DelayedJob.
DelayedJob's table/model uses the same master-slave adapter. And it keeps the slave connection alive by polling the table. But the master connection remains idle for long periods of time, closes overnight, and the next time someone activates a job this happens:
Mysql::Error: MySQL server has gone away: UPDATE `delayed_jobs` SET locked_by = null, locked_at = null WHERE (locked_by = 'delayed_job host:[snip] pid:20481')
I've heard bad things about using the reconnect option in my database.yml, because it allegedly doesn't set the connection character set after a reconnect, like it does on the first connection initialization.
What's the proper way to make this work?
FWIW, we now monkey patch Delayed::Job in the two places it matters. Here's the blob:
module Delayed
class Job < ActiveRecord::Base
class << self
def refresh_connections_for_delayed_job
# Do a cheap check to see if we're actually using master-slave.
if (c = self.connection).respond_to? :master_connection
c.master_connection.reconnect! unless c.master_connection.active?
end
end
def clear_locks_with_connection_refresh!(worker_name)
self.refresh_connections_for_delayed_job
self.clear_locks_without_connection_refresh!(worker_name)
end
alias_method_chain :clear_locks!, :connection_refresh
end
def lock_exclusively_with_connection_refresh!(max_run_time, worker)
self.class.refresh_connections_for_delayed_job
self.lock_exclusively_without_connection_refresh!(max_run_time, worker)
end
alias_method_chain :lock_exclusively!, :connection_refresh
end
end