Workery w CodeIgniter

Workery to bardzo poręczne rozwiązanie, które pozwala nam na przyspieszenie działania naszego serwisu. Wszystko przez to, że niektóre zadania mogą być przez nas oddelegowane do procesu, który działa w tle. Dzięki temu, użytkownik nie będzie musiał czekać np. aż faktycznie jakiś email zostanie wysłany. Wystarczy, że taki email zostanie zakolejkowany do wysłania. W ten sposób, nasze aplikacje mogą działać bardziej płynne – bez niepotrzebnego oczekiwania na dłuższe procesy.

Jakie czynności możemy oddelegować do Workera? Jest tego sporo. Najbardziej oczywiste, to wysyłanie maili lub prace związane z grafiką. Weźmy może na warsztat ten ostatni przykład. Kiedy użytkownik doda do naszego serwisu zdjęcie, chcemy wykonać szereg manipulacji: wykonać miniaturę, dodać znaki wodne i przeskalować główne zdjęcie. Sporo pracy i na pewno odbije się to na czasie oczekiwania. Właśnie w takich sytuacjach workery sprawdzają się idealnie.

Jeszcze innym przykładem, gdzie można wykorzystać workery, jest komunikacja pomiędzy rożnymi platformami. Załóżmy, że mamy aplikację w PHP, która ma wygenerować jakiś raport. Do tego raportu potrzebujemy zrzutu ekranu. W PHP wykonanie zrzutu ekranu jest raczej trudne, za to w PhantomJS wręcz przeciwnie. Możemy więc skorzystać z NodeJS i modułu dla PhantomJS. A do komunikacji (przekazywania i zwracania wyników), możemy posłużyć się właśnie workerem.

No dobra, jeśli wiemy już do jakich zadań mogą się nam przydać workery, to warto przejść do konkretów. Do dyspozycji mamy wiele rozwiązań m.in.:

Dla naszych potrzeb wykorzystamy Beanstalkd, bo… czemu nie – to bardzo lekkie, szybkie i mało zasobożerne rozwiązanie ;) Przejdziemy teraz do napisania prostej aplikacji, która pozwoli nam na przekazywanie i odczytywanie zadań dodanych do workera.

Tworzymy testowy projekt

Na początek musimy pobrać Beanstalkd, a później go uruchomić.

Jeśli serwer działa, to pora na kod, który pozwoli nam na korzystanie z tego wszystkiego. Zakładam, że w pliku konfiguracyjnym CodeIgniter’a mamy aktywowaną obsługę Composer’a (application/config/config.php). Jeśli tak, to teraz musimy się upewnić, że mamy do dyspozycji bibliotekę, która pomoże nam obsługiwać Beanstalkd. W tym celu wykonujemy polecenie z linii komend (będąc w głównym katalogu naszej aplikacji):

Skoro mamy już wymaganą bibliotekę, to możemy przejść dalej. Napiszemy teraz klasę (kontroler), która będzie odpowiedzialna za nasłuchiwanie zadań, które spływają do kolejki i dalej, na uruchamianiu określonych procesów.

Skoro mamy już klasę odpowiedzialną za nasłuchiwanie zadań, to pora na dodawanie zadań do kolejki. Jak dodawać zadania do kolejki? Zbudujemy sobie bardzo prostą klasę, żeby to sobie ułatwić (chociaż i bez tego można by się obejść).

Gotowe. Możemy więc spróbować przygotować jakiś przykładowy model, który będzie uruchamiany za pośrednictwem workera.

Stworzyliśmy więc model, który będzie tworzył plik tekstowy w katalogu cache. Ostatnim kropiem będzie stworzenie metody kontrolera, której uruchomienie spowoduje przekazanie zadania do kolejki.

Ok, mamy już wszystkie potrzebne elementy, aby przejść do testów. Pierwszą rzeczą jaką zrobimy, będzie uruchomienie naszego workera, tak aby mógł nasłuchiwać czy są jakieś zadania do wykonania. W tym celu z linii komend (będąc w głównym katalogu naszego projektu) wykonujemy polecenie:

Tym samym uruchomiliśmy Worker, który będzie nasłuchiwał zadań w kolejce „sample”. Następnym krokiem będzie uruchomienie metody send z kontrolera Sample. W tym celu możemy przejść do przeglądarki i wywołać ten adres, lub zrobić to za pośrednictwem linii komend (w nowym oknie). Ja skorzystam z tej ostatniej opcji:

Jeśli wrócimy do okna konsoli, w którym został uruchomiony worker, to zobaczymy, że zostało tam wykonane nasze zadanie, a w katalogu cache powinniśmy znaleźć nowo utworzony plik.

Podsumowanie

Na koniec kilka ważnych uwaga. Jeśli będziemy korzystać z bazy danych, to powinniśmy wewnątrz naszego workera dodać opcję ponownego połączenia się z bazą, ponieważ długo działający proces workera, na pewno takie połączenie straci przy dłuższej bezczynności. Tak więc, gdzieś przed załadowaniem modelu (ale w pętli while), musimy dodać
$this->db->reconnect();

Kolejna sprawa, to zmiany które nanosimy do naszego kodu. Jeśli wprowadzimy jakieś zmiany w pliku Sample_model, to zostaną one uwzględnione dopiero jeśli zresetujemy nasz worker (uruchomimy go ponownie). Do tego momentu wszystko będzie działać w oparciu o nasz „stary” kod. Warto o tym pamiętać, bo może to nam przysporzyć niezłego bólu głowy :)

Jeśli chcemy mieć wiele kolejek, np. jedna do obsługi maili, a druga do grafiki, to oczywiście dla każdej z nich musimy odpalić osobny worker.

I jeszcze jedno. Możemy sobie umilić pracę z Beanstald instalując Beanstalk Console – jest to interfejs w przeglądarce, który pozwala na podgląd całej kolejki zadań i ogólnie jej zarządzaniem. Czasami jest to bardzo przydatne – szczególnie w środowisku developerskim, pozwala na wygodniejsze testowanie tego co się dzieje.

I to by było na tyle. Mam nadzieję, że temat Wam się spodobał i przy którymś z projektów, będziecie mogli skorzystać z zawartych tu informacji.

Dodaj komentarz

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