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

В Kohana существует несколько адаптеров сессий:

  • Native : Хранение данных сессий на сервере.
  • Database : Хранение данных сессий в базе данных (необходим модуль Database).
  • Cookie : Хранение данных сессии локально (например в браузере).

Рассмотрим пример контроллера, который использует native сессии:

class Controller_Export extends Controller_Template
{
        public $auto_render = FALSE;
        public function action_create()
        {
                Session::instance()->set('process', 0);
                $total_loops = 40;
                for ($i = 0; $i <= $total_loops; $i++)
                {
                            $percent = ($i / $total_loops) * 100;
                            usleep(50000); // pretend to be working on something
                            Session::instance()->set('process', number_format($percent, 0, '', ''));
                }
        }
 
        public function action_process()
        {
                echo Session::instance()->get('process', 0);
        }
}

При запуске метода action_create, блокируются все методы использующие данные сессии. Например если метод выполняется 20 секунд, то в течении 20 секунд action_process не выдаст нам результат. Связано это, как подсказывают зарубежные товарищи с session-write-close.

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

Вторым же методом, выбранным мной, является использование database сессий.

Внимание! Для использования cессий БД должен быть подключен соотвествующий kohana модуль database, создана база данных и отредактированы настройки подключения APPPATH/config/database.php.
Для этого необходимо создать таблицу в нашей базе данных:

CREATE TABLE  `sessions` (
      `session_id` VARCHAR( 24 ) NOT NULL,
      `last_active` INT UNSIGNED NOT NULL,
      `contents` TEXT NOT NULL,
      PRIMARY KEY ( `session_id` ),
      INDEX ( `last_active` )
  ) ENGINE = INNODB ;

Использование данных сессии БД:

Session::instance('database')->set('key_name', 'value'); // Запись
$value = Session::instance('database')->get('key_name'); // Чтение

Для использования модулем Auth сессий БД необходимо сделать несколько действий.
Копируем файл /modules/auth/kohana/auth.php в /application/classes/kohana/auth.php (не забываем об иерархии приложения).

Заменяем

$this->_session = Session::instance();

На

$this->_session = Session::instance('database');

Более подбробная информация об использовании сессий и кук здесь. Cсылки на обсуждении в сообществе kohana в русскоязычном, в англоязычном.

Буду рад услышать ценные замечания, если я где-то наступил на грабли или изобрел велосипед. :)