Короче говоря:
- Нет, Rails никогда не работает в среде без общего доступа.
- Будьте параноиком по поводу переменных класса и переменных экземпляра класса .
Более длинная версия:
Процессы Rails начинают свой жизненный цикл с загрузки платформы и приложения. Как правило, они будут запускать только один поток, который будет обрабатывать много запросов в течение срока его службы. Поэтому запросы будут отправляться строго последовательно .
Тем не менее, все классы сохраняются при разных запросах. Это означает, что любой объект, на который ссылаются ваши классы и метаклассы (например, переменные класса и переменные экземпляра класса) , будет совместно использоваться запросами. Это может укусить вас , например, если вы попытаетесь запоминать методы (@var ||= expensive_calculation
) в ваших class методах, ожидая, что они сохранятся только во время текущего запроса. В действительности, расчет будет выполняться только по первому запросу.
На первый взгляд может показаться целесообразным реализовать кэширование или другое поведение, которое зависит от постоянства запросов. Как правило, это не так. Это связано с тем, что в большинстве стратегий развертывания используется несколько процессов Rails для противодействия их собственной однопоточной природе. Просто не круто блокировать все запросы во время ожидания медленного запроса к базе данных, поэтому самый простой выход - порождать больше процессов. Естественно, эти процессы не разделяют ничего (кроме некоторой памяти, которую вы не заметите). Это может вас укусить , если вы сохраняете вещи в своих переменных класса или переменных экземпляра класса во время запросов . Затем, так или иначе, иногда материал кажется присутствующим, а иногда, кажется, ушел. (В действительности, конечно, данные могут присутствовать или не присутствовать в некоторых процессах , а в других - отсутствовать).
Некоторые конфигурации развертывания (в частности, JRuby + Glassfish) на самом деле являются многопоточными.
Rails является потокобезопасным, поэтому он может справиться с этим. Но ваше приложение не может быть потокобезопасным. Все экземпляры контроллера выбрасываются после каждого запроса, но, как мы знаем, классы являются общими. Это может укусить вас , если вы передадите информацию в переменные класса или в переменные экземпляра класса. Если вы не используете методы синхронизации должным образом, вы вполне можете оказаться в аду состояния гонки.
В качестве примечания: Rails обычно запускается в однопоточных процессах, потому что реализация потоков в Ruby отстой. К счастью, в Ruby 1.9 дела обстоят немного лучше. И много лучше в JRuby.
Поскольку обе эти реализации Ruby набирают популярность, представляется вероятным, что многопоточные стратегии развертывания Rails также получат популярность и количество. Хорошей идеей будет написать приложение с учетом многопоточной обработки запросов.