Download the PHP package shasoft/batch without Composer
On this page you can find all versions of the php package shasoft/batch. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download shasoft/batch
More information about shasoft/batch
Files in shasoft/batch
Informations about the package batch
Группировка вызовов функций через обещания
Базовый функционал
Самое очевидное применение группировки вызовов - решение проблемы N+1 запросов. Данная проблема возникает когда фреймворк доступа к данным выполняет N дополнительных SQL-запросов для получения тех же данных, которые можно получить при выполнении одного запроса. К примеру для получения данных имеются вызовы следующих функций, каждая из которых выполняет один SQL-запрос. При применении пакета 6 вызовов функций группируются в две группы по типу функции вызова. И в каждую группу попадают все аргументы вызова.
В результате вместо шести SQL-запросов будет выполнено всего два.
Для реализации алгоритма с картинки такой код:
Функция BatchManager::all
получает на вход список объектов BatchPromise, возвращаемых групповыми функциями и выполняется когда выполнятся ВСЕ обещания из переданного массива.
Цепочки вызовов
Как и все обещания в данном случае поддерживаются цепочки вызовов.
Обработка ошибок
Каждая функция (обещание) может генерировать ошибку. В отличии от обещаний в том же JavaScript я в своем пакете пошёл другим путем. Вместо указания отдельной функции для получения ошибки необходимо возвращать эту ошибку с помощью вызова BatchError:create()
. В качестве примера перепишем функцию getUser
.
При создании ошибки необходимо указать текст + (опционально) код ошибки. Также класс работы с ошибками содержит статические методы для удобной обработки ошибок.
Приоритизация
В нашем случае группы будут выполняться последовательно. Т.е. в каждый момент времени в списке групп будет только одна группа. В более сложной ситуации групп может быть несколько. И в этом случае важно в какой последовательности они будут выполняться.
Возьмем пример с картинки. Предположим у нас в очереди сразу две группы: getArticle и getUser. В зависимости от последовательности выполнения групп у нас будет выполнено разное количество SQL-запросов. При такой последовательности getArticle, getUser
2 запроса: getArticle, getUser. При такой - getUser, getArticle, getUser
3 запроса: getUser, getArticle, getUser.
В первом случае после выполнения группы getArticle будут добавлены вызовы в группу getUser, а потом она выполнится. Во втором случае выполняется группа getUser, а после выполнения группы getArticle будет создана ещё одна группа getUser. В функционале предусмотрен способ задания приоритизации с помощью расширенного создания обещания:
Теперь в независимости от того в какой очередности группы находятся в списке для выполнения, группа с пониженным приоритетом будет выполнена последней. Для более рациональной работы необходимо для групп, которые не создают других групп, указывать пониженный приоритет. Чтобы они выполнялись в последнюю очередь.
Кэширование
Дополнительная полезная возможность использования функций группировок вызовов - это кэширование результата работы. Для этого Все функции разделяются на несколько видов:
Функция без КЭШирования.
Это функция по-умолчанию. Значение функции не КЭШируется
Функция вида LifeTime - кэширование на время.
Самый простой вариант кэширования.
Функции вида Get/Put - кэширование до изменения значения.
Тип функции Get устанавливается в параметрах расширенного вызова + необходимо указать функции вида Put, от которых эта функция зависит. Если зависимостей нет, то кэширование выполняется навсегда. Если зависимости указаны, то значение кэшируется до изменения текущих значений.
Для работы кэширования необходимо установить объекты КЭШирования.
В качестве параметров можно указать либо объект интерфейса КЭШа CacheItemPoolInterface либо замыкание которое такой объект возвращает. Имеется два КЭШа
- Для сохранения значений функций вида Get (хранит значения результатов работы функций Get)
- Для сохранения значений функций вида Put (хранит значения зависимостей функций вида Put). Если указать только аргумент $cacheGet, то аргумент $cachePut будет автоматически установлен в то же значение.
Как работает кэширование вида Get/Put?
Описание шагов
(1) КЭШ Put и Get пустые
(2) Вызываем функцию fnPut(2,7)
в результате в КЭШ-е Put сохраняется значение 7
с ключом fnPut,2
.
(3) Вызываем функцию fnGet(2)
. Функция проверяет значение в КЕШе Get, не находит его и вызывает групповую функцию fnGet в аргументом 2, получает результат 14 и сохраняет в КЕШ полученный результат + зависимые значения.
(3а) Вызываем функцию fnGet(2)
. Функция проверяет значение в КЕШе Get по ключу fnGet,2
, находит его и получает значение 14. Также считывается список зависимостей и проверяется что все зависимости соответствуют значениям в КЭШе Put. В данном случае они соответствуют и возвращается значение 14. Т.е. значение берется из КЭШа и групповая функция не вызывается.
(4) Вызываем функцию fnPut(2,9)
в результате в КЭШ-е Put сохраняется значение 9
с ключом fnPut,2
.
(5) Вызываем функцию fnGet(2)
. Функция проверяет значение в КЕШе Get по ключу fnGet,2
, находит его и получает значение 14. Также считывается список зависимостей и проверяется что все зависимости соответствуют значениям в КЭШе Put. В данном случае они НЕ соответствуют (7!=9) и поэтому вызывается групповая функция которая возвращает значение 18. После сохраняет в КЕШ Get полученный результат + зависимые значения.
Режим работы с КЭШем
Групповая функция с кэшированием хороша, но иногда необходимо чтобы такая функция игнорировала значения в КЭШе и выполняла прямое чтение значения через групповую функцию. И такая возможность есть. Каждая функция возвращает объект BatchPromise содержащий метод setCacheMode, который позволяет установить следующий режим работы:
- BatchPromise::MODE_CACHE_OFF - отключить КЭШирование. Т.е. в независимости от типа функции она будет вызвана так как обычная функция. И результат её работы не будет сохранен в КЭШе.
- BatchPromise::MODE_CACHE_DIRECT - отключить КЭШирование, но сохранять изменения в КЭШ. Т.е. в независимости от типа функции она будет вызвана так как обычная функция. И результат её работы будет сохранен в КЭШе.
- BatchPromise::MODE_CACHE_ON - включить КЭШирование (значение по умолчанию). Т.е. функция работает в режиме КЭШирования - читает и сохраняет значения в КЭШ.