Asynchroniczne PHP

Pytania i problemy
php
Szymoon202
Szymoon202

Cześć, mam pytanie. W aplikacji mam funkcję, która odczytuje dane z socketu i jeżeli coś się pojawi to funkcja zwraca to co się pojawiło. Wykorzystuje to while, więc zatrzymuje dalszy kod. Chciałbym to "wsadzić" w asynchroniczną funkcję, lecz wiem, że php oficjalnie tego nie wspiera. Znalazłem coś takiego: https://github.com/spatie/async. Użyłem, dodałem kod:

$pool ->add($socketmanager->readMessage()) ->then($app->runAction($output)) ->catch($app>log('APP_ERROR | pool_manager('.$exception.').'));

Niestety - nie działa. Dalszy kod po tej funkcji nie jest wykonywany a gdy w sockecie pojawi się wiadomość, to w konsoli pokazuje się błąd PHP Fatal error: Uncaught InvalidArgumentException: The process passed to Pool::add should be callable. .

Co mogę innego zrobić?

Edit: Może inaczej zadam pytanie. Nie potrafię zrozumieć działania tego, co wysłałem (spatie/async). Dodaję funkcję i jeżeli zostanie coś wykryte to jest to zwracane do 'then'? Nie wiem jak to napisać. Nie wiem też, jak to działa :/

Szymoon202
Szymoon202

Odrzuciłem myśl, żeby robić to asynchronicznie. Poszedłem w inną stronę,w ustawienia socketu. Ustawiłem timeout na 1 sekundę stream_set_timeout($this->runtime['socket'], 1); tylko teraz problem jest taki, że jeżeli co sekundę wykonywany jest odczyt, to $data = fread($this->runtime['socket'], 512); czasami nie zwróci tego, co jest w sockecie.

Problem rozwiązany, wystarczyło ustawić właśnie timeout na 1 sekundę a odczyt co 0.5 sekundy. ̶D̶z̶i̶ę̶k̶i̶ ̶w̶s̶z̶y̶s̶t̶k̶i̶m̶ ̶z̶a̶ ̶o̶d̶p̶o̶w̶i̶e̶d̶z̶i̶.̶

SystemZ
SystemZ Admin lvlup.pro

Generalnie czekanie X czasu zamiast zweryfikowanie czy coś faktycznie nastąpiło to proszenie się o race condition co często może powodować większą zawodność aplikacji. Z doświadczenia mogę powiedzieć że umieszczenie kilku takich w kodzie to bardzo efektowna bomba z opóźnionym zapłonem, jak wybuchnie to nie będziesz wiedział za co się złapać żeby to naprawić 😛

Odradzam async w PHP, to droga przez mękę. Do asynchronicznych działań sugeruję jednak użyć innych języków programowania aby zaoszczędzić włosów na głowie.

Mam też wrażenie że nie potrzebujesz asynca w ogóle, musiałbyś tylko zmienić kod "wyżej", nie podałeś za dużo szczegółów czy też przykładowego kodu gdzie to ma miejsce więc ciężko doradzić.

Tak czy inaczej większość moich problemów z odpaleniem tasków w PHP czy też innych językach rozwiązały kolejki zadań, mogę polecić RabbitMQ, może akurat pomoże Ci szybciej osiągnąć w kodzie to co chcesz: https://www.rabbitmq.com/tutorials/tutorial-one-php.html Rabbit'a możesz użyć na trzy metody, kolejka, pub/sub oraz RPC

system
system

Ten temat został automatycznie zamknięty 32 dni po ostatnim wpisie. Tworzenie nowych odpowiedzi nie jest już możliwe.