Skip to content

2. Swoole Structure

Albert Chen edited this page Apr 29, 2018 · 8 revisions

Swoole Structure

Swoole is designed for higher-level developers. Using this package doesn't require those knowledge bases but it's highly recommended to understand basic lifecycles of Laravel and Swoole.

This is the basic structure for Swoole. Basically there are few components you need to keep in mind:

  • Master Process: This is the original process when you execute your PHP script. It will fork a main reactor and a manager. It is the root process for the who application.
  • Main Reactor: Reactor in Swoole is multi-thread and totally asynchronous implemented with epoll in Linux Kernel or kqueue in OSX. Reactor is in charge of receiving connected requests and deliver to manager process. In simple words, its function is just like Nginx Server.
  • Manager: Manager process will fork multiple worker processes. When any worker terminates, it will automatically fork another worker process to keep accurate amount of worker numbers.
  • Worker: This is where you should really care about. All the requests(main logics) will be processed in worker.
  • Task Worker: Same function as worker process, but only for task delivery. Workers can deliver tasks to a task queue asynchronously. And task workers are in charge of consuming tasks from this queue.

Laravel application will exist in worker processes. Each Laravel application will be loaded and bootstrapped only one time when worker process starts up. That means Laravel can be stored and kept in memory. No more needs to load the whole Laravel every time you process from a request.

This is the key point why we can speed up Laravel but also the dangerous part which may cause strange problems. Container is core concept of Laravel structure. It can be used to application binding, singleton, resolving applications, dependency injections and more.

In the past we don't need to care about the usages of global properties, static class, singletons. Now it matters.

As what I said above, Laravel application will exist in the memory and only initialize at the first time. Any changes you did to Laravel will be kept unless you reset them by yourself.

For example, auth in Laravel is registered as singleton. Here is the partial code of SessionGaurd:

if (! is_null($this->user)) {
    return $this->user;
}

It looks pretty normal and reasonable for caching resolved user object. But in our case this is a fatal problem. That will cause you getting wrong user object after your first user resolving.

Any solutions? Yes, this package provides two options for solving this kind of problems.

Sandbox Mode

By default your request will be processed in a sandbox for Laravel. Any changes to Application class will not effect the initial Laravel application. Application bindings will also be resolved in every request. That means singleton only effect in one request, and will not interfere with other requests.

But some instances will be pre-resolved in the begining for unncessary repeated resolving:

'view', 'files', 'session', 'session.store', 'routes',
'db', 'db.factory', 'cache', 'cache.store', 'config',
'encrypter', 'hash', 'router', 'translator', 'url', 'log'

In every request, it will genrate a new sandbox for single request processing.

This still can not prevent modifying global and static variables. You should avoid using them in any case unless you know what you're doing.

Reset Mode

If you turn off sandbox mode. All your requests will share one Application class, but you can decide what instances you're going to reset on every request. This is for advanced developers who deeply understand Laravel structure.

There are three things you can control to reset:

  • Providers: These providers will be registerd and booted in every request.
  • Instances: Instances here will be cleaned in Application class.
  • Facades: Facades bindings here need to depend on what you set in instances.