ФорумПрограммированиеPHP для идиотов → Актуальность и безопасность использования fastcgi_finish_request + локи

Актуальность и безопасность использования fastcgi_finish_request + локи

  • Абырвалг

    Сообщения: 6477 Репутация: N Группа: Джедаи

    Spritz 13 октября 2010 г. 4:56

    Давайте поговорим об этой плюшке, которую предоставляет нам php-fpm. Для каких целей можно использовать эту ф-цию а для каких лучше ее не трогать?

    Вот к примеру: для [abbr="garbage collector"]gc[/abbr] сессий я бы ее использовал. А вот для commit'а этих же сессий - нет. Сессии могут просто не успеть коммитнуться до того, как они потребуются в следующем запросе, это несколько опасно.


    Кроме того, хотелось бы что бы кто-то разуплил меня, в каких случаях нужно использовать локи [файлов].
  • adw0rd

    Сообщения: 22902 Репутация: N Группа: в ухо

    Spritz 13 октября 2010 г. 5:11, спустя 15 минут 17 секунд

    1. Я вижу такое применение http://highload.com.ua/index.php/2009/12/06/fastcgi_finish_request-asynchronous-requests/
    2. Локи файлов стоит использовать когда боишься что туда кто-то другой сможет записать в этот момент
    adw/0
  • Sinkler

    Сообщения: 9658 Репутация: N Группа: в ухо

    Spritz 13 октября 2010 г. 5:25, спустя 13 минут 15 секунд

    Я вижу такое применение http://highload.com.ua/index.php/2009/12/06/fastcgi_finish_request-asynchronous-requests/

    круто, спасибо
  • Абырвалг

    Сообщения: 6477 Репутация: N Группа: Джедаи

    Spritz 13 октября 2010 г. 5:25, спустя 31 секунду

    Я вижу такое применение http://highload.com.ua/index.php/2009/12/06/fastcgi_finish_request-asynchronous-requests/

    это самая попсовая статья по использованию этой ф-ции) Естественно мы же не будем в контроллере вызывать эту хрень. Как я предлагаю это:

    есть EventDispatcher, есть соответствующий Event "system.finish_request". Ими и пользуемся

    // controller
    $ed->on('system.finish_request', array($this, 'sendMail')); // подключаем listener

    // response class
    function_exist('fastcgi_finish_request') && fastcgi_finish_request(); // типа совместимость
    $ed->notify($ed->event('system.finish_request')); // делаем trigger нашего события


    вот только бы не запутаться во всех этих fastcgi_finish_request/__destruct/shutdown_function


    Локи файлов стоит использовать когда боишься что туда кто-то другой сможет записать в этот момент

    это понятно из описания локов, но не ясно, когда такие конкурирующие запросы возникают.

    два запроса коммитят сессии, причем данные, которые коммитятся различаются. Че делать? Лок вроде не спасет, все равно данные из одного запроса пойдут по пизде. Или такое возможно только теоретически?

  • adw0rd

    Сообщения: 22902 Репутация: N Группа: в ухо

    Spritz 13 октября 2010 г. 5:35, спустя 9 минут 38 секунд

    По поводу локов дай пример с кодом пожалуйста, трудно мне тебя понять
    adw/0
  • Абырвалг

    Сообщения: 6477 Репутация: N Группа: Джедаи

    Spritz 13 октября 2010 г. 5:48, спустя 12 минут 51 секунду

    class Session
    {
    /**
    *
    * @var Session_StorageAdapterInterface
    */
    protected $storage;

    /**
    *
    * @var Session_SerializerAdapterInterface
    */
    protected $serializer;

    /* … */

    public function commit()
    {
    $this->storage->write($this->id, $this->serializer->serialize($this->data));

    return $this;
    }

    public function __destruct()
    {
    $this->commit();
    }
    }


    class Session_StorageAdapter_File implements Session_StorageAdapterInterface
    {
    /* … */

    public function write($id, $data)
    {
    file_put_contents($this->getFile($id), $data);
    }

    protected function getFile($id)
    {
    return $this->options['dir'] . $id . '.' . $this->options['ext'];
    }
    }



    1. сделали запрос 1, открыли сессию, делаем что-то долгодумающее
    2. сделали запрос 2, открыли сессию
    3. запрос 2 добавил в сессию какие-то данные
    4. запрос 1 закончил свою долгоиграющую операцию, добавил данные в сессию (этих данных нет в запросе 2)
    5. запрос 1 сдох, делает коммит. Данных много, коммит будет долгий
    6. запрос 2 сдох, делает коммит, но он сука не идет, файл занят запросом 1
    7. запрос 1 закончил коммит, разлочили файл
    8. запрос 2 получил доступ к файлу, и перезаписал его. Таким образом мы проебали данные от 1 запроса
  • adw0rd

    Сообщения: 22902 Репутация: N Группа: в ухо

    Spritz 13 октября 2010 г. 6:03, спустя 15 минут 52 секунды


    7. запрос 1 закончил коммит, разлочили файл
    8. запрос 2 получил доступ к файлу, и перезаписал его. Таким образом мы проебали данные от 1 запроса


    Почему они пишут в один файл, если он перезаписывается? Может надо дописывать?
    adw/0
  • Абырвалг

    Сообщения: 6477 Репутация: N Группа: Джедаи

    Spritz 13 октября 2010 г. 6:11, спустя 7 минут 42 секунды

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

  • adw0rd

    Сообщения: 22902 Репутация: N Группа: в ухо

    Spritz 13 октября 2010 г. 6:49, спустя 37 минут 36 секунд

    пишут они в один файл, так как это сессия одного и того же пользователя, просто он одновременно хуйнул два запроса в разных вкладках.
    теперь понял {+++176+++}
    Думаю, что если я буду дописывать, то потом не смогу их десериализовать по-нормальному.
    почему? не вижу проблем
    adw/0
  • Абырвалг

    Сообщения: 6477 Репутация: N Группа: Джедаи

    Spritz 13 октября 2010 г. 9:51, спустя 3 часа 2 минуты 17 секунд

    <?php

    $data1 = array(
    &#39;ns1&#39; => array(
    &#39;key1&#39; => &#39;value 1&#39;,
    &#39;key2&#39; => &#39;value 2&#39;
    )
    );

    $data2 = array(
    &#39;ns2&#39; => array(
    &#39;key1&#39; => &#39;value 1&#39;,
    &#39;key2&#39; => &#39;value 2&#39;
    )
    );

    file_put_contents(&#39;file&#39;, serialize($data1));
    file_put_contents(&#39;file&#39;, serialize($data2), FILE_APPEND);

    var_dump(unserialize(file_get_contents(&#39;file&#39;)));


    php file.php
    array(1) {
    [&quot;ns1&quot;]=>
    array(2) {
    [&quot;key1&quot;]=>
    string(7) &quot;value 1&quot;
    [&quot;key2&quot;]=>
    string(7) &quot;value 2&quot;
    }
    }


    данные, которые были append&#39;ены не десериализовались. Кроме того, как ты себе это представляешь: при каждом запросе не перезаписываем файл а делаем ему append? да он же ахуенно вырастит тогда в размерах) {+++27+++} почему остальные не принимают участия в дискуссии?
  • Sinkler

    Сообщения: 9658 Репутация: N Группа: в ухо

    Spritz 13 октября 2010 г. 9:54, спустя 3 минуты 20 секунд

    я думаю, как бы fastcgi_finish_request к кейку приебать
  • phpdude

    Сообщения: 26617 Репутация: N Группа: в ухо

    Spritz 13 октября 2010 г. 10:37, спустя 42 минуты 50 секунд

    почему остальные не принимают участия в дискуссии?

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

    в нагруженных проектах НИКТО и НИКОГДА не шлет почту со СТРАНИЦ, ее кладут в очередь и рассылают &quot;менеджером рассылки почты&quot;.

    я неправ?

    тема гавно, функция баян, о чем рассуждать? я про эту функцию читал еще на заре фпм&#39;а
    Сапожник без сапог
  • Абырвалг

    Сообщения: 6477 Репутация: N Группа: Джедаи

    Spritz 13 октября 2010 г. 10:54, спустя 16 минут 26 секунд

    про очередь - прав. Но я же не для почты предлагаю использовать а для garbage collector&#39;а сессий. Хотя его тоже можно на крон повесить и отключить в скрипте
  • adw0rd

    Сообщения: 22902 Репутация: N Группа: в ухо

    Spritz 13 октября 2010 г. 12:55, спустя 2 часа 55 секунд


    file_put_contents(&#39;file&#39;, serialize($data1));
    file_put_contents(&#39;file&#39;, serialize($data2), FILE_APPEND);

    var_dump(unserialize(file_get_contents(&#39;file&#39;)));


    Типа ты сам не допер что надо на новую строку, а потом в цикле unserialize для кадлой строки сделать?

    foreach(file(&#39;file&#39;) as $f) {
    $d[] = unserialize($f);
    }
    {+++111+++} Да, везде по возможности делаю очередь, никогда не приходилось использовать fastcgi_finish_request..
    Ну еще Нигматулин говорит что лучше ее в конце всегда вызывать, что бы клиент сразу получил данные, а остальные тормозные действия продолжади выполнятся без задержек клиента
    adw/0
  • Абырвалг

    Сообщения: 6477 Репутация: N Группа: Джедаи

    Spritz 13 октября 2010 г. 12:57, спустя 2 минуты 33 секунды

    та не, это не вариант. Потом нужно будет в цикле делать array_merge, а массивы многомерные. Интересно$(&#39;auction_type&#39;), как родные сессии поведут себя в этом случае. Будет время - проверю

Пожалуйста, авторизуйтесь, чтобы написать комментарий!