Problem z sesjami, ajaxem i wolnym CI

Ostatnimi czasy zmienił mi się laptop. Co by tu nie mówić maszyna lekko 2x szybsza od mojej poprzedniej. Podczas reinstalacji środowiska wszystko przebiegało poprawnie, udało się uruchomić wszystko jak trzeba poza jednym projektem. Projekt ten nie wyróżniał się niczym specjalnym poza faktem, że strona główna zawierała dashboard z dużą ilością ajax’owych widgetów. Problem polegał na tym, że załadowanie widgetów zajmowało ponad 2 min odpowiedzi. Gdzie na serwerze produkcyjnym czas ten lekko przekraczał 10-20s – też dosyć długo, ponieważ na poprzednim laptopie wszystko ładowało się poniżej 1s.

Zaczyna się robić ciekawie – skąd rozbieżności. Zbadałem same zapytania ajaxowe – wyniki były zwracane prawie natychmiast, problem pojawiał się jedynie kiedy było ich wiele na raz. Czyli niska wydajność serwera ? Konkurencyjność zapytań ? Cieżko mi uwierzyć w to, że 2.6 GHz Intel Core i7, 16GB RAM i dysk SSD nie potrafią obsłużyć 6 zapytań na raz. Idąc dalej tym tropem uruchomiłem Xdebug i znalazłem winnego:

Szukając dalej (czyt Michał podrzucił mi słowo klucz) trafiłem na ten wpis w dokumentacji CI. Co się okazuje – mechanizm sesji w CI jest trochę dziwny. Wymyślono sobie własną funkcję zamykania dostępu do sesji i w zależności od sterownika, jest ona obsługiwana natywnie (flock dla plików) lub… trochę inaczej. Więc – jeśli sesja nie jest zwolniona, działa sobie pętla która próbuje np. 30 razy odczytać zmienną sesyjną a potem zdycha. Co za tym idzie wiele zapytań „na raz” powoduje zamknięcie dostępu do sesji, następne zapytanie dalej próbuje odczytać zmienną – wszystko się zapętla i spowalnia. Potem leci timeout, albo po czasie wszystko się ładuje.

Rozwiązania

Znalazłem kilka – jedno to użycie session_write_close jak nakazuje instrukcja, drugie to „zdesynchronizowanie” zapytań ajaxowych – nie jest to eleganckie i trochę mija się z celem, ale pozwala na spokojne zamknięcie i otwarcie sesji automatycznie. Najbardziej optymalne rozwiązanie które znalazłem to ograniczenie ładowania ilości widgetów tak długo jak nie są one potrzebne – verge.js

One thought on “Problem z sesjami, ajaxem i wolnym CI

  1. To pewnie dosyć oczywiste, ale dodam dla jasności, że session_write_close, trzeba stosować z umiarem/rozwagą. Po wywołaniu tej funkcji, żadne zmiany na sesjach nie będą zachowywane – więc trzeba się mieć na baczności – pół biedy jeśli wyłączymy sobie w ten sposób możliwość przekazywania powiadomień (flashdata), ale można się przypadkowo wpędzić w o wiele gorsze tarapaty, więc najlepiej stosować to rozwiązanie „punktowo” lub po wcześniejszym przejrzeniu swojego serwisu, dla konkretnych typów requestów.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *