Жизненный цикл

Жизненный цикл процесса

  • У каждого процесса длительный жизненный цикл
  • Каждый процесс работает независимо и не мешает другим
  • Каждый процесс может обрабатывать несколько запросов за свой жизненный цикл
  • При получении команды stop, reload, restart процесс завершает текущий жизненный цикл и выходит из работы

Совет
Каждый процесс работает независимо, что означает, что каждый процесс поддерживает свои ресурсы, переменные и экземпляры классов. Это означает, что каждый процесс имеет свое собственное соединение с базой данных, и некоторые синглтоны инициализируются в каждом процессе, что приводит к нескольким инициализациям в нескольких процессах.

Жизненный цикл запроса

  • Каждый запрос порождает объект $request
  • Объект $request удаляется после завершения обработки запроса

Жизненный цикл контроллера

  • Каждый контроллер инстанциируется только один раз на процесс, и множество процессов создают множество инстанций (исключение - повторное использование контроллера, см. Жизненный цикл контроллера)
  • Экземпляр контроллера разделяется между несколькими запросами в текущем процессе (исключение - повторное использование контроллера)
  • Жизненный цикл контроллера завершается после завершения процесса (исключение - повторное использование контроллера)

О жизненном цикле переменных

Webman разработан на основе PHP, поэтому он полностью следует механизму сборки мусора PHP. Временные переменные, созданные в бизнес-логике, включая экземпляры классов, созданные с помощью оператора new, автоматически освобождаются после завершения функции или метода, и не требуется ручное освобождение с помощью unset. Это означает, что разработка на Webman практически аналогична разработке на традиционных фреймворках. Например, в приведенном ниже примере экземпляр $foo будет автоматически освобожден после завершения метода index:

<?php

namespace app\controller;

use app\service\Foo;
use support\Request;

class IndexController
{
    public function index(Request $request)
    {
        $foo = new Foo(); // Здесь предполагается существование класса Foo
        return response($foo->sayHello());
    }
}

Если вы хотите, чтобы экземпляр класса был повторно использован, вы можете сохранить класс в статическом свойстве класса или в свойстве объектов с длительным жизненным циклом (например, в контроллере), или использовать метод get контейнера для инициализации экземпляра класса, например:

<?php

namespace app\controller;

use app\service\Foo;
use support\Container;
use support\Request;

class IndexController
{
    public function index(Request $request)
    {
        $foo = Container::get(Foo::class);
        return response($foo->sayHello());
    }
}

Метод Container::get() используется для создания и сохранения экземпляра класса, и при повторном вызове с теми же параметрами он вернет ранее созданный экземпляр класса.

Обратите внимание
Container::get() может инициализировать только экземпляры без параметров конструктора. Container::make() может создавать экземпляры класса с параметрами конструктора, но в отличие от Container::get(), Container::make() не будет повторно использовать экземпляр, поэтому даже с теми же параметрами Container::make() всегда возвращает новый экземпляр.

Об утечках памяти

В большинстве случаев наш бизнес-код не вызывает утечки памяти (вероятнее всего, пользователи будут редко сообщать о возникновении утечек памяти); нам просто нужно немного следить за длинными массивами данных. Рассмотрим следующий пример:

<?php
namespace app\controller;

use support\Request;

class FooController
{
    // Свойство массива
    public $data = [];

    public function index(Request $request)
    {
        $this->data[] = time();
        return response('hello index');
    }

    public function hello(Request $request)
    {
        return response('hello webman');
    }
}

Контроллер по умолчанию имеет длительный жизненный цикл (исключение - повторное использование контроллера), и свойство массива $data этого контроллера также имеет длительный жизненный цикл. С увеличением количества элементов массива $data при каждом запросе foo/index, количество элементов в массиве $data увеличивается, что приводит к утечке памяти.

Дополнительную информацию см. в разделе Memory Leak