Szymoon202 | 2021-02-17 10:25:43 UTC | #1
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(‘APPERROR | poolmanager(‘.$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 | 2018-12-16 09:58:38 UTC | #2
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 | 2018-12-16 13:35:31 UTC | #3
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ć :stuckouttongue:
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 | 2019-01-17 13:43:31 UTC | #4
Ten temat został automatycznie zamknięty 32 dni po ostatnim wpisie. Tworzenie nowych odpowiedzi nie jest już możliwe.