diff --git a/app/composer.json b/app/composer.json index 7af5ef0..2e2208b 100644 --- a/app/composer.json +++ b/app/composer.json @@ -2,15 +2,15 @@ "minimum-stability": "dev", "prefer-stable": true, "require": { - "temporal/sdk": "^2.12.0", - "spiral/tokenizer": "^3.7", + "spiral/tokenizer": "^3.14.5", + "temporal/sdk": "^2.13", "temporal/open-telemetry-interceptors": "dev-master", "open-telemetry/exporter-otlp": "^1.1", "open-telemetry/transport-grpc": "^1.1", "symfony/console": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "buggregator/trap": "^1.3", + "buggregator/trap": "^1.13", "internal/dload": "^1.0", "phpunit/phpunit": "^10.5" }, diff --git a/app/composer.lock b/app/composer.lock index 294ff5c..ca11345 100644 --- a/app/composer.lock +++ b/app/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": "441fbbcd77b123372e5774b65eee3371", + "content-hash": "522b38d4791d64c7d0bf867c94e260cd", "packages": [ { "name": "brick/math", @@ -218,16 +218,16 @@ }, { "name": "google/common-protos", - "version": "4.8.3", + "version": "4.10.0", "source": { "type": "git", "url": "https://github.com/googleapis/common-protos-php.git", - "reference": "38a9a8bb459fa618da797d25d7bf36bb21d1103d" + "reference": "88bb76504910ddfe8fec457b622145c5731ab8ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/common-protos-php/zipball/38a9a8bb459fa618da797d25d7bf36bb21d1103d", - "reference": "38a9a8bb459fa618da797d25d7bf36bb21d1103d", + "url": "https://api.github.com/repos/googleapis/common-protos-php/zipball/88bb76504910ddfe8fec457b622145c5731ab8ea", + "reference": "88bb76504910ddfe8fec457b622145c5731ab8ea", "shasum": "" }, "require": { @@ -241,9 +241,9 @@ "extra": { "component": { "id": "common-protos", - "target": "googleapis/common-protos-php.git", "path": "CommonProtos", - "entry": "README.md" + "entry": "README.md", + "target": "googleapis/common-protos-php.git" } }, "autoload": { @@ -271,22 +271,22 @@ "google" ], "support": { - "source": "https://github.com/googleapis/common-protos-php/tree/v4.8.3" + "source": "https://github.com/googleapis/common-protos-php/tree/v4.10.0" }, - "time": "2024-09-07T01:37:15+00:00" + "time": "2025-02-03T23:47:57+00:00" }, { "name": "google/protobuf", - "version": "v4.28.3", + "version": "v4.29.3", "source": { "type": "git", "url": "https://github.com/protocolbuffers/protobuf-php.git", - "reference": "c5c311e0f3d89928251ac5a2f0e3db283612c100" + "reference": "ab5077c2cfdd1f415f42d11fdbdf903ba8e3d9b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/c5c311e0f3d89928251ac5a2f0e3db283612c100", - "reference": "c5c311e0f3d89928251ac5a2f0e3db283612c100", + "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/ab5077c2cfdd1f415f42d11fdbdf903ba8e3d9b7", + "reference": "ab5077c2cfdd1f415f42d11fdbdf903ba8e3d9b7", "shasum": "" }, "require": { @@ -315,9 +315,9 @@ "proto" ], "support": { - "source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.28.3" + "source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.29.3" }, - "time": "2024-10-22T22:27:17+00:00" + "time": "2025-01-08T21:00:13+00:00" }, { "name": "grpc/grpc", @@ -365,16 +365,16 @@ }, { "name": "nesbot/carbon", - "version": "3.8.2", + "version": "3.8.5", "source": { "type": "git", - "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947" + "url": "https://github.com/CarbonPHP/carbon.git", + "reference": "b1a53a27898639579a67de42e8ced5d5386aa9a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/e1268cdbc486d97ce23fef2c666dc3c6b6de9947", - "reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/b1a53a27898639579a67de42e8ced5d5386aa9a4", + "reference": "b1a53a27898639579a67de42e8ced5d5386aa9a4", "shasum": "" }, "require": { @@ -406,10 +406,6 @@ ], "type": "library", "extra": { - "branch-alias": { - "dev-master": "3.x-dev", - "dev-2.x": "2.x-dev" - }, "laravel": { "providers": [ "Carbon\\Laravel\\ServiceProvider" @@ -419,6 +415,10 @@ "includes": [ "extension.neon" ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-master": "3.x-dev" } }, "autoload": { @@ -450,8 +450,8 @@ ], "support": { "docs": "https://carbon.nesbot.com/docs", - "issues": "https://github.com/briannesbitt/Carbon/issues", - "source": "https://github.com/briannesbitt/Carbon" + "issues": "https://github.com/CarbonPHP/carbon/issues", + "source": "https://github.com/CarbonPHP/carbon" }, "funding": [ { @@ -467,7 +467,7 @@ "type": "tidelift" } ], - "time": "2024-11-07T17:46:48+00:00" + "time": "2025-02-11T16:28:45+00:00" }, { "name": "nyholm/psr7-server", @@ -537,16 +537,16 @@ }, { "name": "open-telemetry/api", - "version": "1.1.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/api.git", - "reference": "542064815d38a6df55af7957cd6f1d7d967c99c6" + "reference": "8b925df3047628968bc5be722468db1b98b82d51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/542064815d38a6df55af7957cd6f1d7d967c99c6", - "reference": "542064815d38a6df55af7957cd6f1d7d967c99c6", + "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/8b925df3047628968bc5be722468db1b98b82d51", + "reference": "8b925df3047628968bc5be722468db1b98b82d51", "shasum": "" }, "require": { @@ -560,13 +560,13 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.1.x-dev" - }, "spi": { "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [ "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager" ] + }, + "branch-alias": { + "dev-main": "1.1.x-dev" } }, "autoload": { @@ -603,7 +603,7 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2024-10-15T22:42:37+00:00" + "time": "2025-02-03T21:49:11+00:00" }, { "name": "open-telemetry/context", @@ -666,16 +666,16 @@ }, { "name": "open-telemetry/exporter-otlp", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/exporter-otlp.git", - "reference": "9b6de12204f25f8ab9540b46d6e7b5151897ce18" + "reference": "243d9657c44a06f740cf384f486afe954c2b725f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/exporter-otlp/zipball/9b6de12204f25f8ab9540b46d6e7b5151897ce18", - "reference": "9b6de12204f25f8ab9540b46d6e7b5151897ce18", + "url": "https://api.github.com/repos/opentelemetry-php/exporter-otlp/zipball/243d9657c44a06f740cf384f486afe954c2b725f", + "reference": "243d9657c44a06f740cf384f486afe954c2b725f", "shasum": "" }, "require": { @@ -726,20 +726,20 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2024-04-30T18:28:30+00:00" + "time": "2025-01-08T23:50:03+00:00" }, { "name": "open-telemetry/gen-otlp-protobuf", - "version": "1.2.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/gen-otlp-protobuf.git", - "reference": "66c3b98e998a726691c92e6405a82e6e7b8b169d" + "reference": "585bafddd4ae6565de154610b10a787a455c9ba0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/gen-otlp-protobuf/zipball/66c3b98e998a726691c92e6405a82e6e7b8b169d", - "reference": "66c3b98e998a726691c92e6405a82e6e7b8b169d", + "url": "https://api.github.com/repos/opentelemetry-php/gen-otlp-protobuf/zipball/585bafddd4ae6565de154610b10a787a455c9ba0", + "reference": "585bafddd4ae6565de154610b10a787a455c9ba0", "shasum": "" }, "require": { @@ -789,20 +789,20 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2024-10-30T11:49:49+00:00" + "time": "2025-01-15T23:07:07+00:00" }, { "name": "open-telemetry/sdk", - "version": "1.1.2", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/sdk.git", - "reference": "fb0ff8d8279a3776bd604791e2531dd0cc147e8b" + "reference": "37eec0fe47ddd627911f318f29b6cd48196be0c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/fb0ff8d8279a3776bd604791e2531dd0cc147e8b", - "reference": "fb0ff8d8279a3776bd604791e2531dd0cc147e8b", + "url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/37eec0fe47ddd627911f318f29b6cd48196be0c0", + "reference": "37eec0fe47ddd627911f318f29b6cd48196be0c0", "shasum": "" }, "require": { @@ -830,13 +830,13 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.0.x-dev" - }, "spi": { "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [ "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager" ] + }, + "branch-alias": { + "dev-main": "1.0.x-dev" } }, "autoload": { @@ -879,24 +879,24 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2024-10-18T21:01:35+00:00" + "time": "2025-01-29T21:40:28+00:00" }, { "name": "open-telemetry/sem-conv", - "version": "1.27.1", + "version": "1.30.0", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/sem-conv.git", - "reference": "1dba705fea74bc0718d04be26090e3697e56f4e6" + "reference": "4178c9f390da8e4dbca9b181a9d1efd50cf7ee0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/sem-conv/zipball/1dba705fea74bc0718d04be26090e3697e56f4e6", - "reference": "1dba705fea74bc0718d04be26090e3697e56f4e6", + "url": "https://api.github.com/repos/opentelemetry-php/sem-conv/zipball/4178c9f390da8e4dbca9b181a9d1efd50cf7ee0a", + "reference": "4178c9f390da8e4dbca9b181a9d1efd50cf7ee0a", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.0" }, "type": "library", "extra": { @@ -936,20 +936,20 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2024-08-28T09:20:31+00:00" + "time": "2025-02-06T00:21:48+00:00" }, { "name": "open-telemetry/transport-grpc", - "version": "1.1.0", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/transport-grpc.git", - "reference": "f0c4e0e1acb55617c5d38239d5f5e4984ac92c52" + "reference": "1d67b0ab37cf01b76bd7e95dfb8f2ca035dd6fe0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/transport-grpc/zipball/f0c4e0e1acb55617c5d38239d5f5e4984ac92c52", - "reference": "f0c4e0e1acb55617c5d38239d5f5e4984ac92c52", + "url": "https://api.github.com/repos/opentelemetry-php/transport-grpc/zipball/1d67b0ab37cf01b76bd7e95dfb8f2ca035dd6fe0", + "reference": "1d67b0ab37cf01b76bd7e95dfb8f2ca035dd6fe0", "shasum": "" }, "require": { @@ -998,7 +998,7 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2024-03-14T23:14:21+00:00" + "time": "2025-02-09T22:37:38+00:00" }, { "name": "php-http/discovery", @@ -1795,16 +1795,16 @@ }, { "name": "roadrunner-php/roadrunner-api-dto", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/roadrunner-php/roadrunner-api-dto.git", - "reference": "84ccecbd7a1daeaadda3eb0767001deb2dd13739" + "reference": "dfab9cdba2c6f73223cd0d9e159c39b6b995cff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/roadrunner-php/roadrunner-api-dto/zipball/84ccecbd7a1daeaadda3eb0767001deb2dd13739", - "reference": "84ccecbd7a1daeaadda3eb0767001deb2dd13739", + "url": "https://api.github.com/repos/roadrunner-php/roadrunner-api-dto/zipball/dfab9cdba2c6f73223cd0d9e159c39b6b995cff9", + "reference": "dfab9cdba2c6f73223cd0d9e159c39b6b995cff9", "shasum": "" }, "require": { @@ -1850,7 +1850,7 @@ "docs": "https://docs.roadrunner.dev", "forum": "https://forum.roadrunner.dev", "issues": "https://github.com/roadrunner-server/roadrunner/issues", - "source": "https://github.com/roadrunner-php/roadrunner-api-dto/tree/v1.9.0" + "source": "https://github.com/roadrunner-php/roadrunner-api-dto/tree/v1.10.0" }, "funding": [ { @@ -1858,7 +1858,7 @@ "type": "github" } ], - "time": "2024-08-06T12:07:48+00:00" + "time": "2025-01-14T10:10:32+00:00" }, { "name": "roadrunner-php/version-checker", @@ -1915,16 +1915,16 @@ }, { "name": "spiral/attributes", - "version": "v3.1.7", + "version": "v3.1.8", "source": { "type": "git", "url": "https://github.com/spiral/attributes.git", - "reference": "fc6657de4ed83913c7f02241e5fe4e8e799af8fa" + "reference": "a7e368a42b079f56c16d7fc513b68190b96842c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spiral/attributes/zipball/fc6657de4ed83913c7f02241e5fe4e8e799af8fa", - "reference": "fc6657de4ed83913c7f02241e5fe4e8e799af8fa", + "url": "https://api.github.com/repos/spiral/attributes/zipball/a7e368a42b079f56c16d7fc513b68190b96842c3", + "reference": "a7e368a42b079f56c16d7fc513b68190b96842c3", "shasum": "" }, "require": { @@ -1936,6 +1936,7 @@ "doctrine/annotations": "^1.14 || ^2.0", "jetbrains/phpstorm-attributes": "^1.0", "phpunit/phpunit": "^9.5.20", + "spiral/code-style": "^2.2", "vimeo/psalm": "^5.17" }, "type": "library", @@ -1983,7 +1984,6 @@ "support": { "chat": "https://discord.gg/V6EK4he", "docs": "https://spiral.dev/docs", - "forum": "https://forum.spiral.dev", "issues": "https://github.com/spiral/attributes/issues", "source": "https://github.com/spiral/attributes" }, @@ -1993,34 +1993,34 @@ "type": "github" } ], - "time": "2024-08-22T10:18:52+00:00" + "time": "2024-12-09T15:33:18+00:00" }, { "name": "spiral/core", - "version": "3.14.6", + "version": "3.15.3", "source": { "type": "git", "url": "https://github.com/spiral/core.git", - "reference": "feee88acc53ac323313bc5af4202fed065144e71" + "reference": "11f3222b90cf70b9ae3ebfd76072a5d0d8f15912" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spiral/core/zipball/feee88acc53ac323313bc5af4202fed065144e71", - "reference": "feee88acc53ac323313bc5af4202fed065144e71", + "url": "https://api.github.com/repos/spiral/core/zipball/11f3222b90cf70b9ae3ebfd76072a5d0d8f15912", + "reference": "11f3222b90cf70b9ae3ebfd76072a5d0d8f15912", "shasum": "" }, "require": { "php": ">=8.1", "psr/container": "^1.1|^2.0", - "spiral/security": "^3.14.6" + "spiral/security": "^3.15.3" }, "provide": { "psr/container-implementation": "^1.1|^2.0" }, "require-dev": { - "mockery/mockery": "^1.5", - "phpunit/phpunit": "^10.1", - "vimeo/psalm": "^5.9" + "mockery/mockery": "^1.6.12", + "phpunit/phpunit": "^10.5.41", + "vimeo/psalm": "^6.0" }, "type": "library", "extra": { @@ -2067,7 +2067,7 @@ "type": "github" } ], - "time": "2024-10-22T21:48:36+00:00" + "time": "2025-02-11T11:20:45+00:00" }, { "name": "spiral/goridge", @@ -2158,28 +2158,28 @@ }, { "name": "spiral/hmvc", - "version": "3.14.6", + "version": "3.15.3", "source": { "type": "git", "url": "https://github.com/spiral/hmvc.git", - "reference": "168b432680661834b3f0aa10653b0b04dc2e9628" + "reference": "cfbb53c8ed1561636e9d78a5c5d5a94227962370" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spiral/hmvc/zipball/168b432680661834b3f0aa10653b0b04dc2e9628", - "reference": "168b432680661834b3f0aa10653b0b04dc2e9628", + "url": "https://api.github.com/repos/spiral/hmvc/zipball/cfbb53c8ed1561636e9d78a5c5d5a94227962370", + "reference": "cfbb53c8ed1561636e9d78a5c5d5a94227962370", "shasum": "" }, "require": { "php": ">=8.1", "psr/event-dispatcher": "^1.0", - "spiral/core": "^3.14.6", - "spiral/interceptors": "^3.14.6" + "spiral/core": "^3.15.3", + "spiral/interceptors": "^3.15.3" }, "require-dev": { - "phpunit/phpunit": "^10.1", - "spiral/testing": "^2.8", - "vimeo/psalm": "^5.9" + "phpunit/phpunit": "^10.5.41", + "spiral/testing": "^2.8.3", + "vimeo/psalm": "^6.0" }, "type": "library", "extra": { @@ -2228,31 +2228,31 @@ "type": "github" } ], - "time": "2024-10-22T21:48:51+00:00" + "time": "2025-02-11T11:20:46+00:00" }, { "name": "spiral/interceptors", - "version": "3.14.6", + "version": "3.15.3", "source": { "type": "git", "url": "https://github.com/spiral/interceptors.git", - "reference": "a262479abbe12dc7e4a8e6e2aeac5460f1a7a590" + "reference": "1c4fbf70b40ec4de3f02130aab503e2c01d271a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spiral/interceptors/zipball/a262479abbe12dc7e4a8e6e2aeac5460f1a7a590", - "reference": "a262479abbe12dc7e4a8e6e2aeac5460f1a7a590", + "url": "https://api.github.com/repos/spiral/interceptors/zipball/1c4fbf70b40ec4de3f02130aab503e2c01d271a8", + "reference": "1c4fbf70b40ec4de3f02130aab503e2c01d271a8", "shasum": "" }, "require": { "php": ">=8.1", "psr/event-dispatcher": "^1.0", - "spiral/core": "^3.14.6" + "spiral/core": "^3.15.3" }, "require-dev": { - "phpunit/phpunit": "^10.1", - "spiral/testing": "^2.8", - "vimeo/psalm": "^5.9" + "phpunit/phpunit": "^10.5.41", + "spiral/testing": "^2.8.3", + "vimeo/psalm": "^6.0" }, "type": "library", "extra": { @@ -2306,31 +2306,31 @@ "type": "github" } ], - "time": "2024-10-22T21:48:52+00:00" + "time": "2025-02-11T11:21:00+00:00" }, { "name": "spiral/logger", - "version": "3.14.6", + "version": "3.15.3", "source": { "type": "git", "url": "https://github.com/spiral/logger.git", - "reference": "e39592fa4ee5f5eaaa5b5a75d85ed30d424cbef5" + "reference": "402e9d1530e7810ad387b383c6717e8b415b99c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spiral/logger/zipball/e39592fa4ee5f5eaaa5b5a75d85ed30d424cbef5", - "reference": "e39592fa4ee5f5eaaa5b5a75d85ed30d424cbef5", + "url": "https://api.github.com/repos/spiral/logger/zipball/402e9d1530e7810ad387b383c6717e8b415b99c2", + "reference": "402e9d1530e7810ad387b383c6717e8b415b99c2", "shasum": "" }, "require": { "php": ">=8.1", "psr/log": "1 - 3", - "spiral/core": "^3.14.6" + "spiral/core": "^3.15.3" }, "require-dev": { - "mockery/mockery": "^1.5", - "phpunit/phpunit": "^10.1", - "vimeo/psalm": "^5.9" + "mockery/mockery": "^1.6.12", + "phpunit/phpunit": "^10.5.41", + "vimeo/psalm": "^6.0" }, "type": "library", "extra": { @@ -2377,20 +2377,20 @@ "type": "github" } ], - "time": "2024-10-22T21:48:56+00:00" + "time": "2025-02-11T11:22:26+00:00" }, { "name": "spiral/roadrunner", - "version": "v2024.2.1", + "version": "v2024.3.3", "source": { "type": "git", "url": "https://github.com/roadrunner-server/roadrunner.git", - "reference": "651cb40d300e5594b0d69648c20233795c99c9c9" + "reference": "e2d86914579217e717c1a8bfa7afe85ab6aeac6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/roadrunner-server/roadrunner/zipball/651cb40d300e5594b0d69648c20233795c99c9c9", - "reference": "651cb40d300e5594b0d69648c20233795c99c9c9", + "url": "https://api.github.com/repos/roadrunner-server/roadrunner/zipball/e2d86914579217e717c1a8bfa7afe85ab6aeac6c", + "reference": "e2d86914579217e717c1a8bfa7afe85ab6aeac6c", "shasum": "" }, "type": "metapackage", @@ -2419,7 +2419,7 @@ "docs": "https://roadrunner.dev/docs", "forum": "https://forum.roadrunner.dev/", "issues": "https://github.com/roadrunner-server/roadrunner/issues", - "source": "https://github.com/roadrunner-server/roadrunner/tree/v2024.2.1" + "source": "https://github.com/roadrunner-server/roadrunner/tree/v2024.3.3" }, "funding": [ { @@ -2427,46 +2427,42 @@ "type": "github" } ], - "time": "2024-09-12T16:07:07+00:00" + "time": "2025-02-10T20:25:19+00:00" }, { "name": "spiral/roadrunner-cli", - "version": "v2.6.0", + "version": "v2.7.0", "source": { "type": "git", "url": "https://github.com/roadrunner-php/cli.git", - "reference": "a896e1d05a1fc4ebaf14e68b8b901c851c3b38b2" + "reference": "61eec29e2df6ccd2a7243e2bcc21453ba2fa3f4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/roadrunner-php/cli/zipball/a896e1d05a1fc4ebaf14e68b8b901c851c3b38b2", - "reference": "a896e1d05a1fc4ebaf14e68b8b901c851c3b38b2", + "url": "https://api.github.com/repos/roadrunner-php/cli/zipball/61eec29e2df6ccd2a7243e2bcc21453ba2fa3f4d", + "reference": "61eec29e2df6ccd2a7243e2bcc21453ba2fa3f4d", "shasum": "" }, "require": { - "composer/semver": "^3.2", + "composer/semver": "^3.4", "ext-json": "*", - "php": ">=7.4", - "spiral/roadrunner-worker": ">=2.0.2", - "spiral/tokenizer": "^2.13 || ^3.0", + "php": ">=8.1", + "spiral/roadrunner-worker": "^2 || ^3", + "spiral/tokenizer": "^2.13 || ^3.15", "symfony/console": "^5.3 || ^6.0 || ^7.0", - "symfony/http-client": "^4.4.11 || ^5.0 || ^6.0 || ^7.0", - "symfony/polyfill-php80": "^1.22", - "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + "symfony/http-client": "^4.4.51 || ^5.4.49 || ^6.4.17 || ^7.2", + "symfony/yaml": "^5.4.49 || ^6.4.17 || ^7.2" }, "require-dev": { - "jetbrains/phpstorm-attributes": "^1.0", - "vimeo/psalm": "^5.17" + "jetbrains/phpstorm-attributes": "^1.2", + "spiral/code-style": "^2.2.2", + "spiral/dumper": "^3.3", + "vimeo/psalm": "^6.0" }, "bin": [ "bin/rr" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, "autoload": { "psr-4": { "Spiral\\RoadRunner\\Console\\": "src" @@ -2487,10 +2483,20 @@ } ], "description": "RoadRunner: Command Line Interface", + "homepage": "https://roadrunner.dev", "support": { - "source": "https://github.com/roadrunner-php/cli/tree/v2.6.0" + "chat": "https://discord.gg/V6EK4he", + "docs": "https://docs.roadrunner.dev", + "issues": "https://github.com/roadrunner-server/roadrunner/issues", + "source": "https://github.com/roadrunner-php/cli/tree/v2.7.0" }, - "time": "2023-12-05T20:46:56+00:00" + "funding": [ + { + "url": "https://github.com/sponsors/roadrunner-server", + "type": "github" + } + ], + "time": "2025-01-28T11:07:47+00:00" }, { "name": "spiral/roadrunner-kv", @@ -2578,16 +2584,16 @@ }, { "name": "spiral/roadrunner-worker", - "version": "v3.6.0", + "version": "v3.6.1", "source": { "type": "git", "url": "https://github.com/roadrunner-php/worker.git", - "reference": "44c6f37c6abc25175c2723bd6daaa17651b18036" + "reference": "dd0571a84b432077447ece947e5f2b19edde574f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/roadrunner-php/worker/zipball/44c6f37c6abc25175c2723bd6daaa17651b18036", - "reference": "44c6f37c6abc25175c2723bd6daaa17651b18036", + "url": "https://api.github.com/repos/roadrunner-php/worker/zipball/dd0571a84b432077447ece947e5f2b19edde574f", + "reference": "dd0571a84b432077447ece947e5f2b19edde574f", "shasum": "" }, "require": { @@ -2651,7 +2657,7 @@ "docs": "https://docs.roadrunner.dev", "forum": "https://forum.roadrunner.dev/", "issues": "https://github.com/roadrunner-server/roadrunner/issues", - "source": "https://github.com/roadrunner-php/worker/tree/v3.6.0" + "source": "https://github.com/roadrunner-php/worker/tree/v3.6.1" }, "funding": [ { @@ -2659,32 +2665,32 @@ "type": "github" } ], - "time": "2024-06-03T15:30:19+00:00" + "time": "2024-11-23T08:32:13+00:00" }, { "name": "spiral/security", - "version": "3.14.6", + "version": "3.15.3", "source": { "type": "git", "url": "https://github.com/spiral/security.git", - "reference": "757bd652271876ed1d3ab2191aa4a98cab026ceb" + "reference": "03b14b906a4ee8e6684beed4d261f4d6b6ffab33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spiral/security/zipball/757bd652271876ed1d3ab2191aa4a98cab026ceb", - "reference": "757bd652271876ed1d3ab2191aa4a98cab026ceb", + "url": "https://api.github.com/repos/spiral/security/zipball/03b14b906a4ee8e6684beed4d261f4d6b6ffab33", + "reference": "03b14b906a4ee8e6684beed4d261f4d6b6ffab33", "shasum": "" }, "require": { "php": ">=8.1", - "spiral/core": "^3.14.6", - "spiral/hmvc": "^3.14.6" + "spiral/core": "^3.15.3", + "spiral/hmvc": "^3.15.3" }, "require-dev": { - "mockery/mockery": "^1.5", - "phpunit/phpunit": "^10.1", - "spiral/console": "^3.14.6", - "vimeo/psalm": "^5.9" + "mockery/mockery": "^1.6.12", + "phpunit/phpunit": "^10.5.41", + "spiral/console": "^3.15.3", + "vimeo/psalm": "^6.0" }, "type": "library", "extra": { @@ -2731,36 +2737,36 @@ "type": "github" } ], - "time": "2024-10-22T21:53:28+00:00" + "time": "2025-02-11T11:22:45+00:00" }, { "name": "spiral/tokenizer", - "version": "3.14.6", + "version": "3.15.3", "source": { "type": "git", "url": "https://github.com/spiral/tokenizer.git", - "reference": "fd895a156fbc77202e548429de6db80d86810e9b" + "reference": "15cd55761b101937929ba35fe49c6c85220e0b50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spiral/tokenizer/zipball/fd895a156fbc77202e548429de6db80d86810e9b", - "reference": "fd895a156fbc77202e548429de6db80d86810e9b", + "url": "https://api.github.com/repos/spiral/tokenizer/zipball/15cd55761b101937929ba35fe49c6c85220e0b50", + "reference": "15cd55761b101937929ba35fe49c6c85220e0b50", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": ">=8.1", - "spiral/core": "^3.14.6", - "spiral/logger": "^3.14.6", - "symfony/finder": "^5.3.7 || ^6.0 || ^7.0" + "spiral/core": "^3.15.3", + "spiral/logger": "^3.15.3", + "symfony/finder": "^5.4.45 || ^6.4.17 || ^7.2" }, "require-dev": { - "mockery/mockery": "^1.6", - "phpunit/phpunit": "^10.1", + "mockery/mockery": "^1.6.12", + "phpunit/phpunit": "^10.5.41", "spiral/attributes": "^2.8|^3.0", - "spiral/boot": "^3.14.6", - "spiral/files": "^3.14.6", - "vimeo/psalm": "^5.9" + "spiral/boot": "^3.15.3", + "spiral/files": "^3.15.3", + "vimeo/psalm": "^6.0" }, "type": "library", "extra": { @@ -2807,7 +2813,7 @@ "type": "github" } ], - "time": "2024-10-22T21:54:31+00:00" + "time": "2025-02-11T11:24:45+00:00" }, { "name": "symfony/clock", @@ -2885,16 +2891,16 @@ }, { "name": "symfony/console", - "version": "v6.4.15", + "version": "v6.4.17", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd" + "reference": "799445db3f15768ecc382ac5699e6da0520a0a04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", - "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", + "url": "https://api.github.com/repos/symfony/console/zipball/799445db3f15768ecc382ac5699e6da0520a0a04", + "reference": "799445db3f15768ecc382ac5699e6da0520a0a04", "shasum": "" }, "require": { @@ -2959,7 +2965,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.15" + "source": "https://github.com/symfony/console/tree/v6.4.17" }, "funding": [ { @@ -2975,20 +2981,20 @@ "type": "tidelift" } ], - "time": "2024-11-06T14:19:14+00:00" + "time": "2024-12-07T12:07:30+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -2996,12 +3002,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -3026,7 +3032,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -3042,7 +3048,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/filesystem", @@ -3112,16 +3118,16 @@ }, { "name": "symfony/finder", - "version": "v6.4.13", + "version": "v6.4.17", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "daea9eca0b08d0ed1dc9ab702a46128fd1be4958" + "reference": "1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/daea9eca0b08d0ed1dc9ab702a46128fd1be4958", - "reference": "daea9eca0b08d0ed1dc9ab702a46128fd1be4958", + "url": "https://api.github.com/repos/symfony/finder/zipball/1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7", + "reference": "1d0e8266248c5d9ab6a87e3789e6dc482af3c9c7", "shasum": "" }, "require": { @@ -3156,7 +3162,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.13" + "source": "https://github.com/symfony/finder/tree/v6.4.17" }, "funding": [ { @@ -3172,27 +3178,27 @@ "type": "tidelift" } ], - "time": "2024-10-01T08:30:56+00:00" + "time": "2024-12-29T13:51:37+00:00" }, { "name": "symfony/http-client", - "version": "v6.4.15", + "version": "v6.4.18", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "cb4073c905cd12b8496d24ac428a9228c1750670" + "reference": "394b440934056b8d9d6ba250001458e9d7998b7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/cb4073c905cd12b8496d24ac428a9228c1750670", - "reference": "cb4073c905cd12b8496d24ac428a9228c1750670", + "url": "https://api.github.com/repos/symfony/http-client/zipball/394b440934056b8d9d6ba250001458e9d7998b7f", + "reference": "394b440934056b8d9d6ba250001458e9d7998b7f", "shasum": "" }, "require": { "php": ">=8.1", "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-client-contracts": "^3.4.1", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", "symfony/service-contracts": "^2.5|^3" }, "conflict": { @@ -3249,7 +3255,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.4.15" + "source": "https://github.com/symfony/http-client/tree/v6.4.18" }, "funding": [ { @@ -3265,20 +3271,20 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:40:18+00:00" + "time": "2025-01-28T15:49:13+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.5.0", + "version": "v3.5.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "20414d96f391677bf80078aa55baece78b82647d" + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", - "reference": "20414d96f391677bf80078aa55baece78b82647d", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ee8d807ab20fcb51267fdace50fbe3494c31e645", + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645", "shasum": "" }, "require": { @@ -3286,12 +3292,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -3327,7 +3333,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.2" }, "funding": [ { @@ -3343,7 +3349,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-12-07T08:49:48+00:00" }, { "name": "symfony/polyfill-ctype", @@ -3371,8 +3377,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3447,8 +3453,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3525,8 +3531,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3609,8 +3615,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3663,86 +3669,6 @@ ], "time": "2024-09-09T11:45:10+00:00" }, - { - "name": "symfony/polyfill-php80", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" - }, { "name": "symfony/polyfill-php82", "version": "v1.31.0", @@ -3763,8 +3689,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3839,8 +3765,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3958,16 +3884,16 @@ }, { "name": "symfony/service-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { @@ -3980,12 +3906,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -4021,7 +3947,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -4037,7 +3963,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/string", @@ -4222,16 +4148,16 @@ }, { "name": "symfony/translation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", "shasum": "" }, "require": { @@ -4239,12 +4165,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -4280,7 +4206,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" }, "funding": [ { @@ -4296,20 +4222,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/yaml", - "version": "v6.4.13", + "version": "v6.4.18", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9" + "reference": "bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e99b4e94d124b29ee4cf3140e1b537d2dad8cec9", - "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9", + "url": "https://api.github.com/repos/symfony/yaml/zipball/bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5", + "reference": "bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5", "shasum": "" }, "require": { @@ -4352,7 +4278,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.13" + "source": "https://github.com/symfony/yaml/tree/v6.4.18" }, "funding": [ { @@ -4368,7 +4294,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2025-01-07T09:44:41+00:00" }, { "name": "tbachert/spi", @@ -4397,10 +4323,10 @@ }, "type": "composer-plugin", "extra": { + "class": "Nevay\\SPI\\Composer\\Plugin", "branch-alias": { "dev-main": "0.2.x-dev" }, - "class": "Nevay\\SPI\\Composer\\Plugin", "plugin-optional": true }, "autoload": { @@ -4483,54 +4409,54 @@ }, { "name": "temporal/sdk", - "version": "v2.11.2", + "version": "v2.13.1", "source": { "type": "git", "url": "https://github.com/temporalio/sdk-php.git", - "reference": "ca4f27d3dd9b34fd6785d24057431a26ef6596ce" + "reference": "2b4202b1721bddd18756e975655adc9b0bdf1692" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/temporalio/sdk-php/zipball/ca4f27d3dd9b34fd6785d24057431a26ef6596ce", - "reference": "ca4f27d3dd9b34fd6785d24057431a26ef6596ce", + "url": "https://api.github.com/repos/temporalio/sdk-php/zipball/2b4202b1721bddd18756e975655adc9b0bdf1692", + "reference": "2b4202b1721bddd18756e975655adc9b0bdf1692", "shasum": "" }, "require": { "ext-curl": "*", "ext-json": "*", - "google/common-protos": "^1.3 || ^2.0 || ^3.0 || ^4.0", - "google/protobuf": "^3.22 || ^4.0", - "grpc/grpc": "^1.42", - "nesbot/carbon": "^2.72 || ^3.0.2", + "google/common-protos": "^1.4 || ^2.2 || ^3.2 || ^4.9", + "google/protobuf": "^3.25.5 || ^4.29.3", + "grpc/grpc": "^1.57", + "nesbot/carbon": "^2.72.6 || ^3.8.4", "php": ">=8.1", - "psr/log": "^2.0 || ^3.0", - "ramsey/uuid": "^4.7", - "react/promise": "^2.9", - "roadrunner-php/roadrunner-api-dto": "^1.9.0", - "roadrunner-php/version-checker": "^1.0", - "spiral/attributes": "^3.1.6", - "spiral/roadrunner": "^2024.1", - "spiral/roadrunner-cli": "^2.5", - "spiral/roadrunner-kv": "^4.2", - "spiral/roadrunner-worker": "^3.5", - "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", - "symfony/http-client": "^5.4 || ^6.0 || ^7.0", - "symfony/process": "^5.4 || ^6.0 || ^7.0" + "psr/log": "^2.0 || ^3.0.2", + "ramsey/uuid": "^4.7.6", + "react/promise": "^2.11", + "roadrunner-php/roadrunner-api-dto": "^1.10.0", + "roadrunner-php/version-checker": "^1.0.1", + "spiral/attributes": "^3.1.8", + "spiral/roadrunner": "^2024.3.3", + "spiral/roadrunner-cli": "^2.6", + "spiral/roadrunner-kv": "^4.3", + "spiral/roadrunner-worker": "^3.6.1", + "symfony/filesystem": "^5.4.45 || ^6.4.13 || ^7.0", + "symfony/http-client": "^5.4.49 || ^6.4.17 || ^7.0", + "symfony/polyfill-php83": "^1.31.0", + "symfony/process": "^5.4.47 || ^6.4.15 || ^7.0" }, "require-dev": { - "buggregator/trap": "^1.10.1", - "composer/composer": "^2.0", + "buggregator/trap": "^1.13.0", + "composer/composer": "^2.8.4", "dereuromark/composer-prefer-lowest": "^0.1.10", - "doctrine/annotations": "^1.14|^2.0.0", + "doctrine/annotations": "^1.14.4 || ^2.0.2", "internal/dload": "^1.0", "jetbrains/phpstorm-attributes": "dev-master@dev", - "laminas/laminas-code": "^4.0", - "phpunit/phpunit": "^10.5", + "laminas/laminas-code": "^4.16", + "phpunit/phpunit": "^10.5.41", "spiral/code-style": "~2.1.2", - "spiral/core": "^3.13", - "symfony/var-dumper": "^6.0 || ^7.0", + "spiral/core": "^3.14.9", "ta-tikoma/phpunit-architecture-test": "^0.8.4", - "vimeo/psalm": "^4.30 || ^5.4" + "vimeo/psalm": "^5.26.1 || ^6.2" }, "suggest": { "doctrine/annotations": "For Doctrine metadata driver support", @@ -4572,22 +4498,22 @@ "issues": "https://github.com/temporalio/sdk-php/issues", "source": "https://github.com/temporalio/sdk-php" }, - "time": "2024-10-28T22:16:51+00:00" + "time": "2025-02-12T20:26:42+00:00" } ], "packages-dev": [ { "name": "buggregator/trap", - "version": "1.11.0", + "version": "1.13.3", "source": { "type": "git", "url": "https://github.com/buggregator/trap.git", - "reference": "df2ccbb8327749cd891b5227ba0b5ee794001a7e" + "reference": "500e7ac1313d35bf0a00540f230f134a8fd0ec91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/buggregator/trap/zipball/df2ccbb8327749cd891b5227ba0b5ee794001a7e", - "reference": "df2ccbb8327749cd891b5227ba0b5ee794001a7e", + "url": "https://api.github.com/repos/buggregator/trap/zipball/500e7ac1313d35bf0a00540f230f134a8fd0ec91", + "reference": "500e7ac1313d35bf0a00540f230f134a8fd0ec91", "shasum": "" }, "require": { @@ -4607,7 +4533,6 @@ "require-dev": { "dereuromark/composer-prefer-lowest": "^0.1.10", "ergebnis/phpunit-slow-test-detector": "^2.14", - "friendsofphp/php-cs-fixer": "^3.54", "google/protobuf": "^3.23", "pestphp/pest": "^2.34", "phpstan/extension-installer": "^1.3", @@ -4618,8 +4543,8 @@ "phpunit/phpunit": "^10.5", "rector/rector": "^1.1", "roxblnfk/unpoly": "^1.8.1", - "vimeo/psalm": "^5.11", - "wayofdev/cs-fixer-config": "^1.4" + "spiral/code-style": "*", + "vimeo/psalm": "^5.11" }, "suggest": { "ext-simplexml": "To load trap.xml", @@ -4654,6 +4579,7 @@ "description": "A simple and powerful tool for debugging PHP applications.", "homepage": "https://buggregator.dev/", "keywords": [ + "Fibers", "WebSockets", "binary dump", "cli", @@ -4661,6 +4587,7 @@ "debug", "dev", "dump", + "dumper", "helper", "sentry", "server", @@ -4668,23 +4595,19 @@ ], "support": { "issues": "https://github.com/buggregator/trap/issues", - "source": "https://github.com/buggregator/trap/tree/1.11.0" + "source": "https://github.com/buggregator/trap/tree/1.13.3" }, "funding": [ { - "url": "https://github.com/sponsors/buggregator", - "type": "github" - }, - { - "url": "https://patreon.com/butschster", - "type": "patreon" + "url": "https://boosty.to/roxblnfk", + "type": "boosty" }, { "url": "https://patreon.com/roxblnfk", "type": "patreon" } ], - "time": "2024-09-25T11:27:16+00:00" + "time": "2025-01-23T20:32:15+00:00" }, { "name": "clue/stream-filter", @@ -4825,16 +4748,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": { @@ -4873,7 +4796,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": [ { @@ -4881,20 +4804,20 @@ "type": "tidelift" } ], - "time": "2024-11-08T17:47:46+00:00" + "time": "2025-02-12T12:17:51+00:00" }, { "name": "nikic/php-parser", - "version": "v5.3.1", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" + "reference": "447a020a1f875a434d62f2a401f53b82a396e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", - "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494", "shasum": "" }, "require": { @@ -4937,38 +4860,38 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" }, - "time": "2024-10-08T18:51:32+00:00" + "time": "2024-12-30T11:07:19+00:00" }, { "name": "nunomaduro/termwind", - "version": "v1.16.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/termwind.git", - "reference": "dcf1ec3dfa36137b7ce41d43866644a7ab8fc257" + "reference": "5369ef84d8142c1d87e4ec278711d4ece3cbf301" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/dcf1ec3dfa36137b7ce41d43866644a7ab8fc257", - "reference": "dcf1ec3dfa36137b7ce41d43866644a7ab8fc257", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/5369ef84d8142c1d87e4ec278711d4ece3cbf301", + "reference": "5369ef84d8142c1d87e4ec278711d4ece3cbf301", "shasum": "" }, "require": { "ext-mbstring": "*", "php": "^8.1", - "symfony/console": "^6.4.12" + "symfony/console": "^6.4.15" }, "require-dev": { - "illuminate/console": "^10.48.22", - "illuminate/support": "^10.48.22", - "laravel/pint": "^1.18.1", - "pestphp/pest": "^2", + "illuminate/console": "^10.48.24", + "illuminate/support": "^10.48.24", + "laravel/pint": "^1.18.2", + "pestphp/pest": "^2.36.0", "pestphp/pest-plugin-mock": "2.0.0", - "phpstan/phpstan": "^1.12.6", + "phpstan/phpstan": "^1.12.11", "phpstan/phpstan-strict-rules": "^1.6.1", - "symfony/var-dumper": "^6.4.11", + "symfony/var-dumper": "^6.4.15", "thecodingmachine/phpstan-strict-rules": "^1.0.0" }, "type": "library", @@ -5008,7 +4931,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v1.16.0" + "source": "https://github.com/nunomaduro/termwind/tree/v1.17.0" }, "funding": [ { @@ -5024,7 +4947,7 @@ "type": "github" } ], - "time": "2024-10-15T15:27:12+00:00" + "time": "2024-11-21T10:36:35+00:00" }, { "name": "nyholm/psr7", @@ -5614,16 +5537,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.38", + "version": "10.5.45", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132" + "reference": "bd68a781d8e30348bc297449f5234b3458267ae8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a86773b9e887a67bc53efa9da9ad6e3f2498c132", - "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd68a781d8e30348bc297449f5234b3458267ae8", + "reference": "bd68a781d8e30348bc297449f5234b3458267ae8", "shasum": "" }, "require": { @@ -5633,7 +5556,7 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.0", + "myclabs/deep-copy": "^1.12.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.1", @@ -5695,7 +5618,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.38" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.45" }, "funding": [ { @@ -5711,7 +5634,7 @@ "type": "tidelift" } ], - "time": "2024-10-28T13:06:21+00:00" + "time": "2025-02-06T16:08:12+00:00" }, { "name": "react/async", @@ -6778,16 +6701,16 @@ }, { "name": "symfony/var-dumper", - "version": "v6.4.15", + "version": "v6.4.18", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80" + "reference": "4ad10cf8b020e77ba665305bb7804389884b4837" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80", - "reference": "38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/4ad10cf8b020e77ba665305bb7804389884b4837", + "reference": "4ad10cf8b020e77ba665305bb7804389884b4837", "shasum": "" }, "require": { @@ -6843,7 +6766,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.15" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.18" }, "funding": [ { @@ -6859,7 +6782,7 @@ "type": "tidelift" } ], - "time": "2024-11-08T15:28:48+00:00" + "time": "2025-01-17T11:26:11+00:00" }, { "name": "theseer/tokenizer", diff --git a/app/src/SafeMessageHandlers/DTO/AssignNodesToJobInput.php b/app/src/SafeMessageHandlers/DTO/AssignNodesToJobInput.php new file mode 100644 index 0000000..c13c775 --- /dev/null +++ b/app/src/SafeMessageHandlers/DTO/AssignNodesToJobInput.php @@ -0,0 +1,16 @@ + A [Node => Job Name] array*/ + public array $nodes = []; + /** @var array */ + public array $jobsAssigned = []; +} diff --git a/app/src/SafeMessageHandlers/DTO/FindBadNodesInput.php b/app/src/SafeMessageHandlers/DTO/FindBadNodesInput.php new file mode 100644 index 0000000..591fb14 --- /dev/null +++ b/app/src/SafeMessageHandlers/DTO/FindBadNodesInput.php @@ -0,0 +1,15 @@ +input = $input; + $this->output = $output; + + $jobs = max(1, (int) $input->getArgument('jobs')); + $testContinueAsNew = (bool) $input->getArgument('continue'); + $delay = 0.5; + + $workflow = $this->workflowClient->newWorkflowStub( + MessageHandlerWorkflowInterface::class, + WorkflowOptions::new() + ->withWorkflowId(self::WORKFLOW_ID) + ->withWorkflowIdReusePolicy(IdReusePolicy::TerminateIfRunning), + ); + + $output->writeln("Starting MessageHandlerWorkflow... "); + + $this->workflowClient->start($workflow, new ClusterManagerInput(testContinueAsNew: $testContinueAsNew)); + $this->doClusterLifecycle($workflow, $delay, $jobs); + + return self::SUCCESS; + } + + private function doClusterLifecycle( + MessageHandlerWorkflowInterface|WorkflowProxy $workflow, + float $delay, + int $jobs = 6, + ) { + $untyped = $workflow->__getUntypedStub(); + $workflow->startCluster(); + + $this->output->writeln('Assign jobs to nodes...'); + $handle = []; + for ($i = 0; $i < $jobs; $i++) { + $handle[] = $untyped->startUpdate( + 'assign_nodes_to_job', + new ClusterManagerAssignNodesToJobInput(2, "task-$i"), + ); + } + // await + foreach ($handle as $h) { + $h->getResult(); + } + + $this->output->writeln("Sleeping for $delay second(s)"); + $delay > 0 and \usleep((int) ($delay * 1000000)); + + $this->output->writeln('Deleting jobs...'); + $handle = []; + for ($i = 0; $i < $jobs; $i++) { + $handle[] = $untyped->startUpdate( + 'delete_job', + new ClusterManagerDeleteJobInput("task-$i"), + ); + } + // await + foreach ($handle as $h) { + $h->getResult(); + } + + $workflow->shutdownCluster(); + } +} \ No newline at end of file diff --git a/app/src/SafeMessageHandlers/MessageHandlerActivity.php b/app/src/SafeMessageHandlers/MessageHandlerActivity.php new file mode 100644 index 0000000..a75d891 --- /dev/null +++ b/app/src/SafeMessageHandlers/MessageHandlerActivity.php @@ -0,0 +1,51 @@ +nodes) . ' to job ' . $input->jobName); + \sleep(1); + } + + #[ActivityMethod(name: 'unassign_nodes_for_job')] + public function unassign_nodes_for_job(UnassignNodesForJobInput $input): void + { + \trap('Deallocating nodes ' . \implode(', ', $input->nodes) . ' from job ' . $input->jobName); + \sleep(1); + } + + /** + * @return string[] + */ + #[ActivityMethod(name: 'find_bad_nodes')] + public function find_bad_nodes(FindBadNodesInput $input): array + { + \sleep(1); + $badNodes = []; + foreach ($input->nodesToCheck as $node) { + if ((int) $node % 5 === 0) { + $badNodes[] = $node; + } + } + + \trap(\count($badNodes) > 0 + ? 'Found bad nodes: ' . \implode(', ', $badNodes) + : 'No new bad nodes found.', + ); + + return $badNodes; + } +} diff --git a/app/src/SafeMessageHandlers/MessageHandlerActivityInterface.php b/app/src/SafeMessageHandlers/MessageHandlerActivityInterface.php new file mode 100644 index 0000000..658107a --- /dev/null +++ b/app/src/SafeMessageHandlers/MessageHandlerActivityInterface.php @@ -0,0 +1,27 @@ +state = $input->state ?? new ClusterManagerState(); + $this->maxHistoryLength = $input->testContinueAsNew ? 120 : null; + $this->sleepIntervalSeconds = $input->testContinueAsNew ? 1 : 600; + + // Protects workflow state from interleaved access + $this->nodesLock = new Mutex(); + } + + public function run(ClusterManagerInput $input) + { + yield Workflow::await(fn() => $this->state->clusterStarted); + // Perform health checks at intervals. + while (true) { + yield $this->performHealthChecks(); + try { + yield Workflow::awaitWithTimeout( + $this->sleepIntervalSeconds, + fn() => $this->state->clusterShutdown || $this->shouldContinueAsNew(), + ); + } catch (\Throwable) { + // do nothing + } + + if ($this->state->clusterShutdown) { + break; + } + if ($this->shouldContinueAsNew()) { + // We don't want to leave any job assignment or deletion handlers half-finished when we continue as new. + yield Workflow::await(fn() => Workflow::allHandlersFinished()); + trap("Continuing as new"); + Workflow::continueAsNew( + Workflow::getInfo()->type->name, + [new ClusterManagerInput($this->state, $input->testContinueAsNew)], + ); + } + } + + // Make sure we finish off handlers such as deleting jobs before we complete the workflow. + yield Workflow::await(fn() => Workflow::allHandlersFinished()); + return new ClusterManagerResult( + \count($this->getAssignedNodes()), + \count($this->getBadNodes()), + ); + } + + public function startCluster(): void + { + $this->state->clusterStarted = true; + $this->state->nodes = \array_fill_keys(\range(0, 24), null); + trap("Cluster started"); + } + + public function shutdownCluster() + { + yield Workflow::await(fn() => $this->state->clusterStarted); + $this->state->clusterShutdown = true; + trap("Cluster shut down"); + } + + public function assignNodesToJob(ClusterManagerAssignNodesToJobInput $input) + { + yield Workflow::await(fn() => $this->state->clusterStarted); + // If you want the client to receive a failure, either add an update validator + // and throw the exception from there. + // Other exceptions in the main handler will cause the workflow to keep retrying and get it stuck. + $this->state->clusterShutdown and throw new ApplicationFailure( + 'Cannot assign nodes to a job: Cluster is already shut down', 'CannotAssignNodesToJob', true, + ); + + return yield Workflow::runLocked($this->nodesLock, function () use ($input) { + // Idempotency guard. + if (\in_array($input->jobName, $this->state->jobsAssigned, true)) { + return new ClusterManagerAssignNodesToJobResult( + $this->getAssignedNodes($input->jobName), + ); + } + + $unassignedNodes = $this->getUnassignedNodes(); + \count($unassignedNodes) < $input->totalNumNodes and throw new ApplicationFailure( + \sprintf( + 'Cannot assign %d nodes; have only %d available', + $input->totalNumNodes, + \count($unassignedNodes), + ), + 'CannotAssignNodesToJob', + true, + ); + + $nodesToAssign = \array_slice($unassignedNodes, 0, $input->totalNumNodes); + /** + * This await would be dangerous without {@see self::$nodesLock} because it yields control + * and allows interleaving with {@see self::deleteJob()} and {@see self::performHealthChecks()}, + * which both touch {@see ClusterManagerState::$nodes}. + */ + yield $this->_assignNodesToJob($nodesToAssign, $input->jobName); + return new ClusterManagerAssignNodesToJobResult($this->getAssignedNodes($input->jobName)); + }); + } + + public function deleteJob(ClusterManagerDeleteJobInput $input): \Generator + { + yield Workflow::await(fn() => $this->state->clusterStarted); + // If you want the client to receive a failure, either add an update validator + // and throw the exception from there + $this->state->clusterShutdown and throw new ApplicationFailure( + 'Cannot delete a job: Cluster is already shut down', 'CannotDeleteJob', true, + ); + + return yield Workflow::runLocked($this->nodesLock, function () use ($input) { + $nodesToUnassign = \array_keys(\array_filter($this->state->nodes, fn($v) => $v === $input->jobName)); + /** + * This await would be dangerous without {@see self::$nodesLock} because it yields control + * and allows interleaving with {@see self::assignNodesToJob()} and {@see self::performHealthChecks()}, + * which all touch {@see ClusterManagerState::$nodes}. + */ + yield $this->_unassignNodesForJob($nodesToUnassign, $input->jobName); + }); + } + + public function getState(): ClusterManagerState + { + return $this->state; + } + + private function getUnassignedNodes(): array + { + return \array_keys(\array_filter($this->state->nodes, fn($v) => $v === null)); + } + + private function getBadNodes(): array + { + return \array_keys(\array_filter($this->state->nodes, fn($v) => $v === 'BAD!')); + } + + private function getAssignedNodes(?string $jobName = null): array + { + return $jobName === null + ? \array_keys(\array_filter($this->state->nodes, fn($v) => $v !== null && $v !== 'BAD!')) + : \array_keys(\array_filter($this->state->nodes, fn($v) => $v === $jobName)); + } + + private function performHealthChecks(): \Generator + { + return yield Workflow::runLocked($this->nodesLock, function () { + $assignedNodes = $this->getAssignedNodes(); + try { + /** + * This await would be dangerous without {@see self::$nodesLock} because it yields control + * and allows interleaving with {@see self::assignNodesToJob()} and {@see self::deleteJob()}, + * which both touch {@see ClusterManagerState::$nodes}. + */ + $badNodes = yield Workflow::executeActivity( + 'find_bad_nodes', + [new FindBadNodesInput($assignedNodes)], + ActivityOptions::new()->withStartToCloseTimeout('10 seconds') + // This health check is optional, and our lock would block the whole workflow + ->withRetryOptions(RetryOptions::new()->withMaximumAttempts(1)), + ); + + foreach ($badNodes as $node) { + $this->state->nodes[$node] = 'BAD!'; + } + } catch (\Throwable $e) { + trap(\sprintf('Health check failed with error %s: %s', $e::class, $e->getMessage())); + } + }); + } + + private function shouldContinueAsNew(): bool + { + if (Workflow::getInfo()->shouldContinueAsNew) { + return true; + } + + // This is just for ease-of-testing. In production, we trust temporal to tell us when to continue as new. + if ($this->maxHistoryLength !== null && Workflow::getInfo()->historyLength > $this->maxHistoryLength) { + return true; + } + + return false; + } + + private function _unassignNodesForJob(array $nodesToUnassign, string $jobName): \Generator + { + yield Workflow::executeActivity( + 'unassign_nodes_for_job', + [new UnassignNodesForJobInput($nodesToUnassign, $jobName)], + ActivityOptions::new()->withStartToCloseTimeout('10 seconds'), + ); + + foreach ($nodesToUnassign as $node) { + $this->state->nodes[$node] = null; + } + } + + private function _assignNodesToJob(array $assignedNodes, string $jobName): \Generator + { + yield Workflow::executeActivity( + 'assign_nodes_to_job', + [new AssignNodesToJobInput($assignedNodes, $jobName)], + ActivityOptions::new()->withStartToCloseTimeout('10 seconds'), + ); + foreach ($assignedNodes as $node) { + $this->state->nodes[$node] = $jobName; + } + + $this->state->jobsAssigned[] = $jobName; + } +} diff --git a/app/src/SafeMessageHandlers/MessageHandlerWorkflowInterface.php b/app/src/SafeMessageHandlers/MessageHandlerWorkflowInterface.php new file mode 100644 index 0000000..96dc5ba --- /dev/null +++ b/app/src/SafeMessageHandlers/MessageHandlerWorkflowInterface.php @@ -0,0 +1,44 @@ +shouldContinueAsNew` to see when it's time. +* Most people want their message handlers to finish before the workflow run completes or continues as new. + Use `yield Workflow::await(fn() => Workflow::allHandlersFinished())` to achieve this. +* Message handlers can be made idempotent. + See update `MessageHandlerWorkflow::assignNodesToJob()`. + + +From the root of the project, run the following command: + +```bash +php ./app/app.php safe-message-handlers +``` diff --git a/app/worker.php b/app/worker.php index fa446ad..0b8ef1d 100644 --- a/app/worker.php +++ b/app/worker.php @@ -14,12 +14,15 @@ use Temporal\OpenTelemetry\Interceptor\OpenTelemetryWorkflowOutboundRequestInterceptor; use Temporal\SampleUtils\DeclarationLocator; use Temporal\SampleUtils\TracerFactory; +use Temporal\Worker\FeatureFlags; use Temporal\WorkerFactory; use Temporal\Samples\FileProcessing; ini_set('display_errors', 'stderr'); include "vendor/autoload.php"; +FeatureFlags::$workflowDeferredHandlerStart = true; + // finds all available workflows, activity types and commands in a given directory $declarations = DeclarationLocator::create(__DIR__ . '/src/');