diff --git a/bin/mammatus-queue b/bin/mammatus-queue index 5dc35da..609b8ad 100644 --- a/bin/mammatus-queue +++ b/bin/mammatus-queue @@ -1,6 +1,8 @@ #!/usr/bin/php ContainerFactory::create()->get(App::class)->run($className))($className)); + exit(Boot::boot(App::class, new App\Queue($className))->value); })($argv[1]); diff --git a/composer.json b/composer.json index 2b39ebd..58aca1b 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "mammatus/life-cycle-events": "^2", "mammatus/queue-attributes": "dev-main", "mammatus/queue-contracts": "dev-main", - "psr/container": "^1.1.2", + "psr/container": "^1.1.2 || ^2", "psr/event-dispatcher": "^1.0", "psr/log": "^2", "queue-interop/queue-interop": "^0.8.1", @@ -27,6 +27,7 @@ "wyrihaximus/broadcast-contracts": "^1.3", "wyrihaximus/generative-composer-plugin-tooling": "^1", "wyrihaximus/monolog-factory": "^2", + "wyrihaximus/psr-3-callable-throwable-logger": "^2.3", "wyrihaximus/psr-3-context-logger": "^2.0", "wyrihaximus/simple-twig": "^2.2.1", "wyrihaximus/ticking-promise": "^3.1" @@ -68,6 +69,7 @@ "extra": { "class": "Mammatus\\Queue\\Composer\\Installer", "mammatus": { + "has-bootable": true, "queue": { "has-workers": true } @@ -86,11 +88,13 @@ "scripts": { "post-install-cmd": [ "composer normalize", - "composer update --lock --no-scripts" + "composer update --lock --no-scripts", + "make cs-fix" ], "post-update-cmd": [ "composer normalize", - "composer update --lock --no-scripts" + "composer update --lock --no-scripts", + "make cs-fix" ], "pre-autoload-dump": [ "Mammatus\\Queue\\Composer\\Installer::findActions" diff --git a/composer.lock b/composer.lock index 2241883..e54b841 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c47dd2ae897f349acc3227a60f4542d6", + "content-hash": "0d2cca42a0117bc810bb5f4b8f09cdb1", "packages": [ { "name": "bramus/ansi-php", @@ -104,16 +104,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.5.4", + "version": "1.5.5", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "bc0593537a463e55cadf45fd938d23b75095b7e1" + "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/bc0593537a463e55cadf45fd938d23b75095b7e1", - "reference": "bc0593537a463e55cadf45fd938d23b75095b7e1", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/08c50d5ec4c6ced7d0271d2862dec8c1033283e6", + "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6", "shasum": "" }, "require": { @@ -160,7 +160,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.5.4" + "source": "https://github.com/composer/ca-bundle/tree/1.5.5" }, "funding": [ { @@ -176,20 +176,20 @@ "type": "tidelift" } ], - "time": "2024-11-27T15:35:25+00:00" + "time": "2025-01-08T16:17:16+00:00" }, { "name": "composer/class-map-generator", - "version": "1.5.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/composer/class-map-generator.git", - "reference": "4b0a223cf5be7c9ee7e0ef1bc7db42b4a97c9915" + "reference": "ffe442c5974c44a9343e37a0abcb1cc37319f5b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/class-map-generator/zipball/4b0a223cf5be7c9ee7e0ef1bc7db42b4a97c9915", - "reference": "4b0a223cf5be7c9ee7e0ef1bc7db42b4a97c9915", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/ffe442c5974c44a9343e37a0abcb1cc37319f5b9", + "reference": "ffe442c5974c44a9343e37a0abcb1cc37319f5b9", "shasum": "" }, "require": { @@ -233,7 +233,7 @@ ], "support": { "issues": "https://github.com/composer/class-map-generator/issues", - "source": "https://github.com/composer/class-map-generator/tree/1.5.0" + "source": "https://github.com/composer/class-map-generator/tree/1.6.0" }, "funding": [ { @@ -249,20 +249,20 @@ "type": "tidelift" } ], - "time": "2024-11-25T16:11:06+00:00" + "time": "2025-02-05T10:05:34+00:00" }, { "name": "composer/composer", - "version": "2.8.4", + "version": "2.8.6", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "112e37d1dca22b3fdb81cf3524ab4994f47fdb8c" + "reference": "937c775a644bd7d2c3dfbb352747488463a6e673" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/112e37d1dca22b3fdb81cf3524ab4994f47fdb8c", - "reference": "112e37d1dca22b3fdb81cf3524ab4994f47fdb8c", + "url": "https://api.github.com/repos/composer/composer/zipball/937c775a644bd7d2c3dfbb352747488463a6e673", + "reference": "937c775a644bd7d2c3dfbb352747488463a6e673", "shasum": "" }, "require": { @@ -347,7 +347,7 @@ "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", "security": "https://github.com/composer/composer/security/policy", - "source": "https://github.com/composer/composer/tree/2.8.4" + "source": "https://github.com/composer/composer/tree/2.8.6" }, "funding": [ { @@ -363,7 +363,7 @@ "type": "tidelift" } ], - "time": "2024-12-11T10:57:47+00:00" + "time": "2025-02-25T12:03:50+00:00" }, { "name": "composer/metadata-minifier", @@ -1079,32 +1079,32 @@ }, { "name": "laravel/serializable-closure", - "version": "v1.3.7", + "version": "v2.0.3", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "4f48ade902b94323ca3be7646db16209ec76be3d" + "reference": "f379c13663245f7aa4512a7869f62eb14095f23f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/4f48ade902b94323ca3be7646db16209ec76be3d", - "reference": "4f48ade902b94323ca3be7646db16209ec76be3d", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f379c13663245f7aa4512a7869f62eb14095f23f", + "reference": "f379c13663245f7aa4512a7869f62eb14095f23f", "shasum": "" }, "require": { - "php": "^7.3|^8.0" + "php": "^8.1" }, "require-dev": { - "illuminate/support": "^8.0|^9.0|^10.0|^11.0", - "nesbot/carbon": "^2.61|^3.0", - "pestphp/pest": "^1.21.3", - "phpstan/phpstan": "^1.8.2", - "symfony/var-dumper": "^5.4.11|^6.2.0|^7.0.0" + "illuminate/support": "^10.0|^11.0|^12.0", + "nesbot/carbon": "^2.67|^3.0", + "pestphp/pest": "^2.36|^3.0", + "phpstan/phpstan": "^2.0", + "symfony/var-dumper": "^6.2.0|^7.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { @@ -1136,7 +1136,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2024-11-14T18:34:49+00:00" + "time": "2025-02-11T15:03:05+00:00" }, { "name": "lcobucci/clock", @@ -1263,12 +1263,12 @@ "source": { "type": "git", "url": "https://github.com/MammatusPHP/app.git", - "reference": "2726084f6d021a6389ba741ca9a8058e0e927af0" + "reference": "09673bc852be8d1acdbe60dd0f7e891101628b80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/MammatusPHP/app/zipball/2726084f6d021a6389ba741ca9a8058e0e927af0", - "reference": "2726084f6d021a6389ba741ca9a8058e0e927af0", + "url": "https://api.github.com/repos/MammatusPHP/app/zipball/09673bc852be8d1acdbe60dd0f7e891101628b80", + "reference": "09673bc852be8d1acdbe60dd0f7e891101628b80", "shasum": "" }, "require": { @@ -1280,10 +1280,12 @@ "php": "^8.2", "php-di-definitions/definitions-gatherer": "^1", "php-di/php-di": "^7", - "psr/container": "^1", + "psr/container": "^1 || ^2", "psr/event-dispatcher": "^1", "psr/log": "^2", + "react/async": "^4.3", "react/event-loop": "^1.5", + "react/promise": "^3.2", "thecodingmachine/safe": "^2", "wyrihaximus/broadcast": "^2.3.1", "wyrihaximus/broadcast-contracts": "^1.3", @@ -1357,7 +1359,7 @@ "type": "github" } ], - "time": "2024-04-27T08:09:13+00:00" + "time": "2025-03-03T23:19:45+00:00" }, { "name": "mammatus/kubernetes-attributes", @@ -1607,12 +1609,12 @@ "source": { "type": "git", "url": "https://github.com/MammatusPHP/queue-contracts.git", - "reference": "46d11da5cdbc17d74969a3a356459a65c0d595c0" + "reference": "58cfe7abd28052afcc13b14ea104162e46d8edd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/MammatusPHP/queue-contracts/zipball/46d11da5cdbc17d74969a3a356459a65c0d595c0", - "reference": "46d11da5cdbc17d74969a3a356459a65c0d595c0", + "url": "https://api.github.com/repos/MammatusPHP/queue-contracts/zipball/58cfe7abd28052afcc13b14ea104162e46d8edd2", + "reference": "58cfe7abd28052afcc13b14ea104162e46d8edd2", "shasum": "" }, "require": { @@ -1644,7 +1646,7 @@ "type": "github" } ], - "time": "2025-01-03T13:58:24+00:00" + "time": "2025-03-03T23:13:36+00:00" }, { "name": "mindplay/composer-locator", @@ -1961,16 +1963,16 @@ }, { "name": "php-di/invoker", - "version": "2.3.4", + "version": "2.3.6", "source": { "type": "git", "url": "https://github.com/PHP-DI/Invoker.git", - "reference": "33234b32dafa8eb69202f950a1fc92055ed76a86" + "reference": "59f15608528d8a8838d69b422a919fd6b16aa576" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/33234b32dafa8eb69202f950a1fc92055ed76a86", - "reference": "33234b32dafa8eb69202f950a1fc92055ed76a86", + "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/59f15608528d8a8838d69b422a919fd6b16aa576", + "reference": "59f15608528d8a8838d69b422a919fd6b16aa576", "shasum": "" }, "require": { @@ -2004,7 +2006,7 @@ ], "support": { "issues": "https://github.com/PHP-DI/Invoker/issues", - "source": "https://github.com/PHP-DI/Invoker/tree/2.3.4" + "source": "https://github.com/PHP-DI/Invoker/tree/2.3.6" }, "funding": [ { @@ -2012,24 +2014,24 @@ "type": "github" } ], - "time": "2023-09-08T09:24:21+00:00" + "time": "2025-01-17T12:49:27+00:00" }, { "name": "php-di/php-di", - "version": "7.0.7", + "version": "7.0.9", "source": { "type": "git", "url": "https://github.com/PHP-DI/PHP-DI.git", - "reference": "e87435e3c0e8f22977adc5af0d5cdcc467e15cf1" + "reference": "d8480267f5cf239650debba704f3ecd15b638cde" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/e87435e3c0e8f22977adc5af0d5cdcc467e15cf1", - "reference": "e87435e3c0e8f22977adc5af0d5cdcc467e15cf1", + "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/d8480267f5cf239650debba704f3ecd15b638cde", + "reference": "d8480267f5cf239650debba704f3ecd15b638cde", "shasum": "" }, "require": { - "laravel/serializable-closure": "^1.0", + "laravel/serializable-closure": "^1.0 || ^2.0", "php": ">=8.0", "php-di/invoker": "^2.0", "psr/container": "^1.1 || ^2.0" @@ -2041,8 +2043,8 @@ "friendsofphp/php-cs-fixer": "^3", "friendsofphp/proxy-manager-lts": "^1", "mnapoli/phpunit-easymock": "^1.3", - "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^4.6" + "phpunit/phpunit": "^9.6", + "vimeo/psalm": "^5|^6" }, "suggest": { "friendsofphp/proxy-manager-lts": "Install it if you want to use lazy injection (version ^1)" @@ -2073,7 +2075,7 @@ ], "support": { "issues": "https://github.com/PHP-DI/PHP-DI/issues", - "source": "https://github.com/PHP-DI/PHP-DI/tree/7.0.7" + "source": "https://github.com/PHP-DI/PHP-DI/tree/7.0.9" }, "funding": [ { @@ -2085,7 +2087,7 @@ "type": "tidelift" } ], - "time": "2024-07-21T15:55:45+00:00" + "time": "2025-02-28T12:46:35+00:00" }, { "name": "psr/clock", @@ -2137,22 +2139,27 @@ }, { "name": "psr/container", - "version": "1.1.2", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { "php": ">=7.4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -2179,9 +2186,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "time": "2021-11-05T16:50:12+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { "name": "psr/event-dispatcher", @@ -2285,16 +2292,16 @@ }, { "name": "queue-interop/queue-interop", - "version": "0.8.1", + "version": "0.8.2", "source": { "type": "git", "url": "https://github.com/queue-interop/queue-interop.git", - "reference": "117043fd38490f8b5516622cd4b697b33a89ce2b" + "reference": "752db86fee6d9fd11d2e34191afe212c64b96fa7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/queue-interop/queue-interop/zipball/117043fd38490f8b5516622cd4b697b33a89ce2b", - "reference": "117043fd38490f8b5516622cd4b697b33a89ce2b", + "url": "https://api.github.com/repos/queue-interop/queue-interop/zipball/752db86fee6d9fd11d2e34191afe212c64b96fa7", + "reference": "752db86fee6d9fd11d2e34191afe212c64b96fa7", "shasum": "" }, "require": { @@ -2330,9 +2337,9 @@ ], "support": { "issues": "https://github.com/queue-interop/queue-interop/issues", - "source": "https://github.com/queue-interop/queue-interop/tree/0.8.1" + "source": "https://github.com/queue-interop/queue-interop/tree/0.8.2" }, - "time": "2020-12-21T13:14:51+00:00" + "time": "2025-02-21T08:24:49+00:00" }, { "name": "react-parallel/object-proxy-attributes", @@ -2388,6 +2395,7 @@ "type": "github" } ], + "abandoned": true, "time": "2021-11-11T08:41:45+00:00" }, { @@ -2835,26 +2843,27 @@ }, { "name": "roave/signature", - "version": "1.8.0", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/Roave/Signature.git", - "reference": "f92ce20f82c9a1df3b50fc56fbdaeb82cf4c9c5b" + "reference": "f30f7107f08215cea86a6996613bf86c20db1bda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/Signature/zipball/f92ce20f82c9a1df3b50fc56fbdaeb82cf4c9c5b", - "reference": "f92ce20f82c9a1df3b50fc56fbdaeb82cf4c9c5b", + "url": "https://api.github.com/repos/Roave/Signature/zipball/f30f7107f08215cea86a6996613bf86c20db1bda", + "reference": "f30f7107f08215cea86a6996613bf86c20db1bda", "shasum": "" }, "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" + "php": "~8.2.0 || ~8.3.0 || ~8.4.0" }, "require-dev": { "doctrine/coding-standard": "^12.0.0", - "infection/infection": "^0.26.19", - "phpunit/phpunit": "^9.6.7", - "vimeo/psalm": "^5.9.0" + "phpunit/phpunit": "^11.5.6", + "psalm/plugin-phpunit": "^0.19.2", + "roave/infection-static-analysis-plugin": "^1.36.0", + "vimeo/psalm": "^6.4.0" }, "type": "library", "autoload": { @@ -2869,9 +2878,9 @@ "description": "Sign and verify stuff", "support": { "issues": "https://github.com/Roave/Signature/issues", - "source": "https://github.com/Roave/Signature/tree/1.8.0" + "source": "https://github.com/Roave/Signature/tree/1.9.0" }, - "time": "2023-11-25T00:11:29+00:00" + "time": "2025-02-05T15:43:11+00:00" }, { "name": "seld/jsonlint", @@ -3889,16 +3898,16 @@ }, { "name": "symfony/process", - "version": "v7.2.0", + "version": "v7.2.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" + "reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", - "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "url": "https://api.github.com/repos/symfony/process/zipball/d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf", + "reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf", "shasum": "" }, "require": { @@ -3930,7 +3939,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.2.0" + "source": "https://github.com/symfony/process/tree/v7.2.4" }, "funding": [ { @@ -3946,7 +3955,7 @@ "type": "tidelift" } ], - "time": "2024-11-06T14:24:19+00:00" + "time": "2025-02-05T08:33:46+00:00" }, { "name": "symfony/service-contracts", @@ -4259,24 +4268,23 @@ }, { "name": "twig/twig", - "version": "v3.18.0", + "version": "v3.20.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50" + "reference": "3468920399451a384bef53cf7996965f7cd40183" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50", - "reference": "acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3468920399451a384bef53cf7996965f7cd40183", + "reference": "3468920399451a384bef53cf7996965f7cd40183", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1.0", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php81": "^1.29" + "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { "phpstan/phpstan": "^2.0", @@ -4323,7 +4331,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.18.0" + "source": "https://github.com/twigphp/Twig/tree/v3.20.0" }, "funding": [ { @@ -4335,20 +4343,20 @@ "type": "tidelift" } ], - "time": "2024-12-29T10:51:50+00:00" + "time": "2025-02-13T08:34:43+00:00" }, { "name": "wyrihaximus/broadcast", - "version": "2.4.0", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/WyriHaximus/php-broadcast.git", - "reference": "42ff5c3b640d9e42715da2db75397cfe291bad5c" + "reference": "0b95a37d56997525261293c04fb047b8dc3660bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WyriHaximus/php-broadcast/zipball/42ff5c3b640d9e42715da2db75397cfe291bad5c", - "reference": "42ff5c3b640d9e42715da2db75397cfe291bad5c", + "url": "https://api.github.com/repos/WyriHaximus/php-broadcast/zipball/0b95a37d56997525261293c04fb047b8dc3660bf", + "reference": "0b95a37d56997525261293c04fb047b8dc3660bf", "shasum": "" }, "require": { @@ -4391,7 +4399,7 @@ "description": "✨ Statically on composer install/update compiled (async) event dispatcher", "support": { "issues": "https://github.com/WyriHaximus/php-broadcast/issues", - "source": "https://github.com/WyriHaximus/php-broadcast/tree/2.4.0" + "source": "https://github.com/WyriHaximus/php-broadcast/tree/2.5.0" }, "funding": [ { @@ -4399,7 +4407,7 @@ "type": "github" } ], - "time": "2024-10-10T13:18:40+00:00" + "time": "2025-01-06T13:26:16+00:00" }, { "name": "wyrihaximus/broadcast-contracts", @@ -4921,6 +4929,58 @@ ], "time": "2023-08-10T06:52:26+00:00" }, + { + "name": "wyrihaximus/psr-3-callable-throwable-logger", + "version": "2.3.1", + "source": { + "type": "git", + "url": "https://github.com/WyriHaximus/php-psr-3-callable-throwable-logger.git", + "reference": "3e58cabf93c88ebf4231fa2a32859ec8617883f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/WyriHaximus/php-psr-3-callable-throwable-logger/zipball/3e58cabf93c88ebf4231fa2a32859ec8617883f8", + "reference": "3e58cabf93c88ebf4231fa2a32859ec8617883f8", + "shasum": "" + }, + "require": { + "php": "^8 || ^7.4.7", + "psr/log": "^3 || ^2 || ^1", + "thecodingmachine/safe": "^2 || ^1.0 || ^0.1.16" + }, + "require-dev": { + "wyrihaximus/psr-3-utilities": "^1.0", + "wyrihaximus/test-utilities": "^5 || ^3.7.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "WyriHaximus\\PSR3\\CallableThrowableLogger\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Cees-Jan Kiewiet", + "email": "ceesjank@gmail.com" + } + ], + "description": "callable throwable decorator around a PSR-3 logger (to be used with react/promise and reactivex/rxphp)", + "support": { + "issues": "https://github.com/WyriHaximus/php-psr-3-callable-throwable-logger/issues", + "source": "https://github.com/WyriHaximus/php-psr-3-callable-throwable-logger/tree/2.3.1" + }, + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + } + ], + "time": "2023-01-14T19:24:38+00:00" + }, { "name": "wyrihaximus/psr-3-context-logger", "version": "2.0.0", @@ -5586,16 +5646,16 @@ }, { "name": "brick/math", - "version": "0.12.1", + "version": "0.12.3", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "f510c0a40911935b77b86859eb5223d58d660df1" + "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1", - "reference": "f510c0a40911935b77b86859eb5223d58d660df1", + "url": "https://api.github.com/repos/brick/math/zipball/866551da34e9a618e64a819ee1e01c20d8a588ba", + "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba", "shasum": "" }, "require": { @@ -5604,7 +5664,7 @@ "require-dev": { "php-coveralls/php-coveralls": "^2.2", "phpunit/phpunit": "^10.1", - "vimeo/psalm": "5.16.0" + "vimeo/psalm": "6.8.8" }, "type": "library", "autoload": { @@ -5634,7 +5694,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.12.1" + "source": "https://github.com/brick/math/tree/0.12.3" }, "funding": [ { @@ -5642,7 +5702,7 @@ "type": "github" } ], - "time": "2023-11-29T23:19:16+00:00" + "time": "2025-02-28T13:11:00+00:00" }, { "name": "bunny/bunny", @@ -5650,12 +5710,12 @@ "source": { "type": "git", "url": "https://github.com/jakubkulhan/bunny.git", - "reference": "27c794e951dfc10f89aa06a40d63a9278125ac90" + "reference": "c05d3aa8f1ef69b754b77f26794a39e13e7f7637" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jakubkulhan/bunny/zipball/27c794e951dfc10f89aa06a40d63a9278125ac90", - "reference": "27c794e951dfc10f89aa06a40d63a9278125ac90", + "url": "https://api.github.com/repos/jakubkulhan/bunny/zipball/c05d3aa8f1ef69b754b77f26794a39e13e7f7637", + "reference": "c05d3aa8f1ef69b754b77f26794a39e13e7f7637", "shasum": "" }, "require": { @@ -5715,7 +5775,7 @@ "issues": "https://github.com/jakubkulhan/bunny/issues", "source": "https://github.com/jakubkulhan/bunny/tree/0.6.x" }, - "time": "2024-12-24T09:12:18+00:00" + "time": "2025-02-20T10:49:46+00:00" }, { "name": "colinodell/json5", @@ -6645,16 +6705,16 @@ }, { "name": "ergebnis/phpstan-rules", - "version": "2.5.0", + "version": "2.5.2", "source": { "type": "git", "url": "https://github.com/ergebnis/phpstan-rules.git", - "reference": "ffbc24d0d7e7b0d2b45f524753c20d83a83f66de" + "reference": "2754afbaf4f31ec82aab1cc0e2fdd68130a974c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/phpstan-rules/zipball/ffbc24d0d7e7b0d2b45f524753c20d83a83f66de", - "reference": "ffbc24d0d7e7b0d2b45f524753c20d83a83f66de", + "url": "https://api.github.com/repos/ergebnis/phpstan-rules/zipball/2754afbaf4f31ec82aab1cc0e2fdd68130a974c8", + "reference": "2754afbaf4f31ec82aab1cc0e2fdd68130a974c8", "shasum": "" }, "require": { @@ -6664,16 +6724,18 @@ }, "require-dev": { "doctrine/orm": "^2.20.0 || ^3.3.0", - "ergebnis/composer-normalize": "^2.44.0", + "ergebnis/composer-normalize": "^2.45.0", "ergebnis/license": "^2.6.0", "ergebnis/php-cs-fixer-config": "^6.39.0", "ergebnis/phpunit-slow-test-detector": "^2.17.0", "nette/di": "^3.1.10", "nikic/php-parser": "^4.19.4", + "phpstan/extension-installer": "^1.4.3", "phpstan/phpstan-deprecation-rules": "^1.2.1", "phpstan/phpstan-strict-rules": "^1.6.1", "phpunit/phpunit": "^9.6.21", "psr/container": "^2.0.2", + "symfony/finder": "^5.4.45", "symfony/process": "^5.4.47" }, "type": "phpstan-extension", @@ -6711,30 +6773,30 @@ "security": "https://github.com/ergebnis/phpstan-rules/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/phpstan-rules" }, - "time": "2024-12-01T16:44:41+00:00" + "time": "2025-01-08T09:28:54+00:00" }, { "name": "ergebnis/phpunit-slow-test-detector", - "version": "2.17.0", + "version": "2.19.0", "source": { "type": "git", "url": "https://github.com/ergebnis/phpunit-slow-test-detector.git", - "reference": "671ea2ba0669917f7e98b54e4188e1c1ebf6e29d" + "reference": "2f66ad7fcc468a5db03592a0c73a930e0c0eccce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/phpunit-slow-test-detector/zipball/671ea2ba0669917f7e98b54e4188e1c1ebf6e29d", - "reference": "671ea2ba0669917f7e98b54e4188e1c1ebf6e29d", + "url": "https://api.github.com/repos/ergebnis/phpunit-slow-test-detector/zipball/2f66ad7fcc468a5db03592a0c73a930e0c0eccce", + "reference": "2f66ad7fcc468a5db03592a0c73a930e0c0eccce", "shasum": "" }, "require": { "php": "~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", - "phpunit/phpunit": "^6.5.0 || ^7.5.0 || ^8.5.19 || ^9.0.0 || ^10.0.0 || ^11.0.0" + "phpunit/phpunit": "^6.5.0 || ^7.5.0 || ^8.5.19 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0" }, "require-dev": { - "ergebnis/composer-normalize": "^2.44.0", + "ergebnis/composer-normalize": "^2.45.0", "ergebnis/license": "^2.6.0", - "ergebnis/php-cs-fixer-config": "^6.38.0", + "ergebnis/php-cs-fixer-config": "^6.43.1", "fakerphp/faker": "~1.20.0", "phpstan/extension-installer": "^1.4.3", "phpstan/phpstan": "^1.12.11", @@ -6784,7 +6846,7 @@ "security": "https://github.com/ergebnis/phpunit-slow-test-detector/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/phpunit-slow-test-detector" }, - "time": "2024-11-25T08:54:52+00:00" + "time": "2025-02-23T15:25:48+00:00" }, { "name": "felixfbecker/advanced-json-rpc", @@ -6950,16 +7012,16 @@ }, { "name": "filp/whoops", - "version": "2.16.0", + "version": "2.17.0", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "befcdc0e5dce67252aa6322d82424be928214fa2" + "reference": "075bc0c26631110584175de6523ab3f1652eb28e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2", - "reference": "befcdc0e5dce67252aa6322d82424be928214fa2", + "url": "https://api.github.com/repos/filp/whoops/zipball/075bc0c26631110584175de6523ab3f1652eb28e", + "reference": "075bc0c26631110584175de6523ab3f1652eb28e", "shasum": "" }, "require": { @@ -7009,7 +7071,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.16.0" + "source": "https://github.com/filp/whoops/tree/2.17.0" }, "funding": [ { @@ -7017,7 +7079,7 @@ "type": "github" } ], - "time": "2024-09-25T12:00:00+00:00" + "time": "2025-01-25T12:00:00+00:00" }, { "name": "guzzlehttp/guzzle", @@ -7858,16 +7920,16 @@ }, { "name": "maglnet/composer-require-checker", - "version": "4.14.0", + "version": "4.15.0", "source": { "type": "git", "url": "https://github.com/maglnet/ComposerRequireChecker.git", - "reference": "b6d5acd89d0de1727c1188157fa99552c39d1dfb" + "reference": "5109aed7b4695e6d772c4e748030c92da69a7f81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maglnet/ComposerRequireChecker/zipball/b6d5acd89d0de1727c1188157fa99552c39d1dfb", - "reference": "b6d5acd89d0de1727c1188157fa99552c39d1dfb", + "url": "https://api.github.com/repos/maglnet/ComposerRequireChecker/zipball/5109aed7b4695e6d772c4e748030c92da69a7f81", + "reference": "5109aed7b4695e6d772c4e748030c92da69a7f81", "shasum": "" }, "require": { @@ -7883,11 +7945,11 @@ "doctrine/coding-standard": "^12.0.0", "ext-zend-opcache": "*", "phing/phing": "^2.17.4", - "phpstan/phpstan": "^1.12.10", - "phpunit/phpunit": "^10.5.38", + "phpstan/phpstan": "^1.12.16", + "phpunit/phpunit": "^10.5.41", "psalm/plugin-phpunit": "^0.19.0", "roave/infection-static-analysis-plugin": "^1.35.0", - "spatie/temporary-directory": "^2.2.1", + "spatie/temporary-directory": "^2.3.0", "vimeo/psalm": "^5.26.1" }, "bin": [ @@ -7933,9 +7995,9 @@ ], "support": { "issues": "https://github.com/maglnet/ComposerRequireChecker/issues", - "source": "https://github.com/maglnet/ComposerRequireChecker/tree/4.14.0" + "source": "https://github.com/maglnet/ComposerRequireChecker/tree/4.15.0" }, - "time": "2024-11-13T02:00:19+00:00" + "time": "2025-01-28T06:35:41+00:00" }, { "name": "marc-mabe/php-enum", @@ -8095,16 +8157,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.12.1", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" + "reference": "024473a478be9df5fdaca2c793f2232fe788e414" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", + "reference": "024473a478be9df5fdaca2c793f2232fe788e414", "shasum": "" }, "require": { @@ -8143,7 +8205,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" }, "funding": [ { @@ -8151,7 +8213,7 @@ "type": "tidelift" } ], - "time": "2024-11-08T17:47:46+00:00" + "time": "2025-02-12T12:17:51+00:00" }, { "name": "netresearch/jsonmapper", @@ -8939,32 +9001,33 @@ }, { "name": "ocramius/package-versions", - "version": "2.9.0", + "version": "2.10.0", "source": { "type": "git", "url": "https://github.com/Ocramius/PackageVersions.git", - "reference": "b3397b9b4578989929d3bc2602c26fe19f035095" + "reference": "b2181b8f0e2adeef0db76a209e1a69369d8abe6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/b3397b9b4578989929d3bc2602c26fe19f035095", - "reference": "b3397b9b4578989929d3bc2602c26fe19f035095", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/b2181b8f0e2adeef0db76a209e1a69369d8abe6f", + "reference": "b2181b8f0e2adeef0db76a209e1a69369d8abe6f", "shasum": "" }, "require": { "composer-runtime-api": "^2.2.0", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "~8.2.0 || ~8.3.0 || ~8.4.0" }, "replace": { "composer/package-versions-deprecated": "*" }, "require-dev": { - "composer/composer": "^2.7.7", + "composer/composer": "^2.8.5", "doctrine/coding-standard": "^12.0.0", "ext-zip": "^1.15.0", - "phpunit/phpunit": "^9.6.20", - "roave/infection-static-analysis-plugin": "^1.35.0", - "vimeo/psalm": "^5.25.0" + "phpunit/phpunit": "^11.5.6", + "psalm/plugin-phpunit": "^0.19.2", + "roave/infection-static-analysis-plugin": "^1.36.0", + "vimeo/psalm": "^6.3.0" }, "type": "library", "autoload": { @@ -8985,7 +9048,7 @@ "description": "Provides efficient querying for installed package versions (no runtime IO)", "support": { "issues": "https://github.com/Ocramius/PackageVersions/issues", - "source": "https://github.com/Ocramius/PackageVersions/tree/2.9.0" + "source": "https://github.com/Ocramius/PackageVersions/tree/2.10.0" }, "funding": [ { @@ -8997,7 +9060,7 @@ "type": "tidelift" } ], - "time": "2024-08-04T10:04:51+00:00" + "time": "2025-02-05T12:31:16+00:00" }, { "name": "ondram/ci-detector", @@ -9079,22 +9142,22 @@ }, { "name": "orklah/psalm-insane-comparison", - "version": "v2.3.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/orklah/psalm-insane-comparison.git", - "reference": "d9e608e787e5ae1c994ae07095eea26029d6d0bd" + "reference": "b31246ecb3e78034e5f937ad1bfad007cf541375" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orklah/psalm-insane-comparison/zipball/d9e608e787e5ae1c994ae07095eea26029d6d0bd", - "reference": "d9e608e787e5ae1c994ae07095eea26029d6d0bd", + "url": "https://api.github.com/repos/orklah/psalm-insane-comparison/zipball/b31246ecb3e78034e5f937ad1bfad007cf541375", + "reference": "b31246ecb3e78034e5f937ad1bfad007cf541375", "shasum": "" }, "require": { "ext-simplexml": "*", "php": "^7.3|^8.0", - "vimeo/psalm": "^4|^5|dev-master" + "vimeo/psalm": "^4|^5|^6|dev-master" }, "require-dev": { "nikic/php-parser": "^4.0|^5" @@ -9127,9 +9190,9 @@ "description": "Detects possible insane comparison (\"string\" == 0) to help migrate to PHP8", "support": { "issues": "https://github.com/orklah/psalm-insane-comparison/issues", - "source": "https://github.com/orklah/psalm-insane-comparison/tree/v2.3.0" + "source": "https://github.com/orklah/psalm-insane-comparison/tree/v2.4.0" }, - "time": "2024-03-20T21:49:45+00:00" + "time": "2025-01-31T17:00:11+00:00" }, { "name": "phar-io/manifest", @@ -9772,16 +9835,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.14", + "version": "1.12.19", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "e73868f809e68fff33be961ad4946e2e43ec9e38" + "reference": "c42ba9bab7a940ed00092ecb1c77bad98896d789" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e73868f809e68fff33be961ad4946e2e43ec9e38", - "reference": "e73868f809e68fff33be961ad4946e2e43ec9e38", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c42ba9bab7a940ed00092ecb1c77bad98896d789", + "reference": "c42ba9bab7a940ed00092ecb1c77bad98896d789", "shasum": "" }, "require": { @@ -9826,7 +9889,7 @@ "type": "github" } ], - "time": "2024-12-31T07:26:13+00:00" + "time": "2025-02-19T15:42:21+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -9979,16 +10042,16 @@ }, { "name": "phpstan/phpstan-strict-rules", - "version": "1.6.1", + "version": "1.6.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "daeec748b53de80a97498462513066834ec28f8b" + "reference": "b564ca479e7e735f750aaac4935af965572a7845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/daeec748b53de80a97498462513066834ec28f8b", - "reference": "daeec748b53de80a97498462513066834ec28f8b", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/b564ca479e7e735f750aaac4935af965572a7845", + "reference": "b564ca479e7e735f750aaac4935af965572a7845", "shasum": "" }, "require": { @@ -10022,9 +10085,9 @@ "description": "Extra strict and opinionated rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", - "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.6.1" + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.6.2" }, - "time": "2024-09-20T14:04:44+00:00" + "time": "2025-01-19T13:02:24+00:00" }, { "name": "phpunit/php-code-coverage", @@ -10349,16 +10412,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.40", + "version": "10.5.45", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "e6ddda95af52f69c1e0c7b4f977cccb58048798c" + "reference": "bd68a781d8e30348bc297449f5234b3458267ae8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e6ddda95af52f69c1e0c7b4f977cccb58048798c", - "reference": "e6ddda95af52f69c1e0c7b4f977cccb58048798c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd68a781d8e30348bc297449f5234b3458267ae8", + "reference": "bd68a781d8e30348bc297449f5234b3458267ae8", "shasum": "" }, "require": { @@ -10430,7 +10493,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.40" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.45" }, "funding": [ { @@ -10446,28 +10509,28 @@ "type": "tidelift" } ], - "time": "2024-12-21T05:49:06+00:00" + "time": "2025-02-06T16:08:12+00:00" }, { "name": "psalm/plugin-mockery", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/psalm/psalm-plugin-mockery.git", - "reference": "876247d15f91df08240d00dac69c5135b6689283" + "reference": "4967cf80e32ba78d1e5a8f7f5363dfa62b16dfff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-mockery/zipball/876247d15f91df08240d00dac69c5135b6689283", - "reference": "876247d15f91df08240d00dac69c5135b6689283", + "url": "https://api.github.com/repos/psalm/psalm-plugin-mockery/zipball/4967cf80e32ba78d1e5a8f7f5363dfa62b16dfff", + "reference": "4967cf80e32ba78d1e5a8f7f5363dfa62b16dfff", "shasum": "" }, "require": { "composer/package-versions-deprecated": "^1.10", "composer/semver": "^1.4 || ^2.0 || ^3.0", "mockery/mockery": "^1.0", - "php": "~7.4 || ~8.0 || ~8.1 || ~8.2", - "vimeo/psalm": "dev-master || ^5.0@rc || ^5.0" + "php": ">=8.1", + "vimeo/psalm": "dev-master || ^5.0 || ^6" }, "require-dev": { "codeception/codeception": "^4.1.9", @@ -10501,9 +10564,9 @@ "description": "Psalm plugin for Mockery", "support": { "issues": "https://github.com/psalm/psalm-plugin-mockery/issues", - "source": "https://github.com/psalm/psalm-plugin-mockery/tree/1.1.0" + "source": "https://github.com/psalm/psalm-plugin-mockery/tree/1.2.0" }, - "time": "2022-11-25T07:16:18+00:00" + "time": "2025-01-26T11:02:29+00:00" }, { "name": "psalm/plugin-phpunit", @@ -10771,16 +10834,16 @@ }, { "name": "ramsey/collection", - "version": "2.0.0", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" + "reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", - "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "url": "https://api.github.com/repos/ramsey/collection/zipball/3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109", + "reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109", "shasum": "" }, "require": { @@ -10788,25 +10851,22 @@ }, "require-dev": { "captainhook/plugin-composer": "^5.3", - "ergebnis/composer-normalize": "^2.28.3", - "fakerphp/faker": "^1.21", + "ergebnis/composer-normalize": "^2.45", + "fakerphp/faker": "^1.24", "hamcrest/hamcrest-php": "^2.0", - "jangregor/phpstan-prophecy": "^1.0", - "mockery/mockery": "^1.5", + "jangregor/phpstan-prophecy": "^2.1", + "mockery/mockery": "^1.6", "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3", - "phpcsstandards/phpcsutils": "^1.0.0-rc1", - "phpspec/prophecy-phpunit": "^2.0", - "phpstan/extension-installer": "^1.2", - "phpstan/phpstan": "^1.9", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.5", - "psalm/plugin-mockery": "^1.1", - "psalm/plugin-phpunit": "^0.18.4", - "ramsey/coding-standard": "^2.0.3", - "ramsey/conventional-commits": "^1.3", - "vimeo/psalm": "^5.4" + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpspec/prophecy-phpunit": "^2.3", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5", + "ramsey/coding-standard": "^2.3", + "ramsey/conventional-commits": "^1.6", + "roave/security-advisories": "dev-latest" }, "type": "library", "extra": { @@ -10844,19 +10904,9 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/2.0.0" + "source": "https://github.com/ramsey/collection/tree/2.1.0" }, - "funding": [ - { - "url": "https://github.com/ramsey", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", - "type": "tidelift" - } - ], - "time": "2022-12-31T21:50:55+00:00" + "time": "2025-03-02T04:48:29+00:00" }, { "name": "ramsey/uuid", @@ -11259,16 +11309,16 @@ }, { "name": "revolt/event-loop", - "version": "v1.0.6", + "version": "v1.0.7", "source": { "type": "git", "url": "https://github.com/revoltphp/event-loop.git", - "reference": "25de49af7223ba039f64da4ae9a28ec2d10d0254" + "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/25de49af7223ba039f64da4ae9a28ec2d10d0254", - "reference": "25de49af7223ba039f64da4ae9a28ec2d10d0254", + "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/09bf1bf7f7f574453efe43044b06fafe12216eb3", + "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3", "shasum": "" }, "require": { @@ -11325,9 +11375,9 @@ ], "support": { "issues": "https://github.com/revoltphp/event-loop/issues", - "source": "https://github.com/revoltphp/event-loop/tree/v1.0.6" + "source": "https://github.com/revoltphp/event-loop/tree/v1.0.7" }, - "time": "2023-11-30T05:34:44+00:00" + "time": "2025-01-25T19:27:39+00:00" }, { "name": "roave/backward-compatibility-check", @@ -12628,16 +12678,16 @@ }, { "name": "spatie/phpunit-snapshot-assertions", - "version": "5.1.7", + "version": "5.1.8", "source": { "type": "git", "url": "https://github.com/spatie/phpunit-snapshot-assertions.git", - "reference": "5c7ae9d555c3b46bddd35f4e4bab9a6181aa1446" + "reference": "9cdaa6a197e8dba3e9ebda6f73ac6e0e6db143ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/phpunit-snapshot-assertions/zipball/5c7ae9d555c3b46bddd35f4e4bab9a6181aa1446", - "reference": "5c7ae9d555c3b46bddd35f4e4bab9a6181aa1446", + "url": "https://api.github.com/repos/spatie/phpunit-snapshot-assertions/zipball/9cdaa6a197e8dba3e9ebda6f73ac6e0e6db143ca", + "reference": "9cdaa6a197e8dba3e9ebda6f73ac6e0e6db143ca", "shasum": "" }, "require": { @@ -12646,7 +12696,7 @@ "ext-json": "*", "ext-libxml": "*", "php": "^8.1", - "phpunit/phpunit": "^10.0|^11.0", + "phpunit/phpunit": "^10.0|^11.0|^12.0", "symfony/property-access": "^5.2|^6.2|^7.0", "symfony/serializer": "^5.2|^6.2|^7.0", "symfony/yaml": "^5.2|^6.2|^7.0" @@ -12693,7 +12743,7 @@ ], "support": { "issues": "https://github.com/spatie/phpunit-snapshot-assertions/issues", - "source": "https://github.com/spatie/phpunit-snapshot-assertions/tree/5.1.7" + "source": "https://github.com/spatie/phpunit-snapshot-assertions/tree/5.1.8" }, "funding": [ { @@ -12701,20 +12751,20 @@ "type": "custom" } ], - "time": "2024-12-09T15:47:41+00:00" + "time": "2025-02-10T09:19:13+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.11.2", + "version": "3.11.3", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079" + "reference": "ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/1368f4a58c3c52114b86b1abe8f4098869cb0079", - "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10", + "reference": "ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10", "shasum": "" }, "require": { @@ -12779,22 +12829,26 @@ { "url": "https://opencollective.com/php_codesniffer", "type": "open_collective" + }, + { + "url": "https://thanks.dev/phpcsstandards", + "type": "thanks_dev" } ], - "time": "2024-12-11T16:04:26+00:00" + "time": "2025-01-23T17:04:15+00:00" }, { "name": "symfony/config", - "version": "v7.2.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "bcd3c4adf0144dee5011bb35454728c38adec055" + "reference": "7716594aaae91d9141be080240172a92ecca4d44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/bcd3c4adf0144dee5011bb35454728c38adec055", - "reference": "bcd3c4adf0144dee5011bb35454728c38adec055", + "url": "https://api.github.com/repos/symfony/config/zipball/7716594aaae91d9141be080240172a92ecca4d44", + "reference": "7716594aaae91d9141be080240172a92ecca4d44", "shasum": "" }, "require": { @@ -12840,7 +12894,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.2.0" + "source": "https://github.com/symfony/config/tree/v7.2.3" }, "funding": [ { @@ -12856,20 +12910,20 @@ "type": "tidelift" } ], - "time": "2024-11-04T11:36:24+00:00" + "time": "2025-01-22T12:07:01+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.2.0", + "version": "v7.2.4", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "a475747af1a1c98272a5471abc35f3da81197c5d" + "reference": "f0a1614cccb4b8431a97076f9debc08ddca321ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a475747af1a1c98272a5471abc35f3da81197c5d", - "reference": "a475747af1a1c98272a5471abc35f3da81197c5d", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f0a1614cccb4b8431a97076f9debc08ddca321ca", + "reference": "f0a1614cccb4b8431a97076f9debc08ddca321ca", "shasum": "" }, "require": { @@ -12920,7 +12974,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.2.0" + "source": "https://github.com/symfony/dependency-injection/tree/v7.2.4" }, "funding": [ { @@ -12936,7 +12990,7 @@ "type": "tidelift" } ], - "time": "2024-11-25T15:45:00+00:00" + "time": "2025-02-21T09:47:16+00:00" }, { "name": "symfony/polyfill-php83", @@ -13016,16 +13070,16 @@ }, { "name": "symfony/property-access", - "version": "v7.2.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "3ae42efba01e45aaedecf5c93c8d6a3ab3a82276" + "reference": "b28732e315d81fbec787f838034de7d6c9b2b902" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/3ae42efba01e45aaedecf5c93c8d6a3ab3a82276", - "reference": "3ae42efba01e45aaedecf5c93c8d6a3ab3a82276", + "url": "https://api.github.com/repos/symfony/property-access/zipball/b28732e315d81fbec787f838034de7d6c9b2b902", + "reference": "b28732e315d81fbec787f838034de7d6c9b2b902", "shasum": "" }, "require": { @@ -13072,7 +13126,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v7.2.0" + "source": "https://github.com/symfony/property-access/tree/v7.2.3" }, "funding": [ { @@ -13088,20 +13142,20 @@ "type": "tidelift" } ], - "time": "2024-09-26T12:28:35+00:00" + "time": "2025-01-17T10:56:55+00:00" }, { "name": "symfony/property-info", - "version": "v7.2.2", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "1dfeb0dac7a99f7b3be42db9ccc299c5a6483fcf" + "reference": "dedb118fd588a92f226b390250b384d25f4192fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/1dfeb0dac7a99f7b3be42db9ccc299c5a6483fcf", - "reference": "1dfeb0dac7a99f7b3be42db9ccc299c5a6483fcf", + "url": "https://api.github.com/repos/symfony/property-info/zipball/dedb118fd588a92f226b390250b384d25f4192fe", + "reference": "dedb118fd588a92f226b390250b384d25f4192fe", "shasum": "" }, "require": { @@ -13112,7 +13166,9 @@ "conflict": { "phpdocumentor/reflection-docblock": "<5.2", "phpdocumentor/type-resolver": "<1.5.1", - "symfony/dependency-injection": "<6.4" + "symfony/cache": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/serializer": "<6.4" }, "require-dev": { "phpdocumentor/reflection-docblock": "^5.2", @@ -13155,7 +13211,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v7.2.2" + "source": "https://github.com/symfony/property-info/tree/v7.2.3" }, "funding": [ { @@ -13171,20 +13227,20 @@ "type": "tidelift" } ], - "time": "2024-12-31T11:04:50+00:00" + "time": "2025-01-27T11:08:17+00:00" }, { "name": "symfony/serializer", - "version": "v7.2.0", + "version": "v7.2.4", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "3f5ed9f5e6c02e3853109190ba38408f5e1d2dd0" + "reference": "d3e6cd13f035e1061647f0144b5623a1e7e775ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/3f5ed9f5e6c02e3853109190ba38408f5e1d2dd0", - "reference": "3f5ed9f5e6c02e3853109190ba38408f5e1d2dd0", + "url": "https://api.github.com/repos/symfony/serializer/zipball/d3e6cd13f035e1061647f0144b5623a1e7e775ba", + "reference": "d3e6cd13f035e1061647f0144b5623a1e7e775ba", "shasum": "" }, "require": { @@ -13253,7 +13309,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v7.2.0" + "source": "https://github.com/symfony/serializer/tree/v7.2.4" }, "funding": [ { @@ -13269,20 +13325,20 @@ "type": "tidelift" } ], - "time": "2024-11-25T15:21:05+00:00" + "time": "2025-02-24T10:49:57+00:00" }, { "name": "symfony/stopwatch", - "version": "v7.2.2", + "version": "v7.2.4", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df" + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/e46690d5b9d7164a6d061cab1e8d46141b9f49df", - "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", "shasum": "" }, "require": { @@ -13315,7 +13371,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.2.2" + "source": "https://github.com/symfony/stopwatch/tree/v7.2.4" }, "funding": [ { @@ -13331,7 +13387,7 @@ "type": "tidelift" } ], - "time": "2024-12-18T14:28:33+00:00" + "time": "2025-02-24T10:49:57+00:00" }, { "name": "symfony/translation-contracts", @@ -13413,16 +13469,16 @@ }, { "name": "symfony/type-info", - "version": "v7.2.2", + "version": "v7.2.4", "source": { "type": "git", "url": "https://github.com/symfony/type-info.git", - "reference": "3b5a17470fff0034f25fd4287cbdaa0010d2f749" + "reference": "269344575181c326781382ed53f7262feae3c6a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/type-info/zipball/3b5a17470fff0034f25fd4287cbdaa0010d2f749", - "reference": "3b5a17470fff0034f25fd4287cbdaa0010d2f749", + "url": "https://api.github.com/repos/symfony/type-info/zipball/269344575181c326781382ed53f7262feae3c6a4", + "reference": "269344575181c326781382ed53f7262feae3c6a4", "shasum": "" }, "require": { @@ -13468,7 +13524,7 @@ "type" ], "support": { - "source": "https://github.com/symfony/type-info/tree/v7.2.2" + "source": "https://github.com/symfony/type-info/tree/v7.2.4" }, "funding": [ { @@ -13484,20 +13540,20 @@ "type": "tidelift" } ], - "time": "2024-12-20T13:38:37+00:00" + "time": "2025-02-25T15:19:41+00:00" }, { "name": "symfony/validator", - "version": "v7.2.2", + "version": "v7.2.4", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "5c01f00fed258a987ef35f0fefcc069f84111cb4" + "reference": "00936b34ef29d0e0e9a5340bbce6e7562092da56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/5c01f00fed258a987ef35f0fefcc069f84111cb4", - "reference": "5c01f00fed258a987ef35f0fefcc069f84111cb4", + "url": "https://api.github.com/repos/symfony/validator/zipball/00936b34ef29d0e0e9a5340bbce6e7562092da56", + "reference": "00936b34ef29d0e0e9a5340bbce6e7562092da56", "shasum": "" }, "require": { @@ -13565,7 +13621,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v7.2.2" + "source": "https://github.com/symfony/validator/tree/v7.2.4" }, "funding": [ { @@ -13581,20 +13637,20 @@ "type": "tidelift" } ], - "time": "2024-12-30T18:35:15+00:00" + "time": "2025-02-21T09:47:16+00:00" }, { "name": "symfony/var-exporter", - "version": "v7.2.0", + "version": "v7.2.4", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d" + "reference": "4ede73aa7a73d81506002d2caadbbdad1ef5b69a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1a6a89f95a46af0f142874c9d650a6358d13070d", - "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/4ede73aa7a73d81506002d2caadbbdad1ef5b69a", + "reference": "4ede73aa7a73d81506002d2caadbbdad1ef5b69a", "shasum": "" }, "require": { @@ -13641,7 +13697,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.2.0" + "source": "https://github.com/symfony/var-exporter/tree/v7.2.4" }, "funding": [ { @@ -13657,20 +13713,20 @@ "type": "tidelift" } ], - "time": "2024-10-18T07:58:17+00:00" + "time": "2025-02-13T10:27:23+00:00" }, { "name": "symfony/yaml", - "version": "v7.2.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "099581e99f557e9f16b43c5916c26380b54abb22" + "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22", - "reference": "099581e99f557e9f16b43c5916c26380b54abb22", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ac238f173df0c9c1120f862d0f599e17535a87ec", + "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec", "shasum": "" }, "require": { @@ -13713,7 +13769,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.2.0" + "source": "https://github.com/symfony/yaml/tree/v7.2.3" }, "funding": [ { @@ -13729,7 +13785,7 @@ "type": "tidelift" } ], - "time": "2024-10-23T06:56:12+00:00" + "time": "2025-01-07T12:55:42+00:00" }, { "name": "thecodingmachine/phpstan-safe-rule", diff --git a/etc/generated_templates/AbstractList.php.twig b/etc/generated_templates/AbstractList.php.twig index cdecdd5..11ad5dc 100644 --- a/etc/generated_templates/AbstractList.php.twig +++ b/etc/generated_templates/AbstractList.php.twig @@ -6,7 +6,6 @@ namespace Mammatus\Queue\Generated; use Mammatus\Queue\Worker; -// phpcs:disable /** * Autogenerated file, do not edit. Changes will be overwritten on the next composer (install|update) */ diff --git a/etc/generated_templates/WorkQueueMap.php.twig b/etc/generated_templates/WorkQueueMap.php.twig new file mode 100644 index 0000000..d3a15ce --- /dev/null +++ b/etc/generated_templates/WorkQueueMap.php.twig @@ -0,0 +1,28 @@ + '{{ worker.consumer.queue }}', +{% endfor %} + ]; + + final protected function lookUp(Work $work): string + { + if (array_key_exists($work::class, self::MAP)) { + return self::MAP[$work::class]; + } + + throw new \RuntimeException('Unknown work: ' . $work::class); + } +} diff --git a/etc/qa/phpcs.xml b/etc/qa/phpcs.xml index c677e35..27a07c6 100644 --- a/etc/qa/phpcs.xml +++ b/etc/qa/phpcs.xml @@ -9,7 +9,7 @@ ../../src ../../tests - src/Generated/* - + + src/Generated/Hydrator.php diff --git a/etc/qa/phpstan.neon b/etc/qa/phpstan.neon index d78dbf4..c1d22c0 100644 --- a/etc/qa/phpstan.neon +++ b/etc/qa/phpstan.neon @@ -10,11 +10,16 @@ parameters: - message: '#Variable method call on Mammatus\\Queue\\Contracts\\Worker.#' path: ../../src/Consumer.php + - + message: '#In method \"Mammatus\\Queue\\Consumer::handleMessage\", caught \"Throwable\" must be rethrown.#' + path: ../../src/Consumer.php ergebnis: noExtends: classesAllowedToBeExtended: - Composer\IO\NullIO - Mammatus\Queue\Generated\AbstractList + - Mammatus\Queue\Generated\WorkQueueMap + - RuntimeException includes: - ../../vendor/wyrihaximus/async-test-utilities/rules.neon diff --git a/src/App.php b/src/App.php index c812060..6525c16 100644 --- a/src/App.php +++ b/src/App.php @@ -4,19 +4,22 @@ namespace Mammatus\Queue; +use Mammatus\Contracts\Argv; +use Mammatus\Contracts\Bootable; +use Mammatus\ExitCode; use Mammatus\LifeCycleEvents\Shutdown; +use Mammatus\Queue\App\Queue; use Mammatus\Queue\Generated\AbstractList; use Psr\Log\LoggerInterface; -use React\EventLoop\Loop; use Throwable; use WyriHaximus\Broadcast\Contracts\Listener; -use WyriHaximus\PSR3\ContextLogger\ContextLogger; -use function React\Async\async; use function React\Async\await; use function React\Promise\all; +use function React\Promise\Timer\sleep; -final class App extends AbstractList implements Listener +/** @implements Bootable */ +final class App extends AbstractList implements Bootable, Listener { public function __construct( private readonly Consumer $consumer, @@ -29,36 +32,28 @@ public function stop(Shutdown $event): void $this->consumer->close(); } - public function run(string $className): int + public function boot(Argv $argv): ExitCode { - $exitCode = 2; - async(function (string $className): int { - $logger = new ContextLogger($this->logger, ['worker' => $className]); - try { - $promises = []; - foreach ($this->workers() as $worker) { - if ($worker->class !== $className) { - continue; - } - - $promises[] = $this->consumer->setupConsumer($worker); + try { + $promises = []; + foreach ($this->workers() as $worker) { + if ($worker->class !== $argv->className) { + continue; } - await(all($promises)); + $promises[] = $this->consumer->setupConsumer($worker); + } - $exitCode = 0; - } catch (Throwable $throwable) { /** @phpstan-ignore-line */ - $logger->error('Worker errored: ' . $throwable->getMessage(), ['exception' => $throwable]); + await(all($promises)); - $exitCode = 1; - } + $exitCode = ExitCode::Success; + } catch (Throwable $throwable) { /** @phpstan-ignore-line */ + $this->logger->error('Worker errored: ' . $throwable->getMessage(), ['exception' => $throwable]); - return $exitCode; - })($className)->then(static function (int $resultingExitCode) use (&$exitCode): void { - $exitCode = $resultingExitCode; - }); + $exitCode = ExitCode::Failure; + } - Loop::run(); + await(sleep(3)); return $exitCode; } diff --git a/src/App/Queue.php b/src/App/Queue.php new file mode 100644 index 0000000..23785b9 --- /dev/null +++ b/src/App/Queue.php @@ -0,0 +1,17 @@ + $className */ + public function __construct( + public string $className, + ) { + } +} diff --git a/src/Composer/Collector.php b/src/Composer/Collector.php index 18bfd7f..f293303 100644 --- a/src/Composer/Collector.php +++ b/src/Composer/Collector.php @@ -6,13 +6,16 @@ use Mammatus\Kubernetes\Attributes\SplitOut; use Mammatus\Queue\Attributes\Consumer; +use Mammatus\Queue\Contracts\Work; use Roave\BetterReflection\Reflection\ReflectionClass; use Roave\BetterReflection\Reflection\ReflectionIntersectionType; +use Roave\BetterReflection\Reflection\ReflectionType; use Roave\BetterReflection\Reflection\ReflectionUnionType; use WyriHaximus\Composer\GenerativePluginTooling\Item as ItemContract; use WyriHaximus\Composer\GenerativePluginTooling\ItemCollector; use function array_key_exists; +use function array_map; final class Collector implements ItemCollector { @@ -54,17 +57,23 @@ public function collect(ReflectionClass $class): iterable } if ($messageDTOHolder instanceof ReflectionUnionType) { - $messageDTOs = $messageDTOHolder->getTypes(); + /** @var array> $messageDTOs */ + $messageDTOs = array_map(static fn (ReflectionType $reflectedType): string => (string) $reflectedType, $messageDTOHolder->getTypes()); } else { - $messageDTOs = [$messageDTOHolder]; + /** @var array> $messageDTOs */ + $messageDTOs = [(string) $messageDTOHolder]; } foreach ($messageDTOs as $messageDTO) { + if (! (new \ReflectionClass($messageDTO))->implementsInterface(Work::class)) { + continue; + } + /** @psalm-suppress ArgumentTypeCoercion */ yield new Item( $class->getName(), $method->getName(), - (string) $messageDTO, + $messageDTO, $attributes[Consumer::class], /** @phpstan-ignore-line */ array_key_exists(SplitOut::class, $attributes), ); diff --git a/src/Composer/Plugin.php b/src/Composer/Plugin.php index 62edefa..bf45987 100644 --- a/src/Composer/Plugin.php +++ b/src/Composer/Plugin.php @@ -61,6 +61,16 @@ public function compile(string $rootPath, ItemContract ...$items): void file_put_contents($installPathList, $classContentsList); /** @phpstan-ignore-line */ chmod($installPathList, 0664); /** @phpstan-ignore-line */ + $classContentsList = SimpleTwig::render( + file_get_contents( /** @phpstan-ignore-line */ + $rootPath . '/etc/generated_templates/WorkQueueMap.php.twig', + ), + ['workers' => $items], + ); + $installPathList = $rootPath . '/src/Generated/WorkQueueMap.php'; + file_put_contents($installPathList, $classContentsList); /** @phpstan-ignore-line */ + chmod($installPathList, 0664); /** @phpstan-ignore-line */ + $dtos = []; foreach ($items as $item) { if (! ($item instanceof Item)) { diff --git a/src/Consumer.php b/src/Consumer.php index f7d71c3..41c8217 100644 --- a/src/Consumer.php +++ b/src/Consumer.php @@ -5,8 +5,9 @@ namespace Mammatus\Queue; use Interop\Queue as QueueInterop; +use Interop\Queue\Message; +use Mammatus\Queue\Contracts\Encoder; use Mammatus\Queue\Contracts\Worker as WorkerContract; -use Mammatus\Queue\Generated\AbstractList; use Mammatus\Queue\Generated\Hydrator; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; @@ -14,16 +15,16 @@ use RuntimeException; use Throwable; use WyriHaximus\Broadcast\Contracts\Listener; +use WyriHaximus\PSR3\CallableThrowableLogger\CallableThrowableLogger; +use WyriHaximus\PSR3\ContextLogger\ContextLogger; -use function is_array; -use function json_decode; use function React\Async\async; use function React\Async\await; use function React\Promise\all; use function React\Promise\Timer\sleep; use function WyriHaximus\React\futurePromise; -final class Consumer extends AbstractList implements Listener +final class Consumer implements Listener { private bool $running = true; @@ -31,6 +32,7 @@ public function __construct( private readonly ContainerInterface $container, private readonly QueueInterop\Context $context, private readonly Hydrator $hydrator, + private readonly Encoder $encoder, private readonly LoggerInterface $logger, ) { } @@ -43,47 +45,65 @@ public function close(): void /** @return PromiseInterface */ public function setupConsumer(Worker $worker): PromiseInterface { + $this->logger->debug('Setting up logger for ' . $worker->class); + $logger = new ContextLogger($this->logger, ['worker' => $worker->class, 'method' => $worker->method]); + + $this->logger->debug('Getting worker instance for ' . $worker->class); $workerInstance = $this->container->get($worker->class); if (! ($workerInstance instanceof WorkerContract)) { throw new RuntimeException('Worker instance must be instance of ' . WorkerContract::class); } $promises = [ - sleep(0.1), + sleep(1), ]; + $this->logger->debug('Starting ' . $worker->concurrency . ' workers for ' . $worker->class); for ($i = 0; $i < $worker->concurrency; $i++) { $this->logger->info('Starting consumer ' . $i . ' of ' . $worker->concurrency . ' for ' . $worker->class); - $promises[] = async(fn () => $this->consume($worker, $workerInstance))(); + $promises[] = async(fn () => $this->consume($worker, $workerInstance, new ContextLogger($logger, ['fiber' => $i])))(); } return all($promises); } - private function consume(Worker $worker, WorkerContract $workerInstance): void + private function consume(Worker $worker, WorkerContract $workerInstance, LoggerInterface $baseLogger): bool { + await(sleep(1)); $consumer = $this->context->createConsumer(new Queue($worker->queue)); while ($this->running) { $message = $consumer->receiveNoWait(); if ($message === null) { - await(futurePromise()); + await(sleep(1)); continue; } - try { - $json = json_decode($message->getBody(), true); - if (! is_array($json)) { - throw new RuntimeException('Message is not valid JSON'); - } + $this->handleMessage($message, $consumer, $worker, $workerInstance, $baseLogger); + await(futurePromise()); + } - $dto = $this->hydrator->hydrateObject($worker->dtoClass, $json); - $workerInstance->{$worker->method}($dto); - $consumer->acknowledge($message); - } catch (Throwable $error) { - $consumer->reject($message); - $this->close(); + return true; + } - throw $error; - } + private function handleMessage(Message $message, \Interop\Queue\Consumer $consumer, Worker $worker, WorkerContract $workerInstance, LoggerInterface $baseLogger): void + { + $logger = new ContextLogger($baseLogger, ['dtoClass' => $worker->dtoClass]); + + try { + $this->logger->debug('Hydrating message'); + $dto = $this->hydrator->hydrateObject( + $worker->dtoClass, + $this->encoder->decode($message->getBody()), + ); + + $this->logger->debug('Invoking worker'); + $workerInstance->{$worker->method}($dto); + + $this->logger->debug('Acknowledging message'); + $consumer->acknowledge($message); + } catch (Throwable $error) { + $this->logger->debug('Rejecting message'); + $consumer->reject($message); + CallableThrowableLogger::create($logger)($error); } } } diff --git a/src/Encoder/InvalidJSON.php b/src/Encoder/InvalidJSON.php new file mode 100644 index 0000000..216f571 --- /dev/null +++ b/src/Encoder/InvalidJSON.php @@ -0,0 +1,11 @@ + $json */ + $json = json_decode($payload, true); + /** @phpstan-ignore-next-line */ + if (! is_array($json)) { + throw new InvalidJSON('Message is not valid JSON: ' . json_last_error_msg()); + } + + return $json; + } +} diff --git a/src/Generated/AbstractList.php b/src/Generated/AbstractList.php index 1d4340b..1d72403 100644 --- a/src/Generated/AbstractList.php +++ b/src/Generated/AbstractList.php @@ -4,17 +4,18 @@ namespace Mammatus\Queue\Generated; +use Mammatus\Queue\BuildIn\EmptyMessage; +use Mammatus\Queue\BuildIn\Noop; use Mammatus\Queue\Worker; -// phpcs:disable +use function json_decode; + /** * Autogenerated file, do not edit. Changes will be overwritten on the next composer (install|update) */ abstract class AbstractList { - /** - * @return iterable - */ + /** @return iterable */ final protected function workers(): iterable { /** @see \Mammatus\Queue\BuildIn\Noop */ @@ -22,10 +23,10 @@ final protected function workers(): iterable 'internal', 'noop', 1, - \Mammatus\Queue\BuildIn\Noop::class, + Noop::class, 'perform', - \Mammatus\Queue\BuildIn\EmptyMessage::class, - \json_decode('[]', true), /** @phpstan-ignore-line */ + EmptyMessage::class, + json_decode('[]', true), /** @phpstan-ignore-line */ ); } } diff --git a/src/Generated/WorkQueueMap.php b/src/Generated/WorkQueueMap.php new file mode 100644 index 0000000..c43cacb --- /dev/null +++ b/src/Generated/WorkQueueMap.php @@ -0,0 +1,28 @@ + 'noop']; + + final protected function lookUp(Work $work): string + { + if (array_key_exists($work::class, self::MAP)) { + return self::MAP[$work::class]; + } + + throw new RuntimeException('Unknown work: ' . $work::class); + } +} diff --git a/src/Message.php b/src/Message.php new file mode 100644 index 0000000..3fd159d --- /dev/null +++ b/src/Message.php @@ -0,0 +1,13 @@ + $array */ + $array = $this->hydrator->serializeObject($work); + /** @phpstan-ignore-next-line */ + if (! is_array($array)) { + throw new RuntimeException('Message isn\'t translated into an array but ' . gettype($array) . ' instead'); + } + + $message = new Message(); + $message->setBody($this->encoder->encode($array)); + $message->setHeaders([]); + $this->producer->send( + new Queue($this->lookUp($work)), + $message, + ); + } +} diff --git a/tests/AppTest.php b/tests/AppTest.php index b94201b..4a05d14 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -4,6 +4,7 @@ namespace Mammatus\Tests\Queue; +use Mammatus\ExitCode; use Mammatus\Queue\App; use Mammatus\Queue\BuildIn\Noop; use Mammatus\Queue\Contracts\Worker as WorkerContract; @@ -12,6 +13,7 @@ use WyriHaximus\AsyncTestUtilities\AsyncTestCase; use function array_key_exists; +use function str_contains; use const PHP_INT_MAX; @@ -27,11 +29,12 @@ public function runHappy(): void $container->expects('get')->with(Noop::class)->once()->andReturn(new Noop()); + $logger->expects('debug')->withArgs(static fn (string $error): bool => str_contains($error, ' for ' . Noop::class))->atLeast()->once(); $logger->expects('info')->with('Starting consumer 0 of 1 for ' . Noop::class)->atLeast()->once(); - $exitCode = (new App($consumer, $logger))->run(Noop::class); + $exitCode = (new App($consumer, $logger))->boot(new App\Queue(Noop::class)); - self::assertSame(0, $exitCode); + self::assertSame(ExitCode::Success, $exitCode); } /** @test */ @@ -45,11 +48,12 @@ public function runAngry(): void $exception = new RuntimeException('Ik ben boos!'); $container->expects('get')->with(Noop::class)->once()->andReturn(new Angry($exception)); + $logger->expects('debug')->withArgs(static fn (string $error): bool => str_contains($error, ' for ' . Noop::class))->atLeast()->once(); $logger->expects('info')->with('Starting consumer 0 of 1 for ' . Noop::class)->atLeast()->once(); - $exitCode = (new App($consumer, $logger))->run(Noop::class); + $exitCode = (new App($consumer, $logger))->boot(new App\Queue(Noop::class)); - self::assertSame(0, $exitCode); + self::assertSame(ExitCode::Success, $exitCode); } /** @test */ @@ -59,11 +63,8 @@ public function notAnWorker(): void $container->expects('get')->with(Noop::class)->atLeast()->once()->andReturn(new Sad()); - $logger->expects('log')->withArgs(static function (string $type, string $error, array $context): bool { - if ($type !== 'error') { - return false; - } - + $logger->expects('debug')->withArgs(static fn (string $error): bool => str_contains($error, ' for ' . Noop::class))->atLeast()->once(); + $logger->expects('error')->withArgs(static function (string $error, array $context): bool { if ($error !== 'Worker errored: Worker instance must be instance of ' . WorkerContract::class) { return false; } @@ -72,8 +73,8 @@ public function notAnWorker(): void })->atLeast()->once(); $logger->expects('info')->with('Starting consumer 0 of 1 for ' . Sad::class)->never(); - $exitCode = (new App($consumer, $logger))->run(Noop::class); + $exitCode = (new App($consumer, $logger))->boot(new App\Queue(Noop::class)); - self::assertSame(1, $exitCode); + self::assertSame(ExitCode::Failure, $exitCode); } } diff --git a/tests/ConsumerFactory.php b/tests/ConsumerFactory.php index 857db56..873aeeb 100644 --- a/tests/ConsumerFactory.php +++ b/tests/ConsumerFactory.php @@ -7,6 +7,7 @@ use Interop\Queue as QueueInterop; use Interop\Queue\Queue; use Mammatus\Queue\Consumer; +use Mammatus\Queue\Encoder\JSON; use Mammatus\Queue\Generated\Hydrator; use Mockery; use Psr\Container\ContainerInterface; @@ -32,7 +33,7 @@ public static function create(bool $createConsumerExpected): array return true; })->between($createConsumerExpected ? 1 : 0, PHP_INT_MAX)->andReturn($consumerInternal); - $consumer = new Consumer($container, $context, new Hydrator(), $logger); + $consumer = new Consumer($container, $context, new Hydrator(), new JSON(), $logger); return [ $consumer, diff --git a/tests/ConsumerTest.php b/tests/ConsumerTest.php index dd52f3e..b9ac20a 100644 --- a/tests/ConsumerTest.php +++ b/tests/ConsumerTest.php @@ -9,13 +9,13 @@ use Mammatus\Queue\BuildIn\Noop; use Mammatus\Queue\Worker; use React\EventLoop\Loop; -use RuntimeException; use WyriHaximus\AsyncTestUtilities\AsyncTestCase; use WyriHaximus\React\PHPUnit\TimeOut; use function React\Async\await; +use function str_contains; -#[TimeOut(13)] +#[TimeOut(69)] final class ConsumerTest extends AsyncTestCase { /** @test */ @@ -23,7 +23,13 @@ public function consumeHappy(): void { [$consumer, $container, $context, $internalConsumer, $logger] = ConsumerFactory::create(ConsumerFactory::CREATE_CONSUMER_EXPECTED); $container->expects('get')->with(Noop::class)->once()->andReturn(new Noop()); + $logger->expects('debug')->with('Setting up logger for ' . Noop::class)->once(); + $logger->expects('debug')->with('Getting worker instance for ' . Noop::class)->once(); + $logger->expects('debug')->with('Starting 1 workers for ' . Noop::class)->once(); $logger->expects('info')->with('Starting consumer 0 of 1 for ' . Noop::class)->atLeast()->once(); + $logger->expects('debug')->with('Hydrating message')->once(); + $logger->expects('debug')->with('Invoking worker')->once(); + $logger->expects('debug')->with('Acknowledging message')->once(); $message = new Message(); $message->setBody('[]'); @@ -47,12 +53,22 @@ public function consumeHappy(): void /** @test */ public function invalidJson(): void { - self::expectException(RuntimeException::class); - self::expectExceptionMessage('Message is not valid JSON'); - [$consumer, $container, $context, $internalConsumer, $logger] = ConsumerFactory::create(ConsumerFactory::CREATE_CONSUMER_EXPECTED); $container->expects('get')->with(Noop::class)->once()->andReturn(new Noop()); - $logger->expects('info')->with('Starting consumer 0 of 1 for ' . Noop::class)->atLeast()->once(); + $logger->expects('debug')->with('Setting up logger for ' . Noop::class)->once(); + $logger->expects('debug')->with('Getting worker instance for ' . Noop::class)->once(); + $logger->expects('debug')->with('Starting 1 workers for ' . Noop::class)->once(); + $logger->expects('info')->with('Starting consumer 0 of 1 for ' . Noop::class)->once(); + $logger->expects('debug')->with('Hydrating message')->atLeast()->once(); + $logger->expects('debug')->with('Invoking worker')->never(); + $logger->expects('debug')->with('Rejecting message')->atLeast()->once(); + $logger->expects('log')->withArgs(static function (string $type, string $error): bool { + if ($type !== 'error') { + return false; + } + + return str_contains($error, 'Message is not valid JSON'); + })->atLeast()->once(); $message = new Message(); $message->setBody('{]'); @@ -66,8 +82,8 @@ public function invalidJson(): void EmptyMessage::class, [], ); - $internalConsumer->expects('receiveNoWait')->andReturn($message); - $internalConsumer->expects('reject')->with($message); + $internalConsumer->expects('receiveNoWait')->atLeast()->once()->andReturn($message); + $internalConsumer->expects('reject')->with($message)->atLeast()->once(); Loop::addTimer(3, static fn () => $consumer->close()); await($consumer->setupConsumer($worker)); diff --git a/tests/ManagerTest.php b/tests/ManagerTest.php index e023e17..c22290b 100644 --- a/tests/ManagerTest.php +++ b/tests/ManagerTest.php @@ -18,6 +18,7 @@ use function array_key_exists; use function React\Async\await; use function React\Promise\Timer\sleep; +use function str_contains; use const PHP_INT_MAX; @@ -34,6 +35,7 @@ public function runHappy(): void $eventDispatcher = Mockery::mock(EventDispatcherInterface::class); + $logger->expects('debug')->withArgs(static fn (string $error): bool => str_contains($error, ' for ' . Noop::class))->atLeast()->once(); $logger->expects('debug')->with('Starting queue manager')->once(); $logger->expects('debug')->with('Started queue manager')->once(); $logger->expects('info')->with('Starting consumer 0 of 1 for ' . Noop::class)->atLeast()->once(); @@ -60,6 +62,7 @@ public function runAngry(): void $exception = new RuntimeException('Ik ben boos!'); + $logger->expects('debug')->withArgs(static fn (string $error): bool => str_contains($error, ' for ' . Noop::class))->atLeast()->once(); $logger->expects('debug')->with('Starting queue manager')->once(); $logger->expects('debug')->with('Started queue manager')->once(); $logger->expects('info')->with('Starting consumer 0 of 1 for ' . Noop::class)->atLeast()->once(); @@ -89,8 +92,8 @@ public function notAnWorker(): void $eventDispatcher = Mockery::mock(EventDispatcherInterface::class); $eventDispatcher->expects('dispatch')->withArgs(static fn (Shutdown $event): bool => true)->once(); + $logger->expects('debug')->withArgs(static fn (string $error): bool => str_contains($error, ' for ' . Noop::class))->atLeast()->once(); $logger->expects('debug')->with('Starting queue manager')->once(); - $logger->expects('error')->withArgs(static function (string $error, array $context): bool { if ($error !== 'Worker errored: Worker instance must be instance of ' . WorkerContract::class) { return false; diff --git a/tests/ProducerTest.php b/tests/ProducerTest.php new file mode 100644 index 0000000..d685a80 --- /dev/null +++ b/tests/ProducerTest.php @@ -0,0 +1,37 @@ +shouldReceive('send')->withArgs(static function (Queue $queue, Message $message): bool { + if ($queue->getQueueName() !== 'noop') { + return false; + } + + return $message->getBody() === '[]'; + })->once(); + + $producer = new Producer($interOpProducer, new Hydrator(), new JSON()); + $producer->send(new EmptyMessage()); + } +}