Skip to content

2. Swoole Structure

Albert Chen edited this page Sep 4, 2018 · 6 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 main 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 whole 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 an 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 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 the core concept of Laravel structure. It can be used for 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 a sandbox to prevent some common unexpected bugs.

Sandbox Container

All your requests will be processed in a sandbox of App Container. Any changes to Application class will not affect the initial Laravel application. Application bindings will also be resolved in every request. That means singleton instances only exist in the current 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', 'cookies',
'encrypter', 'hash', 'router', 'translator', 'url', 'log'

After v2.5.0, you can customize your pre-resolved list in pre_resolved in swoole_http.php config.

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

There's also a instances config for you to add customized instances you want to reset in each request.

'instances' => [
    'instanceA', 'instanceB'
],

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

You can’t perform that action at this time.