Возможно ли прозрачно реализовать будущий шаблон для запросов ActiveRecord в Ruby 1.9?


Я работаю на существующем сайте Rails 2 с большой кодовой базой, которая недавно обновилась до Ruby 1.9.2 и mysql2 gem. Я заметил, что эта настройка позволяет не блокировать запросы к базе данных; вы можете сделать client.query(sql, :async => true), а затем вызвать client.async_result, который блокирует до завершения запроса.

Мне кажется, что мы могли бы повысить производительность, если бы все запросы ActiveRecord, возвращающие коллекцию, отклонялись до тех пор, пока метод не будет вызван в коллекции. например

@widgets = Widget.find(:all, :conditions=> conditions) #sends the query
do_some_stuff_that_doesn't_require_widgets
@widgets.each do #if the query hasn't completed yet, wait until it does, then populate @widgets with the result. Iterate through @widgets
...

Это это может быть сделано с помощью monkey-patching Base::find и связанных с ним методов для создания нового клиента базы данных, отправки запроса асинхронно, а затем немедленного возврата Делегатора или другого прокси-объекта, который при вызове любого метода вызовет client.async_result, создаст экземпляр результата с помощью ActiveRecord и делегирует метод этому. ActiveRecord ассоциативные прокси-объекты уже работают аналогично реализации ORM.

Я не могу найти никого, кто бы это сделал, хотя, кажется, это не вариант в любой версии из рельсов. Я пробовал реализовать его сам, и он работает в консоли (пока я добавляю ; 1 к строке, вызывающей все, чтобы to_s не вызывался в результате). Но он, похоже, сталкивается со всеми видами другой магии и создает различные проблемы.

Итак, это плохая идея по какой-то причине, о которой я не подумал? Если нет, то почему это не так, как ActiveRecord уже работает? Есть ли чистый способ сделать так, чтобы это произошло?
1 4

1 ответ:

Я подозреваю, что это так .метод async_result доступен не для всех драйверов баз данных; если нет, то он не может быть объединен в универсальные вызовы ActiveRecord.

Более переносимым способом повышения производительности при циклировании большого набора записей было бы использование find_each или find_in_batches. Я думаю, что они будут работать в rails 2.3, а также rails 3.х.http://guides.rubyonrails.org/active_record_querying.html#retrieving-multiple-objects-in-batches