Я думаю, что вопрос не указывает на реальную проблему, мне трудно сгладить ее точно и кратко.Как хорошо запоминать клиент подключения MySQL во внешнем модуле, используемом, например, Синатра?
У меня есть камень, который реализует т.е. MySQL-базы данных «запросы» (также вставки, обновления ...)
module DBGEM::Query
def self.client settings=DBGEM.settings
@@client ||= Mysql2::Client.new settings
end
def query_this
client.query(...)
end
def process_insert_that list_of_things
list_of_things.each do |thing|
# process
client.query(...)
end
end
Кроме того, этот драгоценный камень, используемый Синатра приложение сидит на запускающим веб-сервер, как пума ,
В Синатра-приложение теперь я могу
get '/path' do
happy = DBGEM::Query.query_this
# process happy
great = DBGEM::Query.process_insert_that 1..20
# go on
end
Мне нравится этот API и этот код должен открыть только одно соединение с базой данных.
Но, насколько я понял, потому что код в определении 'get' не является единственным, кто обращается к вещам DBGEM::Query
в то время, могут произойти странные вещи (через условия гонки, общее внутреннее состояние?).
Есть ли умный способ сохранить хороший синтаксис и совместное использование без создания шаблонного объекта (query = DBGEM::Query.new() #...
), обертывая материал в блок (DBGEM::Query.process do |query| #...
)?
Приведенный выше пример, очевидно, упрощен. Обработка синатры может быть более сложной, запросы, фактически выполняемые в объекте службы и т. Д. Кроме того, afaiu в среде веб-сервера forking, GC уничтожит client
(закрытие соединения - вот как реализуется mysql2).
Вы определяете финализатор на самом модуле, а не на экземплярах классов, которые включают в себя модель. Таким образом, почти уверен, что финализатор никогда не будет вызван. –
Также «странные вещи» означали, что единственный объект-клиент mysql2 лишь частично подходит для использования в потоках и может показывать условия гонки (включая перекрывающиеся транзакции, неполные или неожиданные результаты ...). Хотя сам объект mysql2 нацелен на то, чтобы быть потокобезопасным, я был бы очень осторожен. –
Когда он идет для финализатора, да, потому что переменная '@ @ client' живет до тех пор, пока объект модуля (а не объекты экземпляров), ссылка: The Well Grounded Rubyist, глава: 5. Объект по умолчанию (self), область видимости и видимость , – maicher