Skip to content

Latest commit

 

History

History
66 lines (39 loc) · 4.39 KB

swoole.md

File metadata and controls

66 lines (39 loc) · 4.39 KB

Swoole & Corrotinas

Agora que a gente já entendeu as vantagens da programação assíncrona e os modelos de assíncronia (concorrente e paralelo), podemos ver na prática como seria no PHP.

Como falamos anteriormente, o PHP é tradicionamente bloqueante, mas não significa que não suporte assíncronia em algumas de suas extensões de I/O.

Uma delas é a Streams essa extensão é parte do core do PHP e não requer nenhuma instalação.
Através da função stream_set_blocking é possível tornar o Resource de um stream não-bloqueante.

Isso já possíbilida algumas coisas, mas é muito low-level. Siginifica que é muito cru, tem poucas funcionalidades práticas no dia-a-dia, para saber se um stream já terminou, você teria que implementar seu próprio loop de eventos com a stream_select, por exemplo.

Ao contrário do que muita gente pensa, é legal saber que tem sim coisas nativas no PHP para I/O não-bloqueante e programação assíncrona.
Só que não são abstrações de alto-nível.

Por isso ferramentas como a Swoole surgiram.

Event-loop

E o que é esse event-loop afinal? Fazer I/O não-bloqueante já é uma grande façanha, mas não é o suficiente. Afinal, agora que as coisas estão assíncronas, não esperam terminar para o próximo acontecer, como saber quando terminou?

Operações de I/O em sistemas Unix (GNU/Linux e macOS) são literalmente arquivos, são chamados de File Descriptors. Esses arquivos representam uma operação de I/O no sistema operacional e são os responsáveis por conectar os dados que estão sendo transmitidos nessa operação.

O event-loop é como um monitor, ou agendador, que fica de olho nos file descriptors pra saber se eles já terminaram.

O Node.js tornou essa ideia popular, mas umas das principais implementações desse modelo é o Nginx.

Nginx

E foi dessa forma que o Nginx conseguiu resolver o problema C10K e se popularizar tanto mesmo com outras alternativas como o Apache HTTP.

E é utilizando este padrão de event-loop, que ficou conhecido como Reactor, que a Swoole consegue entregar tanta performance, como o Nginx fez na época.

Aliás, por causa desse nome que o padrão leva, existem alternativas como o ReactPHP: "React" de "Reactor".

Como a Swoole funciona?

A Swoole é uma extensão pra PHP escrita em C/C++ que implementa um event-loop próprio.

Exitem bibliotecas como a libuv e a libevent, que são bibliotecas em C/C++ para implementação de event-loops, o Node.js usa a libuv inclusive, mas a Swoole implementa seu event-loop na mão fazendo as chamadas de sistema (epoll no Linux e kqueue no macOS) diretamente. Isso traz um pouco mais de performance, já que não precisa lidar com abstrações, em contra partida, não funciona no Windows, mas com WSL2, ninguém tá ligando pra isso.

E essas tal de Corrotinas?

Ter I/O não-bloqueante não é suficiente e ter um event-loop acompanhando também não é só isso.

Agora que você tem um modelo de concorrência entre as chamadas de I/O, você precisa, de alguma forma, informar os usuários do seu event-loop que o I/O terminou. A forma mais trivial de fazer isso é com callbacks, é a forma que o Node.js e o ReactPHP escolheram, por exemplo.

Callbacks logo se tornaram um problema e por isso coisas como Promises foram inventadas, pra mitigar um pouco disso.

A Swoole escolheu Corrotinas (Coroutines)

Inspirada na Go, que tem as Goroutines, a Swoole escolheu usar como modelo para trabalhar concorrência as Coroutines.

Corrotinas são como threads do sistema operacional só que muito mais leves, por isso são chamadas as vezes de lightweight-threads ou green-threads ou virtual-threads, mas a característica para serem co-rotinas é fato de cooperarem entre si.

Elas são mais leves do que threads normais porque ao invés de serem gerenciadas pelo sistema operacional, elas são gerenciadas pela runtime/VM da linguagem, no caso, pela própria Swoole.

As operações de I/O que estiverem dentro de uma Corrotina não vão bloquear o processo.

E assim a gente tem nosso I/O não-bloqueante e o PHP assíncrono.