Rails multi-tenancy, области видимости, переменные класса и безопасность потоков - PullRequest
2 голосов
/ 12 августа 2011

Короткая версия

Являются ли переменные класса поточно-ориентированными на время действия контроллера?

Длинная версия

Я пишу приложение на Rails 3, которое реализует мультитенантность с использованием единой схемы базы данных со столбцами tenant_id в каждой таблице, чтобы определить, кому принадлежат данные.

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

Несколько человек предложили добиться этого, всегда обращаясь к базе данных через экземпляр tenant, например ::

current_tenant.associate_collection.where(...)

и т.д.

Однако, поскольку многопользовательская аренда является архитектурной задачей (а не бизнес-сферой), я бы предпочел сохранить ее максимально прозрачной для модели, настроив ее глобально. Это также намного суше.

Я обнаружил, что могу сделать это, используя мультитенантный гем и вокруг_фильтров:

class ApplicationController
  around_filter do
    Multitenant.with_tenant current_tenant
      yield
    end
  end
end

Управляет default_scope соответствующих моделей, так что весь доступ к данным автоматически ограничивается текущим арендатором.

Это прекрасно работает при разработке, но у меня есть опасения по поводу безопасности потоков. Multitenant.with_tenant сохраняет ссылку current_tenant в переменной класса.

Вопрос в том, могу ли я рассчитывать на целостность этой переменной, пока действие контроллера находится в стеке? или она может быть повреждена другим запросом?

Кроме того, каков хороший источник общих проблем параллелизма в Rails?

1 Ответ

1 голос
/ 07 октября 2011

Это не вопрос длительности, и нет ничего особенного в контроллере, который делает его атомарной (непрерывной) последовательностью кода. Безопасность потоков - это понимание блокировок, синхронизации и планировщика потоков.

Я не думаю, что ваш вопрос даже специфичен для Rails в этом случае. В общем смысле безопасность потока достигается за счет блокировки данных во время записи и разблокировки их по окончании записи. Это очень похожие механизмы блокировки базы данных, если вы знакомы с ними.

Для хорошей ссылки, которая фокусируется на Ruby, я бы пошел сюда: http://www.rubycentral.com/pickaxe/tut_threads.html

Для получения дополнительной информации о концепции безопасности потоков (в конце концов, потоки выполняются на уровне операционной системы, так что больше о понимании того, как безопасность потоков работает в любой программе), я бы пошел сюда:

...