From 43bd91933fa8597ffb8bb1f732bdd2bdee09a059 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Wed, 30 May 2018 09:06:22 -0500 Subject: [PATCH 01/19] Remove Pylon As A Dependency For Clients - Use the AVL template to produce aware traits that do not depend on pylon - refactor public API to reflect this - allow locator methods to be executed out of order without instantiating the worker class - instantiate the worker classs, inject the worker service, and call the work method in the same context --- composer.json | 4 +- composer.lock | 395 +++++------------- src/Api/V1/Job/Scheduler/AwareTrait.php | 27 +- src/Api/V1/Job/Scheduler/Factory.php | 2 +- .../V1/Job/Scheduler/Factory/AwareTrait.php | 29 +- src/Api/V1/Job/Type/Registrar/AwareTrait.php | 31 +- src/Api/V1/Job/Type/Registrar/Factory.php | 2 +- .../Job/Type/Registrar/Factory/AwareTrait.php | 29 +- src/Api/V1/Logger/AwareTrait.php | 26 +- src/Api/V1/Worker/Service.php | 16 +- src/Api/V1/Worker/Service/AwareTrait.php | 26 +- src/Foreman.php | 22 +- src/Worker/Locator.php | 26 +- 13 files changed, 245 insertions(+), 390 deletions(-) diff --git a/composer.json b/composer.json index b13ada0a..e0f068ae 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,6 @@ "symfony/finder": "^4.0", "zendframework/zend-db": "^2.8", "dragonmantank/cron-expression": "^2.0", - "ocramius/proxy-manager": "^2.1", "neighborhoods/pylon": "^1.0", "doctrine/dbal": "^2.7" }, @@ -47,8 +46,7 @@ }, "autoload-dev": { "psr-4": { - "Neighborhoods\\KojoTest\\": "tests", - "Neighborhoods\\KojoExample\\": "example" + "Neighborhoods\\KojoTest\\": "tests" } } } diff --git a/composer.lock b/composer.lock index 3c069de3..22506f5d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "ad76a5b871bb8e08602cd4d6bd8e70e0", + "content-hash": "3382a0a8f83c6ac1ba27f686535d85bd", "packages": [ { "name": "doctrine/annotations", @@ -571,124 +571,6 @@ "description": "Neighborhoods Pylon is a collection of useful, but most importantly, generic objects.", "time": "2018-04-18T19:29:35+00:00" }, - { - "name": "ocramius/package-versions", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/Ocramius/PackageVersions.git", - "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f", - "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0.0", - "php": "^7.1.0" - }, - "require-dev": { - "composer/composer": "^1.6.3", - "ext-zip": "*", - "infection/infection": "^0.7.1", - "phpunit/phpunit": "^7.0.0" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "time": "2018-02-05T13:05:30+00:00" - }, - { - "name": "ocramius/proxy-manager", - "version": "2.1.1", - "source": { - "type": "git", - "url": "https://github.com/Ocramius/ProxyManager.git", - "reference": "e18ac876b2e4819c76349de8f78ccc8ef1554cd7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/e18ac876b2e4819c76349de8f78ccc8ef1554cd7", - "reference": "e18ac876b2e4819c76349de8f78ccc8ef1554cd7", - "shasum": "" - }, - "require": { - "ocramius/package-versions": "^1.1.1", - "php": "^7.1.0", - "zendframework/zend-code": "^3.1.0" - }, - "require-dev": { - "couscous/couscous": "^1.5.2", - "ext-phar": "*", - "humbug/humbug": "dev-master@DEV", - "nikic/php-parser": "^3.0.4", - "phpbench/phpbench": "^0.12.2", - "phpstan/phpstan": "^0.6.4", - "phpunit/phpunit": "^5.6.4", - "phpunit/phpunit-mock-objects": "^3.4.1", - "squizlabs/php_codesniffer": "^2.7.0" - }, - "suggest": { - "ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects", - "zendframework/zend-json": "To have the JsonRpc adapter (Remote Object feature)", - "zendframework/zend-soap": "To have the Soap adapter (Remote Object feature)", - "zendframework/zend-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "ProxyManager\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.io/" - } - ], - "description": "A library providing utilities to generate, instantiate and generally operate with Object Proxies", - "homepage": "https://github.com/Ocramius/ProxyManager", - "keywords": [ - "aop", - "lazy loading", - "proxy", - "proxy pattern", - "service proxies" - ], - "time": "2017-05-04T11:12:50+00:00" - }, { "name": "psr/cache", "version": "1.0.1", @@ -881,16 +763,16 @@ }, { "name": "symfony/cache", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "ff96ef34437ccc2c0737677c1bf14904a2b9482d" + "reference": "bd6d0a969c80b00630e9e2f0ab14ad4518712ec8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/ff96ef34437ccc2c0737677c1bf14904a2b9482d", - "reference": "ff96ef34437ccc2c0737677c1bf14904a2b9482d", + "url": "https://api.github.com/repos/symfony/cache/zipball/bd6d0a969c80b00630e9e2f0ab14ad4518712ec8", + "reference": "bd6d0a969c80b00630e9e2f0ab14ad4518712ec8", "shasum": "" }, "require": { @@ -946,25 +828,26 @@ "caching", "psr6" ], - "time": "2018-04-30T01:05:59+00:00" + "time": "2018-05-16T09:05:32+00:00" }, { "name": "symfony/config", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "7c19370ab04e9ac05b74a504198e165f5ccf6dd8" + "reference": "aaef656e99c5396d6118970abd1ceb11fa74551d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/7c19370ab04e9ac05b74a504198e165f5ccf6dd8", - "reference": "7c19370ab04e9ac05b74a504198e165f5ccf6dd8", + "url": "https://api.github.com/repos/symfony/config/zipball/aaef656e99c5396d6118970abd1ceb11fa74551d", + "reference": "aaef656e99c5396d6118970abd1ceb11fa74551d", "shasum": "" }, "require": { "php": "^7.1.3", - "symfony/filesystem": "~3.4|~4.0" + "symfony/filesystem": "~3.4|~4.0", + "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/finder": "<3.4" @@ -1008,20 +891,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2018-03-19T22:35:49+00:00" + "time": "2018-05-16T09:05:32+00:00" }, { "name": "symfony/console", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3e820bc2c520a87ca209ad8fa961c97f42e0b4ae" + "reference": "058f120b8e06ebcd7b211de5ffae07b2db00fbdd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3e820bc2c520a87ca209ad8fa961c97f42e0b4ae", - "reference": "3e820bc2c520a87ca209ad8fa961c97f42e0b4ae", + "url": "https://api.github.com/repos/symfony/console/zipball/058f120b8e06ebcd7b211de5ffae07b2db00fbdd", + "reference": "058f120b8e06ebcd7b211de5ffae07b2db00fbdd", "shasum": "" }, "require": { @@ -1076,20 +959,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-04-30T01:23:47+00:00" + "time": "2018-05-16T09:05:32+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "1f99622d8a63b160bfdd0ad7b2da56ee413cba64" + "reference": "4b272d65e9c0d2d40e2d23bab3c7a184ad4a3a18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/1f99622d8a63b160bfdd0ad7b2da56ee413cba64", - "reference": "1f99622d8a63b160bfdd0ad7b2da56ee413cba64", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4b272d65e9c0d2d40e2d23bab3c7a184ad4a3a18", + "reference": "4b272d65e9c0d2d40e2d23bab3c7a184ad4a3a18", "shasum": "" }, "require": { @@ -1147,11 +1030,11 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-04-30T01:05:59+00:00" + "time": "2018-05-25T11:57:52+00:00" }, { "name": "symfony/expression-language", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", @@ -1201,20 +1084,21 @@ }, { "name": "symfony/filesystem", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21" + "reference": "7a69e728e9f0044958c2fd7d72bfe5e7bd1a4d04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21", - "reference": "5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/7a69e728e9f0044958c2fd7d72bfe5e7bd1a4d04", + "reference": "7a69e728e9f0044958c2fd7d72bfe5e7bd1a4d04", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" }, "type": "library", "extra": { @@ -1246,20 +1130,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-02-22T10:50:29+00:00" + "time": "2018-05-16T09:05:32+00:00" }, { "name": "symfony/finder", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49" + "reference": "8c633f5a815903a1fe6e3fc135f207267a8a79af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", - "reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", + "url": "https://api.github.com/repos/symfony/finder/zipball/8c633f5a815903a1fe6e3fc135f207267a8a79af", + "reference": "8c633f5a815903a1fe6e3fc135f207267a8a79af", "shasum": "" }, "require": { @@ -1295,7 +1179,62 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-04-04T05:10:37+00:00" + "time": "2018-05-16T09:05:32+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2018-04-30T19:57:29+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1358,20 +1297,21 @@ }, { "name": "symfony/yaml", - "version": "v4.0.9", + "version": "v4.0.11", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "275ad099e4cbe612a2acbca14a16dd1c5311324d" + "reference": "048b1be5fb96e73ff1d065f5e7e23f84415ac907" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/275ad099e4cbe612a2acbca14a16dd1c5311324d", - "reference": "275ad099e4cbe612a2acbca14a16dd1c5311324d", + "url": "https://api.github.com/repos/symfony/yaml/zipball/048b1be5fb96e73ff1d065f5e7e23f84415ac907", + "reference": "048b1be5fb96e73ff1d065f5e7e23f84415ac907", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3", + "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/console": "<3.4" @@ -1412,60 +1352,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2018-04-08T08:49:08+00:00" - }, - { - "name": "zendframework/zend-code", - "version": "3.3.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-code.git", - "reference": "6b1059db5b368db769e4392c6cb6cc139e56640d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/6b1059db5b368db769e4392c6cb6cc139e56640d", - "reference": "6b1059db5b368db769e4392c6cb6cc139e56640d", - "shasum": "" - }, - "require": { - "php": "^7.1", - "zendframework/zend-eventmanager": "^2.6 || ^3.0" - }, - "require-dev": { - "doctrine/annotations": "~1.0", - "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "zendframework/zend-coding-standard": "^1.0.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" - }, - "suggest": { - "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", - "zendframework/zend-stdlib": "Zend\\Stdlib component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev", - "dev-develop": "3.3-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Code\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides facilities to generate arbitrary code using an object oriented interface", - "homepage": "https://github.com/zendframework/zend-code", - "keywords": [ - "code", - "zf2" - ], - "time": "2017-10-20T15:21:32+00:00" + "time": "2018-05-07T07:12:24+00:00" }, { "name": "zendframework/zend-db", @@ -1525,60 +1412,6 @@ ], "time": "2018-04-09T13:21:36+00:00" }, - { - "name": "zendframework/zend-eventmanager", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-eventmanager.git", - "reference": "a5e2583a211f73604691586b8406ff7296a946dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/a5e2583a211f73604691586b8406ff7296a946dd", - "reference": "a5e2583a211f73604691586b8406ff7296a946dd", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "athletic/athletic": "^0.1", - "container-interop/container-interop": "^1.1.0", - "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", - "zendframework/zend-coding-standard": "~1.0.0", - "zendframework/zend-stdlib": "^2.7.3 || ^3.0" - }, - "suggest": { - "container-interop/container-interop": "^1.1.0, to use the lazy listeners feature", - "zendframework/zend-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev", - "dev-develop": "3.3-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\EventManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Trigger and listen to events within a PHP application", - "homepage": "https://github.com/zendframework/zend-eventmanager", - "keywords": [ - "event", - "eventmanager", - "events", - "zf2" - ], - "time": "2018-04-25T15:33:34+00:00" - }, { "name": "zendframework/zend-stdlib", "version": "3.2.0", @@ -1728,17 +1561,17 @@ }, { "name": "neighborhoods/scaffolding", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "git@github.com:neighborhoods/Scaffolding.git", - "reference": "65773e310df05b1843d554729bbfd99c6f51313e" + "reference": "b054606cbc696cbe369b9b0de217076da3fba6e5" }, "dist": { "type": "tar", - "url": "https://satis.neighborhoods.com/dist/neighborhoods/scaffolding/neighborhoods-scaffolding-65773e310df05b1843d554729bbfd99c6f51313e-zip-134796.tar", - "reference": "65773e310df05b1843d554729bbfd99c6f51313e", - "shasum": "8a8577ab48c9ddb542e1bb8a611629382305b351" + "url": "https://satis.neighborhoods.com/dist/neighborhoods/scaffolding/neighborhoods-scaffolding-b054606cbc696cbe369b9b0de217076da3fba6e5-zip-990c14.tar", + "reference": "b054606cbc696cbe369b9b0de217076da3fba6e5", + "shasum": "71f21e3c52bf74c7acf2d222962ae14fcf876ade" }, "require": { "neighborhoods/pylon": "^1.0.0", @@ -1771,7 +1604,7 @@ } ], "description": "Neighborhoods Scaffolding is meant to make the creation of contract testing easy and fast.", - "time": "2018-05-02T22:49:38+00:00" + "time": "2018-05-22T21:18:48+00:00" }, { "name": "phar-io/manifest", @@ -2144,16 +1977,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "6.0.4", + "version": "6.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "52187754b0eed0b8159f62a6fa30073327e8c2ca" + "reference": "4cab20a326d14de7575a8e235c70d879b569a57a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/52187754b0eed0b8159f62a6fa30073327e8c2ca", - "reference": "52187754b0eed0b8159f62a6fa30073327e8c2ca", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4cab20a326d14de7575a8e235c70d879b569a57a", + "reference": "4cab20a326d14de7575a8e235c70d879b569a57a", "shasum": "" }, "require": { @@ -2203,7 +2036,7 @@ "testing", "xunit" ], - "time": "2018-04-29T14:59:09+00:00" + "time": "2018-05-28T11:49:20+00:00" }, { "name": "phpunit/php-file-iterator", @@ -2473,16 +2306,16 @@ }, { "name": "phpunit/phpunit-mock-objects", - "version": "6.1.1", + "version": "6.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "70c740bde8fd9ea9ea295be1cd875dd7b267e157" + "reference": "f9756fd4f43f014cb2dca98deeaaa8ce5500a36e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/70c740bde8fd9ea9ea295be1cd875dd7b267e157", - "reference": "70c740bde8fd9ea9ea295be1cd875dd7b267e157", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/f9756fd4f43f014cb2dca98deeaaa8ce5500a36e", + "reference": "f9756fd4f43f014cb2dca98deeaaa8ce5500a36e", "shasum": "" }, "require": { @@ -2525,7 +2358,7 @@ "mock", "xunit" ], - "time": "2018-04-11T04:50:36+00:00" + "time": "2018-05-29T13:54:20+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", diff --git a/src/Api/V1/Job/Scheduler/AwareTrait.php b/src/Api/V1/Job/Scheduler/AwareTrait.php index 109e8a7a..08e96639 100644 --- a/src/Api/V1/Job/Scheduler/AwareTrait.php +++ b/src/Api/V1/Job/Scheduler/AwareTrait.php @@ -5,34 +5,37 @@ use Neighborhoods\Kojo\Api\V1\Job\SchedulerInterface; +/** @codeCoverageIgnore */ trait AwareTrait { + protected $NeighborhoodsKojoApiV1JobScheduler; + public function setApiV1JobScheduler(SchedulerInterface $apiV1JobScheduler): self { - $this->_create(SchedulerInterface::class, $apiV1JobScheduler); + assert(!$this->hasApiV1JobScheduler(), + new \LogicException('NeighborhoodsKojoApiV1JobScheduler is already set.')); + $this->NeighborhoodsKojoApiV1JobScheduler = $apiV1JobScheduler; return $this; } - protected function _getApiV1JobScheduler(): SchedulerInterface + protected function getApiV1JobScheduler(): SchedulerInterface { - return $this->_read(SchedulerInterface::class); - } + assert($this->hasApiV1JobScheduler(), new \LogicException('NeighborhoodsKojoApiV1JobScheduler is not set.')); - protected function _getApiV1JobSchedulerClone(): SchedulerInterface - { - return clone $this->_getApiV1JobScheduler(); + return $this->NeighborhoodsKojoApiV1JobScheduler; } - protected function _hasApiV1JobScheduler(): bool + protected function hasApiV1JobScheduler(): bool { - return $this->_exists(SchedulerInterface::class); + return isset($this->NeighborhoodsKojoApiV1JobScheduler); } - protected function _unsetApiV1JobScheduler(): self + protected function unsetApiV1JobScheduler(): self { - $this->_delete(SchedulerInterface::class); + assert($this->hasApiV1JobScheduler(), new \LogicException('NeighborhoodsKojoApiV1JobScheduler is not set.')); + unset($this->NeighborhoodsKojoApiV1JobScheduler); return $this; } -} \ No newline at end of file +} diff --git a/src/Api/V1/Job/Scheduler/Factory.php b/src/Api/V1/Job/Scheduler/Factory.php index acbd2528..e43157ea 100644 --- a/src/Api/V1/Job/Scheduler/Factory.php +++ b/src/Api/V1/Job/Scheduler/Factory.php @@ -15,7 +15,7 @@ class Factory extends FactoryAbstract implements FactoryInterface public function create(): SchedulerInterface { - $apiV1JobScheduler = $this->_getApiV1JobSchedulerClone(); + $apiV1JobScheduler = clone $this->getApiV1JobScheduler(); $apiV1JobScheduler->setServiceCreate($this->_getServiceCreateFactory()->create()); return $apiV1JobScheduler; diff --git a/src/Api/V1/Job/Scheduler/Factory/AwareTrait.php b/src/Api/V1/Job/Scheduler/Factory/AwareTrait.php index b74c6095..cb6ee0c2 100644 --- a/src/Api/V1/Job/Scheduler/Factory/AwareTrait.php +++ b/src/Api/V1/Job/Scheduler/Factory/AwareTrait.php @@ -5,34 +5,39 @@ use Neighborhoods\Kojo\Api\V1\Job\Scheduler\FactoryInterface; +/** @codeCoverageIgnore */ trait AwareTrait { + protected $NeighborhoodsKojoApiV1JobSchedulerFactory; + public function setApiV1JobSchedulerFactory(FactoryInterface $apiV1JobSchedulerFactory): self { - $this->_create(FactoryInterface::class, $apiV1JobSchedulerFactory); + assert(!$this->hasApiV1JobSchedulerFactory(), + new \LogicException('NeighborhoodsKojoApiV1JobSchedulerFactory is already set.')); + $this->NeighborhoodsKojoApiV1JobSchedulerFactory = $apiV1JobSchedulerFactory; return $this; } - protected function _getApiV1JobSchedulerFactoryClone(): FactoryInterface + protected function getApiV1JobSchedulerFactory(): FactoryInterface { - return clone $this->_getApiV1JobSchedulerFactory(); - } + assert($this->hasApiV1JobSchedulerFactory(), + new \LogicException('NeighborhoodsKojoApiV1JobSchedulerFactory is not set.')); - protected function _getApiV1JobSchedulerFactory(): FactoryInterface - { - return $this->_read(FactoryInterface::class); + return $this->NeighborhoodsKojoApiV1JobSchedulerFactory; } - protected function _hasApiV1JobSchedulerFactory(): bool + protected function hasApiV1JobSchedulerFactory(): bool { - return $this->_exists(FactoryInterface::class); + return isset($this->NeighborhoodsKojoApiV1JobSchedulerFactory); } - protected function _unsetApiV1JobSchedulerFactory(): self + protected function unsetApiV1JobSchedulerFactory(): self { - $this->_delete(FactoryInterface::class); + assert($this->hasApiV1JobSchedulerFactory(), + new \LogicException('NeighborhoodsKojoApiV1JobSchedulerFactory is not set.')); + unset($this->NeighborhoodsKojoApiV1JobSchedulerFactory); return $this; } -} \ No newline at end of file +} diff --git a/src/Api/V1/Job/Type/Registrar/AwareTrait.php b/src/Api/V1/Job/Type/Registrar/AwareTrait.php index 62074c44..510238fa 100644 --- a/src/Api/V1/Job/Type/Registrar/AwareTrait.php +++ b/src/Api/V1/Job/Type/Registrar/AwareTrait.php @@ -5,34 +5,39 @@ use Neighborhoods\Kojo\Api\V1\Job\Type\RegistrarInterface; +/** @codeCoverageIgnore */ trait AwareTrait { - public function setApiV1JobTypeRegistrar(RegistrarInterface $ApiV1JobTypeRegistrar): self + protected $NeighborhoodsKojoApiV1JobTypeRegistrar; + + public function setApiV1JobTypeRegistrar(RegistrarInterface $apiV1JobTypeRegistrar): self { - $this->_create(RegistrarInterface::class, $ApiV1JobTypeRegistrar); + assert(!$this->hasApiV1JobTypeRegistrar(), + new \LogicException('NeighborhoodsKojoApiV1JobTypeRegistrar is already set.')); + $this->NeighborhoodsKojoApiV1JobTypeRegistrar = $apiV1JobTypeRegistrar; return $this; } - protected function _getApiV1JobTypeRegistrar(): RegistrarInterface + protected function getApiV1JobTypeRegistrar(): RegistrarInterface { - return $this->_read(RegistrarInterface::class); - } + assert($this->hasApiV1JobTypeRegistrar(), + new \LogicException('NeighborhoodsKojoApiV1JobTypeRegistrar is not set.')); - protected function _getApiV1JobTypeRegistrarClone(): RegistrarInterface - { - return clone $this->_getApiV1JobTypeRegistrar(); + return $this->NeighborhoodsKojoApiV1JobTypeRegistrar; } - protected function _hasApiV1JobTypeRegistrar(): bool + protected function hasApiV1JobTypeRegistrar(): bool { - return $this->_exists(RegistrarInterface::class); + return isset($this->NeighborhoodsKojoApiV1JobTypeRegistrar); } - protected function _unsetApiV1JobTypeRegistrar(): self + protected function unsetApiV1JobTypeRegistrar(): self { - $this->_delete(RegistrarInterface::class); + assert($this->hasApiV1JobTypeRegistrar(), + new \LogicException('NeighborhoodsKojoApiV1JobTypeRegistrar is not set.')); + unset($this->NeighborhoodsKojoApiV1JobTypeRegistrar); return $this; } -} \ No newline at end of file +} diff --git a/src/Api/V1/Job/Type/Registrar/Factory.php b/src/Api/V1/Job/Type/Registrar/Factory.php index 280d9ba8..d8f84bc0 100644 --- a/src/Api/V1/Job/Type/Registrar/Factory.php +++ b/src/Api/V1/Job/Type/Registrar/Factory.php @@ -12,7 +12,7 @@ class Factory extends FactoryAbstract implements FactoryInterface public function create(): RegistrarInterface { - $apiV1JobTypeRegistrar = $this->_getApiV1JobTypeRegistrarClone(); + $apiV1JobTypeRegistrar = clone $this->getApiV1JobTypeRegistrar(); return $apiV1JobTypeRegistrar; } diff --git a/src/Api/V1/Job/Type/Registrar/Factory/AwareTrait.php b/src/Api/V1/Job/Type/Registrar/Factory/AwareTrait.php index c476dd8d..3bac41ea 100644 --- a/src/Api/V1/Job/Type/Registrar/Factory/AwareTrait.php +++ b/src/Api/V1/Job/Type/Registrar/Factory/AwareTrait.php @@ -5,34 +5,39 @@ use Neighborhoods\Kojo\Api\V1\Job\Type\Registrar\FactoryInterface; +/** @codeCoverageIgnore */ trait AwareTrait { + protected $NeighborhoodsKojoApiV1JobTypeRegistrarFactory; + public function setApiV1JobTypeRegistrarFactory(FactoryInterface $apiV1JobTypeRegistrarFactory): self { - $this->_create(FactoryInterface::class, $apiV1JobTypeRegistrarFactory); + assert(!$this->hasApiV1JobTypeRegistrarFactory(), + new \LogicException('NeighborhoodsKojoApiV1JobTypeRegistrarFactory is already set.')); + $this->NeighborhoodsKojoApiV1JobTypeRegistrarFactory = $apiV1JobTypeRegistrarFactory; return $this; } - protected function _getApiV1JobTypeRegistrarFactory(): FactoryInterface + protected function getApiV1JobTypeRegistrarFactory(): FactoryInterface { - return $this->_read(FactoryInterface::class); - } + assert($this->hasApiV1JobTypeRegistrarFactory(), + new \LogicException('NeighborhoodsKojoApiV1JobTypeRegistrarFactory is not set.')); - protected function _getApiV1JobTypeRegistrarFactoryClone(): FactoryInterface - { - return clone $this->_getApiV1JobTypeRegistrarFactory(); + return $this->NeighborhoodsKojoApiV1JobTypeRegistrarFactory; } - protected function _hasApiV1JobTypeRegistrarFactory(): bool + protected function hasApiV1JobTypeRegistrarFactory(): bool { - return $this->_exists(FactoryInterface::class); + return isset($this->NeighborhoodsKojoApiV1JobTypeRegistrarFactory); } - protected function _unsetApiV1JobTypeRegistrarFactory(): self + protected function unsetApiV1JobTypeRegistrarFactory(): self { - $this->_delete(FactoryInterface::class); + assert($this->hasApiV1JobTypeRegistrarFactory(), + new \LogicException('NeighborhoodsKojoApiV1JobTypeRegistrarFactory is not set.')); + unset($this->NeighborhoodsKojoApiV1JobTypeRegistrarFactory); return $this; } -} \ No newline at end of file +} diff --git a/src/Api/V1/Logger/AwareTrait.php b/src/Api/V1/Logger/AwareTrait.php index 9714ed44..46b46c2c 100644 --- a/src/Api/V1/Logger/AwareTrait.php +++ b/src/Api/V1/Logger/AwareTrait.php @@ -5,34 +5,36 @@ use Neighborhoods\Kojo\Api\V1\LoggerInterface; +/** @codeCoverageIgnore */ trait AwareTrait { + protected $NeighborhoodsKojoApiV1Logger; + public function setApiV1Logger(LoggerInterface $apiV1Logger): self { - $this->_create(LoggerInterface::class, $apiV1Logger); + assert(!$this->hasApiV1Logger(), new \LogicException('NeighborhoodsKojoApiV1Logger is already set.')); + $this->NeighborhoodsKojoApiV1Logger = $apiV1Logger; return $this; } - protected function _getApiV1Logger(): LoggerInterface + protected function getApiV1Logger(): LoggerInterface { - return $this->_read(LoggerInterface::class); - } + assert($this->hasApiV1Logger(), new \LogicException('NeighborhoodsKojoApiV1Logger is not set.')); - protected function _getApiV1LoggerClone(): LoggerInterface - { - return clone $this->_getApiV1Logger(); + return $this->NeighborhoodsKojoApiV1Logger; } - protected function _hasApiV1Logger(): bool + protected function hasApiV1Logger(): bool { - return $this->_exists(LoggerInterface::class); + return isset($this->NeighborhoodsKojoApiV1Logger); } - protected function _unsetApiV1Logger(): self + protected function unsetApiV1Logger(): self { - $this->_delete(LoggerInterface::class); + assert($this->hasApiV1Logger(), new \LogicException('NeighborhoodsKojoApiV1Logger is not set.')); + unset($this->NeighborhoodsKojoApiV1Logger); return $this; } -} \ No newline at end of file +} diff --git a/src/Api/V1/Worker/Service.php b/src/Api/V1/Worker/Service.php index 9caa07ca..132cf077 100644 --- a/src/Api/V1/Worker/Service.php +++ b/src/Api/V1/Worker/Service.php @@ -22,13 +22,13 @@ class Service implements ServiceInterface use Update\Complete\Failed\Factory\AwareTrait; use Create\Factory\AwareTrait; use Defensive\AwareTrait; - protected const PROP_REQUEST = 'request'; - protected const PROP_RETRY_DATE_TIME = 'retry_date_time'; - protected const REQUEST_RETRY = 'retry'; - protected const REQUEST_HOLD = 'hold'; + protected const PROP_REQUEST = 'request'; + protected const PROP_RETRY_DATE_TIME = 'retry_date_time'; + protected const REQUEST_RETRY = 'retry'; + protected const REQUEST_HOLD = 'hold'; protected const REQUEST_COMPLETE_SUCCESS = 'complete_success'; - protected const REQUEST_COMPLETE_FAILED = 'complete_failed'; - protected const PROP_REQUEST_APPLIED = 'request_applied'; + protected const REQUEST_COMPLETE_FAILED = 'complete_failed'; + protected const PROP_REQUEST_APPLIED = 'request_applied'; public function requestRetry(\DateTime $retryDateTime): ServiceInterface { @@ -111,7 +111,7 @@ public function isRequestApplied(): bool public function getLogger(): LoggerInterface { - return $this->_getApiV1Logger(); + return $this->getApiV1Logger(); } public function reload(): ServiceInterface @@ -121,6 +121,6 @@ public function reload(): ServiceInterface public function getNewJobScheduler(): SchedulerInterface { - return $this->_getApiV1JobSchedulerFactory()->create(); + return $this->getApiV1JobSchedulerFactory()->create(); } } \ No newline at end of file diff --git a/src/Api/V1/Worker/Service/AwareTrait.php b/src/Api/V1/Worker/Service/AwareTrait.php index d20bdd8a..b1a2b90b 100644 --- a/src/Api/V1/Worker/Service/AwareTrait.php +++ b/src/Api/V1/Worker/Service/AwareTrait.php @@ -5,29 +5,37 @@ use Neighborhoods\Kojo\Api\V1\Worker\ServiceInterface; +/** @codeCoverageIgnore */ trait AwareTrait { - public function setApiV1WorkerService(ServiceInterface $workerService) + protected $NeighborhoodsKojoApiV1WorkerService; + + public function setApiV1WorkerService(ServiceInterface $apiV1WorkerService): self { - $this->_create(ServiceInterface::class, $workerService); + assert(!$this->hasApiV1WorkerService(), + new \LogicException('NeighborhoodsKojoApiV1WorkerService is already set.')); + $this->NeighborhoodsKojoApiV1WorkerService = $apiV1WorkerService; return $this; } - protected function _getApiV1WorkerService(): ServiceInterface + protected function getApiV1WorkerService(): ServiceInterface { - return $this->_read(ServiceInterface::class); + assert($this->hasApiV1WorkerService(), new \LogicException('NeighborhoodsKojoApiV1WorkerService is not set.')); + + return $this->NeighborhoodsKojoApiV1WorkerService; } - protected function _hasApiV1WorkerService(): bool + protected function hasApiV1WorkerService(): bool { - return $this->_exists(ServiceInterface::class); + return isset($this->NeighborhoodsKojoApiV1WorkerService); } - protected function _unsetApiV1WorkerService(): self + protected function unsetApiV1WorkerService(): self { - $this->_delete(ServiceInterface::class); + assert($this->hasApiV1WorkerService(), new \LogicException('NeighborhoodsKojoApiV1WorkerService is not set.')); + unset($this->NeighborhoodsKojoApiV1WorkerService); return $this; } -} \ No newline at end of file +} diff --git a/src/Foreman.php b/src/Foreman.php index c501005f..29623977 100644 --- a/src/Foreman.php +++ b/src/Foreman.php @@ -43,12 +43,11 @@ protected function _workWorker(): ForemanInterface { $this->setJob($this->_getSelector()->getWorkableJob()); $this->_getLocator()->setJob($this->_getJob()); - try{ - $this->_injectWorkerService(); + try { $this->_updateJobAsWorking(); $this->_runWorker(); $this->_updateJobAfterWork(); - }catch(Locator\Exception | \Error $throwable){ + } catch (Locator\Exception | \Error $throwable) { $this->_panicJob(); $jobId = $this->_getJob()->getId(); throw new \RuntimeException("Panicking job with ID[$jobId].", 0, $throwable); @@ -66,7 +65,7 @@ protected function _injectWorkerService(): ForemanInterface { $worker = $this->_getLocator()->getClass(); if (method_exists($worker, 'setApiV1WorkerService')) { - $worker->setApiV1WorkerService($this->_getApiV1WorkerService()->setJob($this->_getJob())); + $worker->setApiV1WorkerService($this->getApiV1WorkerService()->setJob($this->_getJob())); } return $this; @@ -74,14 +73,15 @@ protected function _injectWorkerService(): ForemanInterface protected function _runWorker(): ForemanInterface { - try{ - $this->_getApmNewRelic()->startTransaction(); + try { $className = $this->_getLocator()->getClassName(); $methodName = $this->_getLocator()->getMethodName(); + $this->_getApmNewRelic()->startTransaction(); $this->_getApmNewRelic()->nameTransaction($className . '::' . $methodName); + $this->_injectWorkerService(); call_user_func($this->_getLocator()->getCallable()); $this->_getApmNewRelic()->endTransaction(); - }catch(\Exception $throwable){ + } catch (\Exception $throwable) { $this->_crashJob(); throw $throwable; } @@ -91,11 +91,11 @@ protected function _runWorker(): ForemanInterface protected function _updateJobAsWorking(): ForemanInterface { - try{ + try { $updateWork = $this->_getServiceUpdateWorkFactory()->create(); $updateWork->setJob($this->_getJob()); $updateWork->save(); - }catch(\Exception $exception){ + } catch (\Exception $exception) { $this->_panicJob(); $this->_getSemaphore()->releaseLock($this->_getNewJobOwnerResource($this->_getJob())); throw $exception; @@ -110,8 +110,8 @@ protected function _updateJobAfterWork(): ForemanInterface $updateCompleteSuccess = $this->_getServiceUpdateCompleteSuccessFactory()->create(); $updateCompleteSuccess->setJob($this->_getJob()); $updateCompleteSuccess->save(); - }else { - if (!$this->_getApiV1WorkerService()->isRequestApplied()) { + } else { + if (!$this->getApiV1WorkerService()->isRequestApplied()) { $this->_panicJob(); $jobId = $this->_getJob()->getId(); throw new \LogicException("Worker related to job with ID[$jobId] did not request a next state."); diff --git a/src/Worker/Locator.php b/src/Worker/Locator.php index cbfdd6c4..92109120 100644 --- a/src/Worker/Locator.php +++ b/src/Worker/Locator.php @@ -11,8 +11,6 @@ class Locator implements LocatorInterface { use Job\AwareTrait; use Defensive\AwareTrait; - protected const PROP_METHOD_NAME = 'method_name'; - protected const PROP_CLASS_NAME = 'class_name'; protected $_callable = []; public function getClass() @@ -23,20 +21,18 @@ public function getClass() public function getCallable(): callable { if (empty($this->_callable)) { - try{ - $class = $this->_getJob()->getWorkerUri(); - $method = $this->_getJob()->getWorkerMethod(); - $this->_create(self::PROP_CLASS_NAME, $class); - $this->_create(self::PROP_METHOD_NAME, $method); - $object = new $class; - $callable = [$object, $method]; + try { + $className = $this->getClassName(); + $methodName = $this->getMethodName(); + $object = new $className; + $callable = [$object, $methodName]; if (is_callable($callable)) { $this->_callable = $callable; - }else { - throw new \RuntimeException("Class[$class] and method[$method] is not callable."); + } else { + throw new \RuntimeException("Class[$className] and method[$methodName] is not callable."); } - }catch(\Throwable $throwable){ - throw new Exception($throwable->getMessage(), Exception::CODE_CANNOT_INSTANTIATE_WORKER, $throwable); + } catch (\Throwable $throwable) { + throw new \Exception($throwable->getMessage(), Exception::CODE_CANNOT_INSTANTIATE_WORKER, $throwable); } } @@ -45,11 +41,11 @@ public function getCallable(): callable public function getMethodName(): string { - return $this->_read(self::PROP_METHOD_NAME); + return $this->_getJob()->getWorkerUri(); } public function getClassName(): string { - return $this->_read(self::PROP_CLASS_NAME); + return $this->_getJob()->getWorkerMethod(); } } \ No newline at end of file From 71e3f46e6a5c98650f8d6fc150a57c445d07c074 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Wed, 30 May 2018 09:11:22 -0500 Subject: [PATCH 02/19] Update Example To Be A Fully Working Protean Implementation --- .gitignore | 5 +- Dockerfile | 2 +- docker/xdebug.ini | 2 +- example/Worker.php | 58 ----------------- example/Worker/Delegate/AwareTrait.php | 38 ----------- example/Worker/Delegate/Factory.php | 18 ------ .../Worker/Delegate/Factory/AwareTrait.php | 38 ----------- example/Worker/Delegate/FactoryInterface.php | 11 ---- example/Worker/Delegate/Repository.php | 17 ----- .../Worker/Delegate/Repository/AwareTrait.php | 38 ----------- .../Worker/Delegate/RepositoryInterface.php | 11 ---- example/Worker/DelegateInterface.php | 13 ---- example/Worker/Queue.php | 29 --------- example/Worker/Queue/AwareTrait.php | 40 ------------ example/Worker/Queue/Message.php | 8 --- example/Worker/Queue/Message/AwareTrait.php | 34 ---------- example/Worker/Queue/Message/Factory.php | 19 ------ example/Worker/Queue/MessageInterface.php | 9 --- example/composer.json | 29 +++++++++ .../{ => src/V1}/Environment/Parameters.yml | 0 example/src/V1/Worker.php | 63 +++++++++++++++++++ example/{ => src/V1}/Worker/Delegate.php | 8 +-- example/src/V1/Worker/Delegate/AwareTrait.php | 43 +++++++++++++ example/src/V1/Worker/Delegate/Factory.php | 17 +++++ .../V1/Worker/Delegate/Factory/AwareTrait.php | 43 +++++++++++++ .../V1/Worker/Delegate/FactoryInterface.php | 11 ++++ example/src/V1/Worker/Delegate/Repository.php | 17 +++++ .../Worker/Delegate/Repository/AwareTrait.php | 43 +++++++++++++ .../Worker/Delegate/RepositoryInterface.php | 11 ++++ example/src/V1/Worker/DelegateInterface.php | 13 ++++ example/src/V1/Worker/Queue.php | 63 +++++++++++++++++++ example/src/V1/Worker/Queue/AwareTrait.php | 41 ++++++++++++ example/src/V1/Worker/Queue/Message.php | 55 ++++++++++++++++ .../V1/Worker/Queue/Message/AwareTrait.php | 43 +++++++++++++ .../src/V1/Worker/Queue/Message/Factory.php | 19 ++++++ .../Queue/Message/Factory/AwareTrait.php | 43 +++++++++++++ .../Worker/Queue/Message/FactoryInterface.php | 4 +- .../V1}/Worker/Queue/MessageArray.php | 2 +- .../Worker/Queue/MessageArrayInterface.php | 2 +- .../src/V1/Worker/Queue/MessageInterface.php | 14 +++++ .../{ => src/V1}/Worker/QueueInterface.php | 4 +- example/{ => src/V1}/WorkerInterface.php | 2 +- 42 files changed, 585 insertions(+), 395 deletions(-) delete mode 100644 example/Worker.php delete mode 100644 example/Worker/Delegate/AwareTrait.php delete mode 100644 example/Worker/Delegate/Factory.php delete mode 100644 example/Worker/Delegate/Factory/AwareTrait.php delete mode 100644 example/Worker/Delegate/FactoryInterface.php delete mode 100644 example/Worker/Delegate/Repository.php delete mode 100644 example/Worker/Delegate/Repository/AwareTrait.php delete mode 100644 example/Worker/Delegate/RepositoryInterface.php delete mode 100644 example/Worker/DelegateInterface.php delete mode 100644 example/Worker/Queue.php delete mode 100644 example/Worker/Queue/AwareTrait.php delete mode 100644 example/Worker/Queue/Message.php delete mode 100644 example/Worker/Queue/Message/AwareTrait.php delete mode 100644 example/Worker/Queue/Message/Factory.php delete mode 100644 example/Worker/Queue/MessageInterface.php create mode 100644 example/composer.json rename example/{ => src/V1}/Environment/Parameters.yml (100%) create mode 100644 example/src/V1/Worker.php rename example/{ => src/V1}/Worker/Delegate.php (57%) create mode 100644 example/src/V1/Worker/Delegate/AwareTrait.php create mode 100644 example/src/V1/Worker/Delegate/Factory.php create mode 100644 example/src/V1/Worker/Delegate/Factory/AwareTrait.php create mode 100644 example/src/V1/Worker/Delegate/FactoryInterface.php create mode 100644 example/src/V1/Worker/Delegate/Repository.php create mode 100644 example/src/V1/Worker/Delegate/Repository/AwareTrait.php create mode 100644 example/src/V1/Worker/Delegate/RepositoryInterface.php create mode 100644 example/src/V1/Worker/DelegateInterface.php create mode 100644 example/src/V1/Worker/Queue.php create mode 100644 example/src/V1/Worker/Queue/AwareTrait.php create mode 100644 example/src/V1/Worker/Queue/Message.php create mode 100644 example/src/V1/Worker/Queue/Message/AwareTrait.php create mode 100644 example/src/V1/Worker/Queue/Message/Factory.php create mode 100644 example/src/V1/Worker/Queue/Message/Factory/AwareTrait.php rename example/{ => src/V1}/Worker/Queue/Message/FactoryInterface.php (52%) rename example/{ => src/V1}/Worker/Queue/MessageArray.php (96%) rename example/{ => src/V1}/Worker/Queue/MessageArrayInterface.php (92%) create mode 100644 example/src/V1/Worker/Queue/MessageInterface.php rename example/{ => src/V1}/Worker/QueueInterface.php (66%) rename example/{ => src/V1}/WorkerInterface.php (72%) diff --git a/.gitignore b/.gitignore index 0a90e5ae..0f2ef456 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ vendor/ +example/vendor/ .composer/ -phpunit.xml \ No newline at end of file +phpunit.xml +scratch/ +data/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 3a2272b9..b4f79bf1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,4 +26,4 @@ RUN bash docker/build.sh \ #CMD ["php-fpm"] -EXPOSE 9000 \ No newline at end of file +EXPOSE 9001 \ No newline at end of file diff --git a/docker/xdebug.ini b/docker/xdebug.ini index 976bd78b..10bc73eb 100644 --- a/docker/xdebug.ini +++ b/docker/xdebug.ini @@ -7,5 +7,5 @@ xdebug.remote_enable=1 xdebug.remote_autostart=1 xdebug.remote_connect_back=0 xdebug.remote_mode=req -xdebug.remote_port=9000 +xdebug.remote_port=9001 xdebug.remote_host=docker.for.mac.localhost \ No newline at end of file diff --git a/example/Worker.php b/example/Worker.php deleted file mode 100644 index ee8e319a..00000000 --- a/example/Worker.php +++ /dev/null @@ -1,58 +0,0 @@ -_getWorkerQueue()->waitForNextMessage(); - - // Schedule another job of the same type. -// $this->_scheduleNextJob(); - - // Delegate the work for the first message. -// $this->_delegateWork(); -// -// // Delegate the work until the observed Queue is empty. -// while ($this->_getWorkerQueue()->hasNextMessage()) { -// $this->_delegateWork(); -// } -// - // Tell Kōjō that we are done and all is well. - $this->_getApiV1WorkerService()->requestCompleteSuccess()->applyRequest(); - - // Fluent interfaces for the love of Pete. - return $this; - } - - protected function _delegateWork(): WorkerInterface - { - $workerDelegate = $this->_getWorkerDelegateRepository()->getNewWorkerDelegate(); - $workerDelegate->setWorkerQueueMessage($this->_getWorkerQueue()->getNextMessage()); - $workerDelegate->businessLogic(); - - return $this; - } - - protected function _scheduleNextJob(): WorkerInterface - { - $newJobScheduler = $this->_getApiV1WorkerService()->getNewJobScheduler(); - $newJobScheduler->setJobTypeCode(self::JOB_TYPE_CODE) - ->setWorkAtDateTime(new \DateTime('now')) - ->save(); - - return $this; - } -} \ No newline at end of file diff --git a/example/Worker/Delegate/AwareTrait.php b/example/Worker/Delegate/AwareTrait.php deleted file mode 100644 index f4bcc1b5..00000000 --- a/example/Worker/Delegate/AwareTrait.php +++ /dev/null @@ -1,38 +0,0 @@ -_create(DelegateInterface::class, $workerDelegate); - - return $this; - } - - protected function _getWorkerDelegate(): DelegateInterface - { - return $this->_read(DelegateInterface::class); - } - - protected function _getWorkerDelegateClone(): DelegateInterface - { - return clone $this->_getWorkerDelegate(); - } - - protected function _hasWorkerDelegate(): bool - { - return $this->_exists(DelegateInterface::class); - } - - protected function _unsetWorkerDelegate(): self - { - $this->_delete(DelegateInterface::class); - - return $this; - } -} \ No newline at end of file diff --git a/example/Worker/Delegate/Factory.php b/example/Worker/Delegate/Factory.php deleted file mode 100644 index a09a1a9e..00000000 --- a/example/Worker/Delegate/Factory.php +++ /dev/null @@ -1,18 +0,0 @@ -_getWorkerDelegateClone(); - - return $workerDelegate; - } -} \ No newline at end of file diff --git a/example/Worker/Delegate/Factory/AwareTrait.php b/example/Worker/Delegate/Factory/AwareTrait.php deleted file mode 100644 index eadce7a8..00000000 --- a/example/Worker/Delegate/Factory/AwareTrait.php +++ /dev/null @@ -1,38 +0,0 @@ -_create(FactoryInterface::class, $workerDelegateFactory); - - return $this; - } - - protected function _getWorkerDelegateFactory(): FactoryInterface - { - return $this->_read(FactoryInterface::class); - } - - protected function _getWorkerDelegateFactoryClone(): FactoryInterface - { - return clone $this->_getWorkerDelegateFactory(); - } - - protected function _hasWorkerDelegateFactory(): bool - { - return $this->_exists(FactoryInterface::class); - } - - protected function _unsetWorkerDelegateFactory(): self - { - $this->_delete(FactoryInterface::class); - - return $this; - } -} \ No newline at end of file diff --git a/example/Worker/Delegate/FactoryInterface.php b/example/Worker/Delegate/FactoryInterface.php deleted file mode 100644 index 0bbcf684..00000000 --- a/example/Worker/Delegate/FactoryInterface.php +++ /dev/null @@ -1,11 +0,0 @@ -_getWorkerDelegateFactory()->create(); - } -} \ No newline at end of file diff --git a/example/Worker/Delegate/Repository/AwareTrait.php b/example/Worker/Delegate/Repository/AwareTrait.php deleted file mode 100644 index bf9269ec..00000000 --- a/example/Worker/Delegate/Repository/AwareTrait.php +++ /dev/null @@ -1,38 +0,0 @@ -_create(RepositoryInterface::class, $workerDelegateRepository); - - return $this; - } - - protected function _getWorkerDelegateRepository(): RepositoryInterface - { - return $this->_read(RepositoryInterface::class); - } - - protected function _getWorkerDelegateRepositoryClone(): RepositoryInterface - { - return clone $this->_getWorkerDelegateRepository(); - } - - protected function _hasWorkerDelegateRepository(): bool - { - return $this->_exists(RepositoryInterface::class); - } - - protected function _unsetWorkerDelegateRepository(): self - { - $this->_delete(RepositoryInterface::class); - - return $this; - } -} \ No newline at end of file diff --git a/example/Worker/Delegate/RepositoryInterface.php b/example/Worker/Delegate/RepositoryInterface.php deleted file mode 100644 index fea46b52..00000000 --- a/example/Worker/Delegate/RepositoryInterface.php +++ /dev/null @@ -1,11 +0,0 @@ -_getWorkerQueueMessageClone(); - } - - public function waitForNextMessage(): QueueInterface - { - sleep(random_int(0, 10)); - - return $this; - } - - public function hasNextMessage(): bool - { - return (random_int(0, 5) === 5); - } -} \ No newline at end of file diff --git a/example/Worker/Queue/AwareTrait.php b/example/Worker/Queue/AwareTrait.php deleted file mode 100644 index b1febb18..00000000 --- a/example/Worker/Queue/AwareTrait.php +++ /dev/null @@ -1,40 +0,0 @@ -hasWorkerQueue(), new \LogicException('NeighborhoodsKojoExampleWorkerQueue is already set.')); - $this->NeighborhoodsKojoExampleWorkerQueue = $workerQueue; - - return $this; - } - - protected function getWorkerQueue(): QueueInterface - { - assert($this->hasWorkerQueue(), new \LogicException('NeighborhoodsKojoExampleWorkerQueue is not set.')); - - return $this->NeighborhoodsKojoExampleWorkerQueue; - } - - protected function hasWorkerQueue(): bool - { - return isset($this->NeighborhoodsKojoExampleWorkerQueue); - } - - protected function unsetWorkerQueue(): self - { - assert($this->hasWorkerQueue(), new \LogicException('NeighborhoodsKojoExampleWorkerQueue is not set.')); - unset($this->NeighborhoodsKojoExampleWorkerQueue); - - return $this; - } -} diff --git a/example/Worker/Queue/Message.php b/example/Worker/Queue/Message.php deleted file mode 100644 index 20378efa..00000000 --- a/example/Worker/Queue/Message.php +++ /dev/null @@ -1,8 +0,0 @@ -_create(MessageInterface::class, $workerQueueMessage); - - return $this; - } - - protected function getWorkerQueueMessage(): MessageInterface - { - return $this->_read(MessageInterface::class); - } - - protected function hasWorkerQueueMessage(): bool - { - return $this->_exists(MessageInterface::class); - } - - protected function unsetWorkerQueueMessage(): self - { - $this->_delete(MessageInterface::class); - - return $this; - } -} diff --git a/example/Worker/Queue/Message/Factory.php b/example/Worker/Queue/Message/Factory.php deleted file mode 100644 index cff8881f..00000000 --- a/example/Worker/Queue/Message/Factory.php +++ /dev/null @@ -1,19 +0,0 @@ -getWorkerQueueMessage(); - } -} diff --git a/example/Worker/Queue/MessageInterface.php b/example/Worker/Queue/MessageInterface.php deleted file mode 100644 index 7ed9d952..00000000 --- a/example/Worker/Queue/MessageInterface.php +++ /dev/null @@ -1,9 +0,0 @@ -=7.1", + "neighborhoods/kojo": "^2.0.0", + "aws/aws-sdk-php": "2.*" + }, + "autoload": { + "psr-4": { + "Neighborhoods\\KojoExample\\": "src" + } + } +} \ No newline at end of file diff --git a/example/Environment/Parameters.yml b/example/src/V1/Environment/Parameters.yml similarity index 100% rename from example/Environment/Parameters.yml rename to example/src/V1/Environment/Parameters.yml diff --git a/example/src/V1/Worker.php b/example/src/V1/Worker.php new file mode 100644 index 00000000..64c9067d --- /dev/null +++ b/example/src/V1/Worker.php @@ -0,0 +1,63 @@ +bootstrap(); + + // Wait for one message to become available. + $this->getV1WorkerQueue()->waitForNextMessage(); + + // Schedule another kōjō job of the same type. + $this->_scheduleNextJob(); + + // Delegate the work for the first message. + $this->_delegateWork(); + + // Delegate the work until the observed Queue is empty. + while ($this->getV1WorkerQueue()->hasNextMessage()) { + $this->_delegateWork(); + } + + // Tell Kōjō that we are done and all is well. + $this->getApiV1WorkerService()->requestCompleteSuccess()->applyRequest(); + + // Fluent interfaces for the love of Pete. + return $this; + } + + protected function bootstrap(): WorkerInterface + { + return $this; + } + + protected function _delegateWork(): WorkerInterface + { + $workerDelegate = $this->getV1WorkerDelegateRepository()->getV1NewWorkerDelegate(); + $workerDelegate->setV1WorkerQueueMessage($this->getV1WorkerQueue()->getNextMessage()); + $workerDelegate->businessLogic(); + + return $this; + } + + protected function _scheduleNextJob(): WorkerInterface + { + $newJobScheduler = $this->getApiV1WorkerService()->getNewJobScheduler(); + $newJobScheduler->setJobTypeCode(self::JOB_TYPE_CODE) + ->setWorkAtDateTime(new \DateTime('now')) + ->save(); + + return $this; + } +} \ No newline at end of file diff --git a/example/Worker/Delegate.php b/example/src/V1/Worker/Delegate.php similarity index 57% rename from example/Worker/Delegate.php rename to example/src/V1/Worker/Delegate.php index 21791e0d..25b874ef 100644 --- a/example/Worker/Delegate.php +++ b/example/src/V1/Worker/Delegate.php @@ -1,18 +1,18 @@ getV1WorkerQueueMessage()->delete(); + return $this; } } \ No newline at end of file diff --git a/example/src/V1/Worker/Delegate/AwareTrait.php b/example/src/V1/Worker/Delegate/AwareTrait.php new file mode 100644 index 00000000..23826c9c --- /dev/null +++ b/example/src/V1/Worker/Delegate/AwareTrait.php @@ -0,0 +1,43 @@ +hasV1WorkerDelegate(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerDelegate is already set.')); + $this->NeighborhoodsKojoExampleV1WorkerDelegate = $v1WorkerDelegate; + + return $this; + } + + protected function getV1WorkerDelegate(): DelegateInterface + { + assert($this->hasV1WorkerDelegate(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerDelegate is not set.')); + + return $this->NeighborhoodsKojoExampleV1WorkerDelegate; + } + + protected function hasV1WorkerDelegate(): bool + { + return isset($this->NeighborhoodsKojoExampleV1WorkerDelegate); + } + + protected function unsetV1WorkerDelegate(): self + { + assert($this->hasV1WorkerDelegate(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerDelegate is not set.')); + unset($this->NeighborhoodsKojoExampleV1WorkerDelegate); + + return $this; + } +} diff --git a/example/src/V1/Worker/Delegate/Factory.php b/example/src/V1/Worker/Delegate/Factory.php new file mode 100644 index 00000000..5adcc8cd --- /dev/null +++ b/example/src/V1/Worker/Delegate/Factory.php @@ -0,0 +1,17 @@ +getV1WorkerDelegate(); + } +} diff --git a/example/src/V1/Worker/Delegate/Factory/AwareTrait.php b/example/src/V1/Worker/Delegate/Factory/AwareTrait.php new file mode 100644 index 00000000..8266cb66 --- /dev/null +++ b/example/src/V1/Worker/Delegate/Factory/AwareTrait.php @@ -0,0 +1,43 @@ +hasV1WorkerDelegateFactory(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerDelegateFactory is already set.')); + $this->NeighborhoodsKojoExampleV1WorkerDelegateFactory = $v1WorkerDelegateFactory; + + return $this; + } + + protected function getV1WorkerDelegateFactory(): FactoryInterface + { + assert($this->hasV1WorkerDelegateFactory(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerDelegateFactory is not set.')); + + return $this->NeighborhoodsKojoExampleV1WorkerDelegateFactory; + } + + protected function hasV1WorkerDelegateFactory(): bool + { + return isset($this->NeighborhoodsKojoExampleV1WorkerDelegateFactory); + } + + protected function unsetV1WorkerDelegateFactory(): self + { + assert($this->hasV1WorkerDelegateFactory(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerDelegateFactory is not set.')); + unset($this->NeighborhoodsKojoExampleV1WorkerDelegateFactory); + + return $this; + } +} diff --git a/example/src/V1/Worker/Delegate/FactoryInterface.php b/example/src/V1/Worker/Delegate/FactoryInterface.php new file mode 100644 index 00000000..b3923c18 --- /dev/null +++ b/example/src/V1/Worker/Delegate/FactoryInterface.php @@ -0,0 +1,11 @@ +getV1WorkerDelegateFactory()->create(); + } +} \ No newline at end of file diff --git a/example/src/V1/Worker/Delegate/Repository/AwareTrait.php b/example/src/V1/Worker/Delegate/Repository/AwareTrait.php new file mode 100644 index 00000000..4661861b --- /dev/null +++ b/example/src/V1/Worker/Delegate/Repository/AwareTrait.php @@ -0,0 +1,43 @@ +hasV1WorkerDelegateRepository(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerDelegateRepository is already set.')); + $this->NeighborhoodsKojoExampleV1WorkerDelegateRepository = $v1WorkerDelegateRepository; + + return $this; + } + + protected function getV1WorkerDelegateRepository(): RepositoryInterface + { + assert($this->hasV1WorkerDelegateRepository(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerDelegateRepository is not set.')); + + return $this->NeighborhoodsKojoExampleV1WorkerDelegateRepository; + } + + protected function hasV1WorkerDelegateRepository(): bool + { + return isset($this->NeighborhoodsKojoExampleV1WorkerDelegateRepository); + } + + protected function unsetV1WorkerDelegateRepository(): self + { + assert($this->hasV1WorkerDelegateRepository(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerDelegateRepository is not set.')); + unset($this->NeighborhoodsKojoExampleV1WorkerDelegateRepository); + + return $this; + } +} diff --git a/example/src/V1/Worker/Delegate/RepositoryInterface.php b/example/src/V1/Worker/Delegate/RepositoryInterface.php new file mode 100644 index 00000000..cd841796 --- /dev/null +++ b/example/src/V1/Worker/Delegate/RepositoryInterface.php @@ -0,0 +1,11 @@ +getV1WorkerQueueMessage(); + } + + public function waitForNextMessage(): QueueInterface + { + $this->unsetV1WorkerQueueMessage(); + $guzzleServiceResourceModel = $this->getSqsClient()->receiveMessage(); + while (empty($guzzleServiceResourceModel)) { + $guzzleServiceResourceModel = $this->getSqsClient()->receiveMessage(); + } + $this->createNextMessage($guzzleServiceResourceModel); + + return $this; + } + + public function hasNextMessage(): bool + { + if (!$this->hasV1WorkerQueueMessage()) { + if (!empty($guzzleServiceResourceModel = $this->getSqsClient()->receiveMessage())) { + $this->createNextMessage($guzzleServiceResourceModel); + } + } + + return $this->hasV1WorkerQueueMessage(); + } + + protected function getSqsClient(): SqsClient + { + if ($this->sqsClient === null) { + $this->sqsClient = SqsClient::factory(); + } + + return $this->sqsClient; + } + + protected function createNextMessage(Model $guzzleServiceResourceModel): QueueInterface + { + $v1WorkerQueueMessage = $this->getV1WorkerQueueMessageFactory()->create(); + $v1WorkerQueueMessage->setGuzzleServiceResourceModel($guzzleServiceResourceModel); + $this->setV1WorkerQueueMessage($v1WorkerQueueMessage); + + return $this; + } +} \ No newline at end of file diff --git a/example/src/V1/Worker/Queue/AwareTrait.php b/example/src/V1/Worker/Queue/AwareTrait.php new file mode 100644 index 00000000..718def0b --- /dev/null +++ b/example/src/V1/Worker/Queue/AwareTrait.php @@ -0,0 +1,41 @@ +hasV1WorkerQueue(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerQueue is already set.')); + $this->NeighborhoodsKojoExampleV1WorkerQueue = $v1WorkerQueue; + + return $this; + } + + protected function getV1WorkerQueue(): QueueInterface + { + assert($this->hasV1WorkerQueue(), new \LogicException('NeighborhoodsKojoExampleV1WorkerQueue is not set.')); + + return $this->NeighborhoodsKojoExampleV1WorkerQueue; + } + + protected function hasV1WorkerQueue(): bool + { + return isset($this->NeighborhoodsKojoExampleV1WorkerQueue); + } + + protected function unsetV1WorkerQueue(): self + { + assert($this->hasV1WorkerQueue(), new \LogicException('NeighborhoodsKojoExampleV1WorkerQueue is not set.')); + unset($this->NeighborhoodsKojoExampleV1WorkerQueue); + + return $this; + } +} diff --git a/example/src/V1/Worker/Queue/Message.php b/example/src/V1/Worker/Queue/Message.php new file mode 100644 index 00000000..941f0faf --- /dev/null +++ b/example/src/V1/Worker/Queue/Message.php @@ -0,0 +1,55 @@ +GuzzleServiceResourceModel === null) { + $this->GuzzleServiceResourceModel = $guzzleServiceResourceModel; + } + + return $this; + } + + protected function getGuzzleServiceResourceModel(): Model + { + if ($this->GuzzleServiceResourceModel === null) { + throw new \LogicException('GuzzleServiceResourceModel is not set.'); + } + + return $this->GuzzleServiceResourceModel; + } + + public function delete(): MessageInterface + { + if ($this->isDeleted !== false) { + throw new \LogicException('Message is already deleted.'); + } + $this->getSqsClient()->deleteMessage([ + 'QueueUrl' => $this->getGuzzleServiceResourceModel()->get('QueueUrl'), + 'ReceiptHandle' => $this->getGuzzleServiceResourceModel()->get('ReceiptHandle'), + ]); + $this->isDeleted = true; + + return $this; + } + + protected function getSqsClient(): SqsClient + { + if ($this->sqsClient === null) { + $this->sqsClient = SqsClient::factory(); + } + + return $this->sqsClient; + } +} \ No newline at end of file diff --git a/example/src/V1/Worker/Queue/Message/AwareTrait.php b/example/src/V1/Worker/Queue/Message/AwareTrait.php new file mode 100644 index 00000000..f375d4db --- /dev/null +++ b/example/src/V1/Worker/Queue/Message/AwareTrait.php @@ -0,0 +1,43 @@ +hasV1WorkerQueueMessage(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerQueueMessage is already set.')); + $this->NeighborhoodsKojoExampleV1WorkerQueueMessage = $v1WorkerQueueMessage; + + return $this; + } + + protected function getV1WorkerQueueMessage(): MessageInterface + { + assert($this->hasV1WorkerQueueMessage(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerQueueMessage is not set.')); + + return $this->NeighborhoodsKojoExampleV1WorkerQueueMessage; + } + + protected function hasV1WorkerQueueMessage(): bool + { + return isset($this->NeighborhoodsKojoExampleV1WorkerQueueMessage); + } + + protected function unsetV1WorkerQueueMessage(): self + { + assert($this->hasV1WorkerQueueMessage(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerQueueMessage is not set.')); + unset($this->NeighborhoodsKojoExampleV1WorkerQueueMessage); + + return $this; + } +} diff --git a/example/src/V1/Worker/Queue/Message/Factory.php b/example/src/V1/Worker/Queue/Message/Factory.php new file mode 100644 index 00000000..24705e2b --- /dev/null +++ b/example/src/V1/Worker/Queue/Message/Factory.php @@ -0,0 +1,19 @@ +getV1WorkerQueueMessage(); + } +} diff --git a/example/src/V1/Worker/Queue/Message/Factory/AwareTrait.php b/example/src/V1/Worker/Queue/Message/Factory/AwareTrait.php new file mode 100644 index 00000000..a25f71f6 --- /dev/null +++ b/example/src/V1/Worker/Queue/Message/Factory/AwareTrait.php @@ -0,0 +1,43 @@ +hasV1WorkerQueueMessageFactory(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerQueueMessageFactory is already set.')); + $this->NeighborhoodsKojoExampleV1WorkerQueueMessageFactory = $v1WorkerQueueMessageFactory; + + return $this; + } + + protected function getV1WorkerQueueMessageFactory(): FactoryInterface + { + assert($this->hasV1WorkerQueueMessageFactory(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerQueueMessageFactory is not set.')); + + return $this->NeighborhoodsKojoExampleV1WorkerQueueMessageFactory; + } + + protected function hasV1WorkerQueueMessageFactory(): bool + { + return isset($this->NeighborhoodsKojoExampleV1WorkerQueueMessageFactory); + } + + protected function unsetV1WorkerQueueMessageFactory(): self + { + assert($this->hasV1WorkerQueueMessageFactory(), + new \LogicException('NeighborhoodsKojoExampleV1WorkerQueueMessageFactory is not set.')); + unset($this->NeighborhoodsKojoExampleV1WorkerQueueMessageFactory); + + return $this; + } +} diff --git a/example/Worker/Queue/Message/FactoryInterface.php b/example/src/V1/Worker/Queue/Message/FactoryInterface.php similarity index 52% rename from example/Worker/Queue/Message/FactoryInterface.php rename to example/src/V1/Worker/Queue/Message/FactoryInterface.php index c7cd3d80..87f58787 100644 --- a/example/Worker/Queue/Message/FactoryInterface.php +++ b/example/src/V1/Worker/Queue/Message/FactoryInterface.php @@ -1,9 +1,9 @@ Date: Wed, 30 May 2018 16:05:13 -0500 Subject: [PATCH 03/19] Updates To Example To Be A Fully Working Protean Implementation --- example/composer.json | 3 +- example/src/V1/Aws/Sqs/SqsClient.yml | 14 +++++ .../src/V1/Aws/Sqs/SqsClient/AwareTrait.php | 43 ++++++++++++++++ .../Service/Resource/Model/AwareTrait.php | 43 ++++++++++++++++ example/src/V1/Worker/Queue.php | 51 ++++++++++++------- example/src/V1/Worker/Queue.yml | 12 +++++ example/src/V1/Worker/Queue/Message.php | 43 ++++------------ example/src/V1/Worker/Queue/Message.yml | 10 ++++ .../src/V1/Worker/Queue/Message/Factory.yml | 10 ++++ .../src/V1/Worker/Queue/MessageInterface.php | 3 +- 10 files changed, 178 insertions(+), 54 deletions(-) create mode 100644 example/src/V1/Aws/Sqs/SqsClient.yml create mode 100644 example/src/V1/Aws/Sqs/SqsClient/AwareTrait.php create mode 100644 example/src/V1/Guzzle/Service/Resource/Model/AwareTrait.php create mode 100644 example/src/V1/Worker/Queue.yml create mode 100644 example/src/V1/Worker/Queue/Message.yml create mode 100644 example/src/V1/Worker/Queue/Message/Factory.yml diff --git a/example/composer.json b/example/composer.json index b7191455..8e7297bd 100644 --- a/example/composer.json +++ b/example/composer.json @@ -19,7 +19,8 @@ "require": { "php": ">=7.1", "neighborhoods/kojo": "^2.0.0", - "aws/aws-sdk-php": "2.*" + "aws/aws-sdk-php": "2.*", + "neighborhoods/pylon": "^1.0.0" }, "autoload": { "psr-4": { diff --git a/example/src/V1/Aws/Sqs/SqsClient.yml b/example/src/V1/Aws/Sqs/SqsClient.yml new file mode 100644 index 00000000..92830f07 --- /dev/null +++ b/example/src/V1/Aws/Sqs/SqsClient.yml @@ -0,0 +1,14 @@ +parameters: + neighborhoods.kojo_example.v1.aws.sqs.sqs_client.region: '%env(SQS_REGION)%' +services: + neighborhoods.kojo_example.v1.aws.sqs.sqs_client: + class: Aws\Sqs\SqsClient + public: false + shared: false + factory: [Aws\Sqs\SqsClient, factory] + arguments: + - + region: '%neighborhoods.kojo_example.v1.aws.sqs.sqs_client.region%' + v1.aws.sqs.sqs_client: + alias: neighborhoods.kojo_example.v1.aws.sqs.sqs_client + public: false \ No newline at end of file diff --git a/example/src/V1/Aws/Sqs/SqsClient/AwareTrait.php b/example/src/V1/Aws/Sqs/SqsClient/AwareTrait.php new file mode 100644 index 00000000..0dbc8a15 --- /dev/null +++ b/example/src/V1/Aws/Sqs/SqsClient/AwareTrait.php @@ -0,0 +1,43 @@ +hasV1AwsSqsSqsClient(), + new \LogicException('NeighborhoodsKojoExampleV1AwsSqsSqsClient is already set.')); + $this->NeighborhoodsKojoExampleV1AwsSqsSqsClient = $v1AwsSqsSqsClient; + + return $this; + } + + protected function getV1AwsSqsSqsClient(): SqsClient + { + assert($this->hasV1AwsSqsSqsClient(), + new \LogicException('NeighborhoodsKojoExampleV1AwsSqsSqsClient is not set.')); + + return $this->NeighborhoodsKojoExampleV1AwsSqsSqsClient; + } + + protected function hasV1AwsSqsSqsClient(): bool + { + return isset($this->NeighborhoodsKojoExampleV1AwsSqsSqsClient); + } + + protected function unsetV1AwsSqsSqsClient(): self + { + assert($this->hasV1AwsSqsSqsClient(), + new \LogicException('NeighborhoodsKojoExampleV1AwsSqsSqsClient is not set.')); + unset($this->NeighborhoodsKojoExampleV1AwsSqsSqsClient); + + return $this; + } +} diff --git a/example/src/V1/Guzzle/Service/Resource/Model/AwareTrait.php b/example/src/V1/Guzzle/Service/Resource/Model/AwareTrait.php new file mode 100644 index 00000000..b3f6d5da --- /dev/null +++ b/example/src/V1/Guzzle/Service/Resource/Model/AwareTrait.php @@ -0,0 +1,43 @@ +hasV1GuzzleServiceResourceModel(), + new \LogicException('NeighborhoodsKojoExampleV1GuzzleServiceResourceModel is already set.')); + $this->NeighborhoodsKojoExampleV1GuzzleServiceResourceModel = $v1GuzzleServiceResourceModel; + + return $this; + } + + protected function getV1GuzzleServiceResourceModel(): Model + { + assert($this->hasV1GuzzleServiceResourceModel(), + new \LogicException('NeighborhoodsKojoExampleV1GuzzleServiceResourceModel is not set.')); + + return $this->NeighborhoodsKojoExampleV1GuzzleServiceResourceModel; + } + + protected function hasV1GuzzleServiceResourceModel(): bool + { + return isset($this->NeighborhoodsKojoExampleV1GuzzleServiceResourceModel); + } + + protected function unsetV1GuzzleServiceResourceModel(): self + { + assert($this->hasV1GuzzleServiceResourceModel(), + new \LogicException('NeighborhoodsKojoExampleV1GuzzleServiceResourceModel is not set.')); + unset($this->NeighborhoodsKojoExampleV1GuzzleServiceResourceModel); + + return $this; + } +} diff --git a/example/src/V1/Worker/Queue.php b/example/src/V1/Worker/Queue.php index 4ae2a0b4..eb157d2e 100644 --- a/example/src/V1/Worker/Queue.php +++ b/example/src/V1/Worker/Queue.php @@ -3,17 +3,17 @@ namespace Neighborhoods\KojoExample\V1\Worker; -use Aws\Sqs\SqsClient; use Guzzle\Service\Resource\Model; -use Neighborhoods\KojoExample\V1\Worker; +use Neighborhoods\KojoExample\V1; use Neighborhoods\KojoExample\V1\Worker\Queue\MessageInterface; class Queue implements QueueInterface { - use Worker\Queue\Message\Factory\AwareTrait; - use Worker\Queue\Message\AwareTrait; + use V1\Worker\Queue\Message\Factory\AwareTrait; + use V1\Worker\Queue\Message\AwareTrait; + use V1\Aws\Sqs\SqsClient\AwareTrait; - protected $sqsClient; + protected $queueUrl; public function getNextMessage(): MessageInterface { @@ -23,9 +23,9 @@ public function getNextMessage(): MessageInterface public function waitForNextMessage(): QueueInterface { $this->unsetV1WorkerQueueMessage(); - $guzzleServiceResourceModel = $this->getSqsClient()->receiveMessage(); + $guzzleServiceResourceModel = $this->receiveMessage(); while (empty($guzzleServiceResourceModel)) { - $guzzleServiceResourceModel = $this->getSqsClient()->receiveMessage(); + $guzzleServiceResourceModel = $this->receiveMessage(); } $this->createNextMessage($guzzleServiceResourceModel); @@ -35,7 +35,8 @@ public function waitForNextMessage(): QueueInterface public function hasNextMessage(): bool { if (!$this->hasV1WorkerQueueMessage()) { - if (!empty($guzzleServiceResourceModel = $this->getSqsClient()->receiveMessage())) { + $messages = $guzzleServiceResourceModel = $this->receiveMessage()->get('Messages'); + if (!empty($messages)) { $this->createNextMessage($guzzleServiceResourceModel); } } @@ -43,21 +44,37 @@ public function hasNextMessage(): bool return $this->hasV1WorkerQueueMessage(); } - protected function getSqsClient(): SqsClient + protected function createNextMessage(Model $guzzleServiceResourceModel): QueueInterface { - if ($this->sqsClient === null) { - $this->sqsClient = SqsClient::factory(); - } + $v1WorkerQueueMessage = $this->getV1WorkerQueueMessageFactory()->create(); + $v1WorkerQueueMessage->setV1GuzzleServiceResourceModel($guzzleServiceResourceModel); + $this->setV1WorkerQueueMessage($v1WorkerQueueMessage); - return $this->sqsClient; + return $this; } - protected function createNextMessage(Model $guzzleServiceResourceModel): QueueInterface + protected function receiveMessage(): Model { - $v1WorkerQueueMessage = $this->getV1WorkerQueueMessageFactory()->create(); - $v1WorkerQueueMessage->setGuzzleServiceResourceModel($guzzleServiceResourceModel); - $this->setV1WorkerQueueMessage($v1WorkerQueueMessage); + return $this->getV1AwsSqsSqsClient()->receiveMessage(['QueueUrl' => $this->getQueueUrl()]); + } + + public function setQueueUrl(string $queueUrl): QueueInterface + { + if ($this->queueUrl === null) { + $this->queueUrl = $queueUrl; + } else { + throw new \LogicException('Queue URL is not set.'); + } return $this; } + + protected function getQueueUrl(): string + { + if ($this->queueUrl === null) { + throw new \LogicException('Queue URL is not set.'); + } + + return $this->queueUrl; + } } \ No newline at end of file diff --git a/example/src/V1/Worker/Queue.yml b/example/src/V1/Worker/Queue.yml new file mode 100644 index 00000000..3b2f2ef8 --- /dev/null +++ b/example/src/V1/Worker/Queue.yml @@ -0,0 +1,12 @@ +services: + neighborhoods.kojo_example.v1.worker.queue: + class: Neighborhoods\KojoExample\V1\Worker\Queue + public: true + shared: false + calls: + - [setV1WorkerQueueMessageFactory, ['@v1.worker.queue.message.factory']] + - [setV1AwsSqsSqsClient, ['@v1.aws.sqs.sqs_client']] + - [setQueueUrl, ['https://sqs.us-east-1.amazonaws.com/272157948465/local-bwilson']] + v1.worker.queue: + alias: neighborhoods.kojo_example.v1.worker.queue + public: true \ No newline at end of file diff --git a/example/src/V1/Worker/Queue/Message.php b/example/src/V1/Worker/Queue/Message.php index 941f0faf..44460d04 100644 --- a/example/src/V1/Worker/Queue/Message.php +++ b/example/src/V1/Worker/Queue/Message.php @@ -3,53 +3,28 @@ namespace Neighborhoods\KojoExample\V1\Worker\Queue; -use Aws\Sqs\SqsClient; -use Guzzle\Service\Resource\Model; +use Neighborhoods\KojoExample\V1; class Message implements MessageInterface { - protected $GuzzleServiceResourceModel; - protected $sqsClient; + use V1\Guzzle\Service\Resource\Model\AwareTrait; + use V1\Aws\Sqs\SqsClient\AwareTrait; protected $isDeleted = false; - - public function setGuzzleServiceResourceModel(Model $guzzleServiceResourceModel): MessageInterface - { - if ($this->GuzzleServiceResourceModel === null) { - $this->GuzzleServiceResourceModel = $guzzleServiceResourceModel; - } - - return $this; - } - - protected function getGuzzleServiceResourceModel(): Model - { - if ($this->GuzzleServiceResourceModel === null) { - throw new \LogicException('GuzzleServiceResourceModel is not set.'); - } - - return $this->GuzzleServiceResourceModel; - } + protected const SQS_CLIENT_QUEUE_URL = 'QueueUrl'; + protected const SQS_CLIENT_RECEIPT_HANDLE = 'ReceiptHandle'; public function delete(): MessageInterface { if ($this->isDeleted !== false) { throw new \LogicException('Message is already deleted.'); } - $this->getSqsClient()->deleteMessage([ - 'QueueUrl' => $this->getGuzzleServiceResourceModel()->get('QueueUrl'), - 'ReceiptHandle' => $this->getGuzzleServiceResourceModel()->get('ReceiptHandle'), + $sqsClientReceiptHandle = $this->getV1GuzzleServiceResourceModel()->get(self::SQS_CLIENT_RECEIPT_HANDLE); + $this->getV1AwsSqsSqsClient()->deleteMessage([ + self::SQS_CLIENT_QUEUE_URL => $this->getV1GuzzleServiceResourceModel()->get(self::SQS_CLIENT_QUEUE_URL), + self::SQS_CLIENT_RECEIPT_HANDLE => $sqsClientReceiptHandle, ]); $this->isDeleted = true; return $this; } - - protected function getSqsClient(): SqsClient - { - if ($this->sqsClient === null) { - $this->sqsClient = SqsClient::factory(); - } - - return $this->sqsClient; - } } \ No newline at end of file diff --git a/example/src/V1/Worker/Queue/Message.yml b/example/src/V1/Worker/Queue/Message.yml new file mode 100644 index 00000000..1e8fbb2f --- /dev/null +++ b/example/src/V1/Worker/Queue/Message.yml @@ -0,0 +1,10 @@ +services: + neighborhoods.kojo_example.v1.worker.queue.message: + class: Neighborhoods\KojoExample\V1\Worker\Queue\Message + public: false + shared: false + calls: + - [setV1AwsSqsSqsClient, ['@v1.aws.sqs.sqs_client']] + v1.worker.queue.message: + alias: neighborhoods.kojo_example.v1.worker.queue.message + public: true \ No newline at end of file diff --git a/example/src/V1/Worker/Queue/Message/Factory.yml b/example/src/V1/Worker/Queue/Message/Factory.yml new file mode 100644 index 00000000..f114f523 --- /dev/null +++ b/example/src/V1/Worker/Queue/Message/Factory.yml @@ -0,0 +1,10 @@ +services: + neighborhoods.kojo_example.v1.worker.queue.message.factory: + class: Neighborhoods\KojoExample\V1\Worker\Queue\Message\Factory + public: false + shared: true + calls: + - [setV1WorkerQueueMessage, ['@v1.worker.queue.message']] + v1.worker.queue.message.factory: + alias: neighborhoods.kojo_example.v1.worker.queue.message.factory + public: true \ No newline at end of file diff --git a/example/src/V1/Worker/Queue/MessageInterface.php b/example/src/V1/Worker/Queue/MessageInterface.php index e48544a9..64136b09 100644 --- a/example/src/V1/Worker/Queue/MessageInterface.php +++ b/example/src/V1/Worker/Queue/MessageInterface.php @@ -7,8 +7,7 @@ interface MessageInterface { - - public function setGuzzleServiceResourceModel(Model $guzzleServiceResourceModel): MessageInterface; + public function setV1GuzzleServiceResourceModel(Model $guzzleServiceResourceModel); public function delete(): MessageInterface; } \ No newline at end of file From abb85204c75289d262c395399f531c9876f3aa78 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Wed, 30 May 2018 17:58:30 -0500 Subject: [PATCH 04/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- example/src/V1/Worker/Queue.php | 13 +++++---- example/src/V1/Worker/Queue.yml | 4 ++- example/src/V1/Worker/Queue/Message.php | 28 +++++++++++++++++-- example/src/V1/Worker/Queue/Message.yml | 1 + .../src/V1/Worker/Queue/MessageInterface.php | 2 ++ 5 files changed, 39 insertions(+), 9 deletions(-) diff --git a/example/src/V1/Worker/Queue.php b/example/src/V1/Worker/Queue.php index eb157d2e..86469e04 100644 --- a/example/src/V1/Worker/Queue.php +++ b/example/src/V1/Worker/Queue.php @@ -15,6 +15,9 @@ class Queue implements QueueInterface protected $queueUrl; + protected const QUEUE_URL = 'QueueUrl'; + protected const MESSAGES = 'Messages'; + public function getNextMessage(): MessageInterface { return $this->getV1WorkerQueueMessage(); @@ -24,7 +27,7 @@ public function waitForNextMessage(): QueueInterface { $this->unsetV1WorkerQueueMessage(); $guzzleServiceResourceModel = $this->receiveMessage(); - while (empty($guzzleServiceResourceModel)) { + while ($guzzleServiceResourceModel->get(self::MESSAGES) === null) { $guzzleServiceResourceModel = $this->receiveMessage(); } $this->createNextMessage($guzzleServiceResourceModel); @@ -35,8 +38,8 @@ public function waitForNextMessage(): QueueInterface public function hasNextMessage(): bool { if (!$this->hasV1WorkerQueueMessage()) { - $messages = $guzzleServiceResourceModel = $this->receiveMessage()->get('Messages'); - if (!empty($messages)) { + $guzzleServiceResourceModel = $this->receiveMessage(); + if ($guzzleServiceResourceModel->get(self::MESSAGES) !== null) { $this->createNextMessage($guzzleServiceResourceModel); } } @@ -55,7 +58,7 @@ protected function createNextMessage(Model $guzzleServiceResourceModel): QueueIn protected function receiveMessage(): Model { - return $this->getV1AwsSqsSqsClient()->receiveMessage(['QueueUrl' => $this->getQueueUrl()]); + return $this->getV1AwsSqsSqsClient()->receiveMessage([self::QUEUE_URL => $this->getQueueUrl()]); } public function setQueueUrl(string $queueUrl): QueueInterface @@ -63,7 +66,7 @@ public function setQueueUrl(string $queueUrl): QueueInterface if ($this->queueUrl === null) { $this->queueUrl = $queueUrl; } else { - throw new \LogicException('Queue URL is not set.'); + throw new \LogicException('Queue URL is already set.'); } return $this; diff --git a/example/src/V1/Worker/Queue.yml b/example/src/V1/Worker/Queue.yml index 3b2f2ef8..1c3dd238 100644 --- a/example/src/V1/Worker/Queue.yml +++ b/example/src/V1/Worker/Queue.yml @@ -1,3 +1,5 @@ +parameters: + neighborhoods.kojo_example.v1.worker.queue.queue_url: 'https://sqs.us-east-1.amazonaws.com/272157948465/local-bwilson' services: neighborhoods.kojo_example.v1.worker.queue: class: Neighborhoods\KojoExample\V1\Worker\Queue @@ -6,7 +8,7 @@ services: calls: - [setV1WorkerQueueMessageFactory, ['@v1.worker.queue.message.factory']] - [setV1AwsSqsSqsClient, ['@v1.aws.sqs.sqs_client']] - - [setQueueUrl, ['https://sqs.us-east-1.amazonaws.com/272157948465/local-bwilson']] + - [setQueueUrl, ['%neighborhoods.kojo_example.v1.worker.queue.queue_url%']] v1.worker.queue: alias: neighborhoods.kojo_example.v1.worker.queue public: true \ No newline at end of file diff --git a/example/src/V1/Worker/Queue/Message.php b/example/src/V1/Worker/Queue/Message.php index 44460d04..46555af0 100644 --- a/example/src/V1/Worker/Queue/Message.php +++ b/example/src/V1/Worker/Queue/Message.php @@ -10,6 +10,8 @@ class Message implements MessageInterface use V1\Guzzle\Service\Resource\Model\AwareTrait; use V1\Aws\Sqs\SqsClient\AwareTrait; protected $isDeleted = false; + protected $queueUrl; + protected const SQS_CLIENT_QUEUE_URL = 'QueueUrl'; protected const SQS_CLIENT_RECEIPT_HANDLE = 'ReceiptHandle'; @@ -18,13 +20,33 @@ public function delete(): MessageInterface if ($this->isDeleted !== false) { throw new \LogicException('Message is already deleted.'); } - $sqsClientReceiptHandle = $this->getV1GuzzleServiceResourceModel()->get(self::SQS_CLIENT_RECEIPT_HANDLE); + $messages = $this->getV1GuzzleServiceResourceModel()->get('Messages'); + $receiptHandle = $messages[0][self::SQS_CLIENT_RECEIPT_HANDLE]; $this->getV1AwsSqsSqsClient()->deleteMessage([ - self::SQS_CLIENT_QUEUE_URL => $this->getV1GuzzleServiceResourceModel()->get(self::SQS_CLIENT_QUEUE_URL), - self::SQS_CLIENT_RECEIPT_HANDLE => $sqsClientReceiptHandle, + self::SQS_CLIENT_QUEUE_URL => $this->getQueueUrl(), + self::SQS_CLIENT_RECEIPT_HANDLE => $receiptHandle, ]); $this->isDeleted = true; return $this; } + + protected function getQueueUrl() + { + if ($this->queueUrl === null) { + throw new \LogicException('Queue URL has not been set.'); + } + + return $this->queueUrl; + } + + public function setQueueUrl($queueUrl): MessageInterface + { + if ($this->queueUrl !== null) { + throw new \LogicException('Queue URL already set.'); + } + $this->queueUrl = $queueUrl; + + return $this; + } } \ No newline at end of file diff --git a/example/src/V1/Worker/Queue/Message.yml b/example/src/V1/Worker/Queue/Message.yml index 1e8fbb2f..76ee5215 100644 --- a/example/src/V1/Worker/Queue/Message.yml +++ b/example/src/V1/Worker/Queue/Message.yml @@ -5,6 +5,7 @@ services: shared: false calls: - [setV1AwsSqsSqsClient, ['@v1.aws.sqs.sqs_client']] + - [setQueueUrl, ['%neighborhoods.kojo_example.v1.worker.queue.queue_url%']] v1.worker.queue.message: alias: neighborhoods.kojo_example.v1.worker.queue.message public: true \ No newline at end of file diff --git a/example/src/V1/Worker/Queue/MessageInterface.php b/example/src/V1/Worker/Queue/MessageInterface.php index 64136b09..6b901425 100644 --- a/example/src/V1/Worker/Queue/MessageInterface.php +++ b/example/src/V1/Worker/Queue/MessageInterface.php @@ -10,4 +10,6 @@ interface MessageInterface public function setV1GuzzleServiceResourceModel(Model $guzzleServiceResourceModel); public function delete(): MessageInterface; + + public function setQueueUrl($queueUrl): MessageInterface; } \ No newline at end of file From ba7dab5c50bab634dc01a51f0d24f80277d87ddf Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Wed, 30 May 2018 18:31:15 -0500 Subject: [PATCH 05/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- example/src/V1/Worker.php | 11 +--- example/src/V1/Worker.yml | 8 +++ example/src/V1/Worker/Delegate.yml | 5 ++ example/src/V1/Worker/Delegate/Factory.yml | 7 +++ example/src/V1/Worker/Delegate/Repository.yml | 7 +++ example/src/V1/Worker/Facade.php | 54 +++++++++++++++++++ example/src/V1/Worker/FacadeInterface.php | 9 ++++ example/src/V1/Worker/Queue.php | 6 ++- 8 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 example/src/V1/Worker.yml create mode 100644 example/src/V1/Worker/Delegate.yml create mode 100644 example/src/V1/Worker/Delegate/Factory.yml create mode 100644 example/src/V1/Worker/Delegate/Repository.yml create mode 100644 example/src/V1/Worker/Facade.php create mode 100644 example/src/V1/Worker/FacadeInterface.php diff --git a/example/src/V1/Worker.php b/example/src/V1/Worker.php index 64c9067d..402dfa6a 100644 --- a/example/src/V1/Worker.php +++ b/example/src/V1/Worker.php @@ -14,13 +14,11 @@ class Worker implements WorkerInterface public function work(): WorkerInterface { - $this->bootstrap(); - // Wait for one message to become available. $this->getV1WorkerQueue()->waitForNextMessage(); // Schedule another kōjō job of the same type. - $this->_scheduleNextJob(); +// $this->_scheduleNextJob(); // Delegate the work for the first message. $this->_delegateWork(); @@ -31,17 +29,12 @@ public function work(): WorkerInterface } // Tell Kōjō that we are done and all is well. - $this->getApiV1WorkerService()->requestCompleteSuccess()->applyRequest(); +// $this->getApiV1WorkerService()->requestCompleteSuccess()->applyRequest(); // Fluent interfaces for the love of Pete. return $this; } - protected function bootstrap(): WorkerInterface - { - return $this; - } - protected function _delegateWork(): WorkerInterface { $workerDelegate = $this->getV1WorkerDelegateRepository()->getV1NewWorkerDelegate(); diff --git a/example/src/V1/Worker.yml b/example/src/V1/Worker.yml new file mode 100644 index 00000000..63878827 --- /dev/null +++ b/example/src/V1/Worker.yml @@ -0,0 +1,8 @@ +services: + neighborhoods.kojo_example.v1.worker: + class: Neighborhoods\KojoExample\V1\Worker + public: true + shared: false + calls: + - [setV1WorkerDelegateRepository, ['@neighborhoods.kojo_example.v1.worker.delegate.repository']] + - [setV1WorkerQueue, ['@neighborhoods.kojo_example.v1.worker.queue']] \ No newline at end of file diff --git a/example/src/V1/Worker/Delegate.yml b/example/src/V1/Worker/Delegate.yml new file mode 100644 index 00000000..f08d63fa --- /dev/null +++ b/example/src/V1/Worker/Delegate.yml @@ -0,0 +1,5 @@ +services: + neighborhoods.kojo_example.v1.worker.delegate: + class: Neighborhoods\KojoExample\V1\Worker\Delegate + public: false + shared: false \ No newline at end of file diff --git a/example/src/V1/Worker/Delegate/Factory.yml b/example/src/V1/Worker/Delegate/Factory.yml new file mode 100644 index 00000000..3b2fc298 --- /dev/null +++ b/example/src/V1/Worker/Delegate/Factory.yml @@ -0,0 +1,7 @@ +services: + neighborhoods.kojo_example.v1.worker.delegate.factory: + class: Neighborhoods\KojoExample\V1\Worker\Delegate\Factory + public: false + shared: true + calls: + - [setV1WorkerDelegate, ['@neighborhoods.kojo_example.v1.worker.delegate']] \ No newline at end of file diff --git a/example/src/V1/Worker/Delegate/Repository.yml b/example/src/V1/Worker/Delegate/Repository.yml new file mode 100644 index 00000000..a79f5be0 --- /dev/null +++ b/example/src/V1/Worker/Delegate/Repository.yml @@ -0,0 +1,7 @@ +services: + neighborhoods.kojo_example.v1.worker.delegate.repository: + class: Neighborhoods\KojoExample\V1\Worker\Delegate\Repository + public: false + shared: true + calls: + - [setV1WorkerDelegateFactory, ['@neighborhoods.kojo_example.v1.worker.delegate.factory']] \ No newline at end of file diff --git a/example/src/V1/Worker/Facade.php b/example/src/V1/Worker/Facade.php new file mode 100644 index 00000000..14286c32 --- /dev/null +++ b/example/src/V1/Worker/Facade.php @@ -0,0 +1,54 @@ +bootstrap(); + $this->getWorker()->work(); + + return $this; + } + + protected function bootstrap(): FacadeInterface + { + $containerBuilderFacade = new DependencyInjection\ContainerBuilder\Facade(); + $discoverableDirectories[] = __DIR__ . '/../../../src'; + $finder = new Finder(); + $finder->name('*.yml'); + $finder->files()->in($discoverableDirectories); + $containerBuilderFacade->addFinder($finder); + $containerBuilder = $containerBuilderFacade->getContainerBuilder(); + $this->setWorker($containerBuilder->get('neighborhoods.kojo_example.v1.worker')); + + return $this; + } + + public function getWorker(): WorkerInterface + { + if ($this->worker === null) { + throw new \LogicException('Worker has not been set.'); + } + + return $this->worker; + } + + public function setWorker(WorkerInterface $worker): FacadeInterface + { + if ($this->worker !== null) { + throw new \LogicException('Worker already set.'); + } + $this->worker = $worker; + + return $this; + } +} \ No newline at end of file diff --git a/example/src/V1/Worker/FacadeInterface.php b/example/src/V1/Worker/FacadeInterface.php new file mode 100644 index 00000000..781e3697 --- /dev/null +++ b/example/src/V1/Worker/FacadeInterface.php @@ -0,0 +1,9 @@ +getV1WorkerQueueMessage(); + $v1WorkerQueueMessage = $this->getV1WorkerQueueMessage(); + $this->unsetV1WorkerQueueMessage(); + + return $v1WorkerQueueMessage; } public function waitForNextMessage(): QueueInterface { - $this->unsetV1WorkerQueueMessage(); $guzzleServiceResourceModel = $this->receiveMessage(); while ($guzzleServiceResourceModel->get(self::MESSAGES) === null) { $guzzleServiceResourceModel = $this->receiveMessage(); From 702b00a5627bc0e8084cc6886a32e6c756419666 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Wed, 30 May 2018 18:34:19 -0500 Subject: [PATCH 06/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- example/README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 example/README.md diff --git a/example/README.md b/example/README.md new file mode 100644 index 00000000..452f3ae6 --- /dev/null +++ b/example/README.md @@ -0,0 +1,22 @@ +# Example Protean Compliant Kōjō DLC Pattern + +`scratch/worker-facade.php` +```php +start(); +} catch (\Throwable $throwable) { + echo $throwable->getMessage(); +} + +return; +``` \ No newline at end of file From 0bd04526b4c3cd85d80a53570e21d92e59249384 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Wed, 30 May 2018 18:35:14 -0500 Subject: [PATCH 07/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- example/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/example/README.md b/example/README.md index 452f3ae6..0c38ac91 100644 --- a/example/README.md +++ b/example/README.md @@ -1,5 +1,7 @@ # Example Protean Compliant Kōjō DLC Pattern +SQS Queue Name: `local-bwilson` + `scratch/worker-facade.php` ```php Date: Wed, 30 May 2018 19:38:49 -0500 Subject: [PATCH 08/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- example/src/V1/Worker/Facade.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/example/src/V1/Worker/Facade.php b/example/src/V1/Worker/Facade.php index 14286c32..037abd97 100644 --- a/example/src/V1/Worker/Facade.php +++ b/example/src/V1/Worker/Facade.php @@ -10,6 +10,7 @@ class Facade implements FacadeInterface { protected $worker; + protected $isBootStrapped = false; public function start(): FacadeInterface { @@ -21,6 +22,9 @@ public function start(): FacadeInterface protected function bootstrap(): FacadeInterface { + if ($this->isBootStrapped !== false) { + throw new \LogicException('Worker facade is already bootstrapped.'); + } $containerBuilderFacade = new DependencyInjection\ContainerBuilder\Facade(); $discoverableDirectories[] = __DIR__ . '/../../../src'; $finder = new Finder(); @@ -29,6 +33,7 @@ protected function bootstrap(): FacadeInterface $containerBuilderFacade->addFinder($finder); $containerBuilder = $containerBuilderFacade->getContainerBuilder(); $this->setWorker($containerBuilder->get('neighborhoods.kojo_example.v1.worker')); + $this->isBootStrapped = true; return $this; } @@ -36,7 +41,7 @@ protected function bootstrap(): FacadeInterface public function getWorker(): WorkerInterface { if ($this->worker === null) { - throw new \LogicException('Worker has not been set.'); + throw new \LogicException('Worker is not set.'); } return $this->worker; @@ -45,7 +50,7 @@ public function getWorker(): WorkerInterface public function setWorker(WorkerInterface $worker): FacadeInterface { if ($this->worker !== null) { - throw new \LogicException('Worker already set.'); + throw new \LogicException('Worker is already set.'); } $this->worker = $worker; From 2210b61ef9833b98336e95d992eb756e72c222c1 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Thu, 31 May 2018 09:13:45 -0500 Subject: [PATCH 09/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- example/src/V1/Worker/Facade.php | 4 ++-- example/src/V1/Worker/FacadeInterface.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/example/src/V1/Worker/Facade.php b/example/src/V1/Worker/Facade.php index 037abd97..b9f56a70 100644 --- a/example/src/V1/Worker/Facade.php +++ b/example/src/V1/Worker/Facade.php @@ -38,7 +38,7 @@ protected function bootstrap(): FacadeInterface return $this; } - public function getWorker(): WorkerInterface + protected function getWorker(): WorkerInterface { if ($this->worker === null) { throw new \LogicException('Worker is not set.'); @@ -47,7 +47,7 @@ public function getWorker(): WorkerInterface return $this->worker; } - public function setWorker(WorkerInterface $worker): FacadeInterface + protected function setWorker(WorkerInterface $worker): FacadeInterface { if ($this->worker !== null) { throw new \LogicException('Worker is already set.'); diff --git a/example/src/V1/Worker/FacadeInterface.php b/example/src/V1/Worker/FacadeInterface.php index 781e3697..f295e348 100644 --- a/example/src/V1/Worker/FacadeInterface.php +++ b/example/src/V1/Worker/FacadeInterface.php @@ -5,5 +5,5 @@ interface FacadeInterface { - + public function start(): FacadeInterface; } \ No newline at end of file From 7807f21c58bf87eece17f0d426857f65de735cf0 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Thu, 31 May 2018 09:17:35 -0500 Subject: [PATCH 10/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- example/bin/create-messages.php | 23 +++++++++++++++++++++++ example/bin/worker-facade.php | 17 +++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 example/bin/create-messages.php create mode 100644 example/bin/worker-facade.php diff --git a/example/bin/create-messages.php b/example/bin/create-messages.php new file mode 100644 index 00000000..20e0f395 --- /dev/null +++ b/example/bin/create-messages.php @@ -0,0 +1,23 @@ + 'us-east-1'] +); + +$totalNumberOfMessagesToSend = 12000; +$messageCount = 0; +while ($messageCount !== $totalNumberOfMessagesToSend) { + $client->sendMessage(array( + 'QueueUrl' => 'https://sqs.us-east-1.amazonaws.com/272157948465/local-bwilson', + 'MessageBody' => 'MESSAGE BODY', + )); + + ++$messageCount; +} + +return; \ No newline at end of file diff --git a/example/bin/worker-facade.php b/example/bin/worker-facade.php new file mode 100644 index 00000000..87814255 --- /dev/null +++ b/example/bin/worker-facade.php @@ -0,0 +1,17 @@ +start(); +} catch (\Throwable $throwable) { + echo $throwable->getMessage(); +} + +return; \ No newline at end of file From 2b4f59728524dda871adc38202291d7b31d4cf77 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Thu, 31 May 2018 09:24:08 -0500 Subject: [PATCH 11/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- example/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/README.md b/example/README.md index 0c38ac91..444c4479 100644 --- a/example/README.md +++ b/example/README.md @@ -2,7 +2,7 @@ SQS Queue Name: `local-bwilson` -`scratch/worker-facade.php` +`bin/worker-facade.php` ```php Date: Thu, 31 May 2018 11:02:31 -0500 Subject: [PATCH 12/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- .gitignore | 5 +- example/composer.json | 11 +- example/src/V1/Worker.php | 4 +- example/src/V1/Worker/Facade.php | 12 +- example/tests/Application/Db/Setup.yml | 4 + example/tests/Application/Db/TearDown.yml | 4 + .../Application/Environment/Parameters.yml | 13 + example/tests/Application/Foreman.yml | 4 + example/tests/Application/PDO/Builder.yml | 4 + example/tests/Application/Process/Job.yml | 4 + .../Application/Process/Strategy/Mock.php | 14 + example/tests/Application/Redis/Factory.yml | 4 + example/tests/Application/Selector.yml | 4 + example/tests/Application/Worker/Mock.php | 12 + .../BehaviorSmokeTest/BehaviorSmokeTest.php | 27 + .../dataSet1/fixtures/1_job_types.yml | 14 + .../dataSet1/fixtures/2_jobs.yml | 4180 +++++++++++++++++ .../dataSet2/fixtures/1_job_type.yml | 14 + .../dataSet2/fixtures/2_job.yml | 1001 ++++ .../dataSet3/fixtures/1_job_type.yml | 14 + .../dataSet3/fixtures/2_jobs.yml | 1001 ++++ src/Data/Status/MessageInterface.php | 18 + src/Data/Status/TypeInterface.php | 13 + tests/BehaviorSmokeTest/BehaviorSmokeTest.php | 2 +- 24 files changed, 6372 insertions(+), 11 deletions(-) create mode 100644 example/tests/Application/Db/Setup.yml create mode 100644 example/tests/Application/Db/TearDown.yml create mode 100644 example/tests/Application/Environment/Parameters.yml create mode 100644 example/tests/Application/Foreman.yml create mode 100644 example/tests/Application/PDO/Builder.yml create mode 100644 example/tests/Application/Process/Job.yml create mode 100644 example/tests/Application/Process/Strategy/Mock.php create mode 100644 example/tests/Application/Redis/Factory.yml create mode 100644 example/tests/Application/Selector.yml create mode 100644 example/tests/Application/Worker/Mock.php create mode 100644 example/tests/BehaviorSmokeTest/BehaviorSmokeTest.php create mode 100644 example/tests/BehaviorSmokeTest/dataSet1/fixtures/1_job_types.yml create mode 100644 example/tests/BehaviorSmokeTest/dataSet1/fixtures/2_jobs.yml create mode 100644 example/tests/BehaviorSmokeTest/dataSet2/fixtures/1_job_type.yml create mode 100644 example/tests/BehaviorSmokeTest/dataSet2/fixtures/2_job.yml create mode 100644 example/tests/BehaviorSmokeTest/dataSet3/fixtures/1_job_type.yml create mode 100644 example/tests/BehaviorSmokeTest/dataSet3/fixtures/2_jobs.yml create mode 100644 src/Data/Status/MessageInterface.php create mode 100644 src/Data/Status/TypeInterface.php diff --git a/.gitignore b/.gitignore index 0f2ef456..0a90e5ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ vendor/ -example/vendor/ .composer/ -phpunit.xml -scratch/ -data/ \ No newline at end of file +phpunit.xml \ No newline at end of file diff --git a/example/composer.json b/example/composer.json index 8e7297bd..4194cd66 100644 --- a/example/composer.json +++ b/example/composer.json @@ -19,12 +19,17 @@ "require": { "php": ">=7.1", "neighborhoods/kojo": "^2.0.0", - "aws/aws-sdk-php": "2.*", - "neighborhoods/pylon": "^1.0.0" + "neighborhoods/pylon": "^1.0.0", + "aws/aws-sdk-php": "2.*" + }, + "require-dev": { + "php": ">=7.1", + "neighborhoods/scaffolding": "^1.0.0" }, "autoload": { "psr-4": { - "Neighborhoods\\KojoExample\\": "src" + "Neighborhoods\\KojoExample\\": "src", + "Neighborhoods\\KojoExampleTest\\": "tests" } } } \ No newline at end of file diff --git a/example/src/V1/Worker.php b/example/src/V1/Worker.php index 402dfa6a..82372026 100644 --- a/example/src/V1/Worker.php +++ b/example/src/V1/Worker.php @@ -18,7 +18,7 @@ public function work(): WorkerInterface $this->getV1WorkerQueue()->waitForNextMessage(); // Schedule another kōjō job of the same type. -// $this->_scheduleNextJob(); + $this->_scheduleNextJob(); // Delegate the work for the first message. $this->_delegateWork(); @@ -29,7 +29,7 @@ public function work(): WorkerInterface } // Tell Kōjō that we are done and all is well. -// $this->getApiV1WorkerService()->requestCompleteSuccess()->applyRequest(); + $this->getApiV1WorkerService()->requestCompleteSuccess()->applyRequest(); // Fluent interfaces for the love of Pete. return $this; diff --git a/example/src/V1/Worker/Facade.php b/example/src/V1/Worker/Facade.php index b9f56a70..1a96942f 100644 --- a/example/src/V1/Worker/Facade.php +++ b/example/src/V1/Worker/Facade.php @@ -9,6 +9,7 @@ class Facade implements FacadeInterface { + protected $containerBuilderFacade; protected $worker; protected $isBootStrapped = false; @@ -25,7 +26,7 @@ protected function bootstrap(): FacadeInterface if ($this->isBootStrapped !== false) { throw new \LogicException('Worker facade is already bootstrapped.'); } - $containerBuilderFacade = new DependencyInjection\ContainerBuilder\Facade(); + $containerBuilderFacade = $this->getContainerBuilderFacade(); $discoverableDirectories[] = __DIR__ . '/../../../src'; $finder = new Finder(); $finder->name('*.yml'); @@ -38,6 +39,15 @@ protected function bootstrap(): FacadeInterface return $this; } + public function getContainerBuilderFacade(): DependencyInjection\ContainerBuilder\Facade + { + if ($this->containerBuilderFacade === null) { + $this->containerBuilderFacade = new DependencyInjection\ContainerBuilder\Facade(); + } + + return $this->containerBuilderFacade; + } + protected function getWorker(): WorkerInterface { if ($this->worker === null) { diff --git a/example/tests/Application/Db/Setup.yml b/example/tests/Application/Db/Setup.yml new file mode 100644 index 00000000..3ad370e8 --- /dev/null +++ b/example/tests/Application/Db/Setup.yml @@ -0,0 +1,4 @@ +services: + db.setup: + public: true + alias: neighborhoods.kojo.db.setup \ No newline at end of file diff --git a/example/tests/Application/Db/TearDown.yml b/example/tests/Application/Db/TearDown.yml new file mode 100644 index 00000000..8112468b --- /dev/null +++ b/example/tests/Application/Db/TearDown.yml @@ -0,0 +1,4 @@ +services: + db.tear_down: + public: true + alias: neighborhoods.kojo.db.tear_down \ No newline at end of file diff --git a/example/tests/Application/Environment/Parameters.yml b/example/tests/Application/Environment/Parameters.yml new file mode 100644 index 00000000..009fd245 --- /dev/null +++ b/example/tests/Application/Environment/Parameters.yml @@ -0,0 +1,13 @@ +parameters: + neighborhoods.kojo.environment.parameters.redis_port: '%env(REDIS_PORT)%' + neighborhoods.kojo.environment.parameters.redis_host: '%env(REDIS_HOST)%' + neighborhoods.kojo.environment.parameters.database_user_name: '%env(DATABASE_USERNAME)%' + neighborhoods.kojo.environment.parameters.database_password: '%env(DATABASE_PASSWORD)%' + neighborhoods.kojo.environment.parameters.database_adapter: '%env(DATABASE_ADAPTER)%' + neighborhoods.kojo.environment.parameters.database_host: '%env(DATABASE_HOST)%' + neighborhoods.kojo.environment.parameters.database_name: '%env(DATABASE_NAME)%' +# neighborhoods.kojo.environment.parameters.database_user_name: 'nhds' +# neighborhoods.kojo.environment.parameters.database_password: 'nhds2016' +# neighborhoods.kojo.environment.parameters.database_adapter: 'pgsql' +# neighborhoods.kojo.environment.parameters.database_host: 'pgsql' +# neighborhoods.kojo.environment.parameters.database_name: 'kojo' \ No newline at end of file diff --git a/example/tests/Application/Foreman.yml b/example/tests/Application/Foreman.yml new file mode 100644 index 00000000..56e7f800 --- /dev/null +++ b/example/tests/Application/Foreman.yml @@ -0,0 +1,4 @@ +services: + foreman: + public: true + alias: neighborhoods.kojo.foreman \ No newline at end of file diff --git a/example/tests/Application/PDO/Builder.yml b/example/tests/Application/PDO/Builder.yml new file mode 100644 index 00000000..c26c5a5a --- /dev/null +++ b/example/tests/Application/PDO/Builder.yml @@ -0,0 +1,4 @@ +services: + pdo.builder: + public: true + alias: neighborhoods.kojo.pdo.builder \ No newline at end of file diff --git a/example/tests/Application/Process/Job.yml b/example/tests/Application/Process/Job.yml new file mode 100644 index 00000000..3debd31c --- /dev/null +++ b/example/tests/Application/Process/Job.yml @@ -0,0 +1,4 @@ +services: + process.job: + public: true + alias: neighborhoods.kojo.process.job \ No newline at end of file diff --git a/example/tests/Application/Process/Strategy/Mock.php b/example/tests/Application/Process/Strategy/Mock.php new file mode 100644 index 00000000..c2119ef1 --- /dev/null +++ b/example/tests/Application/Process/Strategy/Mock.php @@ -0,0 +1,14 @@ + Date: Thu, 31 May 2018 11:48:37 -0500 Subject: [PATCH 13/19] Fix Locator --- src/Worker/Locator.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Worker/Locator.php b/src/Worker/Locator.php index 92109120..9ed994de 100644 --- a/src/Worker/Locator.php +++ b/src/Worker/Locator.php @@ -32,7 +32,10 @@ public function getCallable(): callable throw new \RuntimeException("Class[$className] and method[$methodName] is not callable."); } } catch (\Throwable $throwable) { - throw new \Exception($throwable->getMessage(), Exception::CODE_CANNOT_INSTANTIATE_WORKER, $throwable); + throw (new Exception( + $throwable->getMessage(), + $throwable + ))->setCode(Exception::CODE_CANNOT_INSTANTIATE_WORKER); } } @@ -41,11 +44,11 @@ public function getCallable(): callable public function getMethodName(): string { - return $this->_getJob()->getWorkerUri(); + return $this->_getJob()->getWorkerMethod(); } public function getClassName(): string { - return $this->_getJob()->getWorkerMethod(); + return $this->_getJob()->getWorkerUri(); } } \ No newline at end of file From ec2084ea7e39846d632975e4ac56d6b37a69f9f2 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Thu, 31 May 2018 12:02:43 -0500 Subject: [PATCH 14/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- example/src/V1/Worker.php | 2 +- example/src/V1/Worker/Facade.php | 4 +++- example/src/V1/WorkerInterface.php | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/example/src/V1/Worker.php b/example/src/V1/Worker.php index 82372026..ef1f4cbd 100644 --- a/example/src/V1/Worker.php +++ b/example/src/V1/Worker.php @@ -10,7 +10,7 @@ class Worker implements WorkerInterface use Worker\Delegate\Repository\AwareTrait; use Api\V1\Worker\Service\AwareTrait; use Worker\Queue\AwareTrait; - public const JOB_TYPE_CODE = 'type_code_1'; + public const JOB_TYPE_CODE = 'protean_dlcp_example'; public function work(): WorkerInterface { diff --git a/example/src/V1/Worker/Facade.php b/example/src/V1/Worker/Facade.php index 1a96942f..18948e99 100644 --- a/example/src/V1/Worker/Facade.php +++ b/example/src/V1/Worker/Facade.php @@ -6,9 +6,11 @@ use Neighborhoods\KojoExample\V1\WorkerInterface; use Neighborhoods\Pylon\DependencyInjection; use Symfony\Component\Finder\Finder; +use Neighborhoods\Kojo\Api; class Facade implements FacadeInterface { + use Api\V1\Worker\Service\AwareTrait; protected $containerBuilderFacade; protected $worker; protected $isBootStrapped = false; @@ -62,7 +64,7 @@ protected function setWorker(WorkerInterface $worker): FacadeInterface if ($this->worker !== null) { throw new \LogicException('Worker is already set.'); } - $this->worker = $worker; + $this->worker = $worker->setApiV1WorkerService($this->getApiV1WorkerService()); return $this; } diff --git a/example/src/V1/WorkerInterface.php b/example/src/V1/WorkerInterface.php index 64bf9687..2726cc23 100644 --- a/example/src/V1/WorkerInterface.php +++ b/example/src/V1/WorkerInterface.php @@ -3,7 +3,11 @@ namespace Neighborhoods\KojoExample\V1; +use Neighborhoods\Kojo\Api\V1\Worker\ServiceInterface; + interface WorkerInterface { + public function setApiV1WorkerService(ServiceInterface $apiV1WorkerService); + public function work(): WorkerInterface; } \ No newline at end of file From 24adf645ed8199ed9a3fc0e4708a3612f814f0f4 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Thu, 31 May 2018 12:22:51 -0500 Subject: [PATCH 15/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- src/Doctrine/Connection/Decorator.php | 2 +- src/Process/Pool/Logger.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Doctrine/Connection/Decorator.php b/src/Doctrine/Connection/Decorator.php index b897ce9d..a8c249ad 100644 --- a/src/Doctrine/Connection/Decorator.php +++ b/src/Doctrine/Connection/Decorator.php @@ -28,7 +28,7 @@ public function getDoctrineConnection(): Connection $connection = DriverManager::getConnection(['pdo' => $pdoBuilder->getPdo()]); } - $connection->getConfiguration()->setSQLLogger(new EchoSQLLogger()); +// $connection->getConfiguration()->setSQLLogger(new EchoSQLLogger()); $this->_create(Connection::class, $connection); } diff --git a/src/Process/Pool/Logger.yml b/src/Process/Pool/Logger.yml index 42043524..e55995fe 100644 --- a/src/Process/Pool/Logger.yml +++ b/src/Process/Pool/Logger.yml @@ -1,7 +1,7 @@ parameters: process.pool.logger.process_id_padding: 6 process.pool.logger.path_padding: 80 - process.pool.logger.is_enabled: false + process.pool.logger.is_enabled: true services: neighborhoods.kojo.process.pool.logger: class: Neighborhoods\Kojo\Process\Pool\Logger From 590220601cbf776a52600bc4040e5a8f608f2df4 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Thu, 31 May 2018 14:26:27 -0500 Subject: [PATCH 16/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- example/src/V1/Worker/Queue.php | 5 +++++ src/Api/V1/Worker/Service.php | 5 +++++ src/Api/V1/Worker/ServiceInterface.php | 2 ++ 3 files changed, 12 insertions(+) diff --git a/example/src/V1/Worker/Queue.php b/example/src/V1/Worker/Queue.php index 8f4626a5..fae27978 100644 --- a/example/src/V1/Worker/Queue.php +++ b/example/src/V1/Worker/Queue.php @@ -82,4 +82,9 @@ protected function getQueueUrl(): string return $this->queueUrl; } + + public function setNumberOfPollCycles(int $numberOfPollCycles): QueueInterface + { + // TODO: Implement setNumberOfPollCycles() method. + } } \ No newline at end of file diff --git a/src/Api/V1/Worker/Service.php b/src/Api/V1/Worker/Service.php index 132cf077..88847cb6 100644 --- a/src/Api/V1/Worker/Service.php +++ b/src/Api/V1/Worker/Service.php @@ -109,6 +109,11 @@ public function isRequestApplied(): bool return $this->_exists(self::PROP_REQUEST_APPLIED); } + public function getTimesCrashed(): int + { + return $this->_getJob()->getTimesCrashed(); + } + public function getLogger(): LoggerInterface { return $this->getApiV1Logger(); diff --git a/src/Api/V1/Worker/ServiceInterface.php b/src/Api/V1/Worker/ServiceInterface.php index 2b16760b..274e4eab 100644 --- a/src/Api/V1/Worker/ServiceInterface.php +++ b/src/Api/V1/Worker/ServiceInterface.php @@ -31,6 +31,8 @@ public function getNewJobScheduler(): SchedulerInterface; public function reload(): ServiceInterface; + public function getTimesCrashed(): int; + /** @injected:configuration */ public function setServiceUpdateRetryFactory(Retry\FactoryInterface $updateRetryFactory); From ee2e274d36ce2220ea513f408922a9c413c8312a Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Thu, 31 May 2018 16:59:38 -0500 Subject: [PATCH 17/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- .../Job/Collection/Schedule/LimitCheck.php | 1 + src/Data/Job/Collection/ScheduleLimit.php | 4 ++-- .../Job/Collection/ScheduleLimitInterface.php | 2 +- src/Maintainer.php | 22 +++++++++---------- src/Process/Pool/Factory.yml | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Data/Job/Collection/Schedule/LimitCheck.php b/src/Data/Job/Collection/Schedule/LimitCheck.php index 3f2c6480..7e224bd1 100644 --- a/src/Data/Job/Collection/Schedule/LimitCheck.php +++ b/src/Data/Job/Collection/Schedule/LimitCheck.php @@ -18,6 +18,7 @@ protected function _prepareCollection(): Db\Model\CollectionAbstract JobInterface::FIELD_NAME_ID, JobInterface::FIELD_NAME_TYPE_CODE, JobInterface::FIELD_NAME_PRIORITY, + JobInterface::FIELD_NAME_WORK_AT_DATE_TIME, JobInterface::FIELD_NAME_CAN_WORK_IN_PARALLEL, JobInterface::FIELD_NAME_ASSIGNED_STATE, JobInterface::FIELD_NAME_NEXT_STATE_REQUEST, diff --git a/src/Data/Job/Collection/ScheduleLimit.php b/src/Data/Job/Collection/ScheduleLimit.php index a9dd3405..c32eb492 100644 --- a/src/Data/Job/Collection/ScheduleLimit.php +++ b/src/Data/Job/Collection/ScheduleLimit.php @@ -19,9 +19,9 @@ public function getNumberOfCurrentlyScheduledJobs(): int return $this->_getRecords()[self::ALIAS_NUMBER_OF_SCHEDULED_JOBS]; } - public function decrementNumberOfCurrentlyScheduledJobs(): ScheduleLimitInterface + public function incrementNumberOfCurrentlyScheduledJobs(): ScheduleLimitInterface { - --$this->_getRecords()[self::ALIAS_NUMBER_OF_SCHEDULED_JOBS]; + ++$this->_getRecords()[self::ALIAS_NUMBER_OF_SCHEDULED_JOBS]; return $this; } diff --git a/src/Data/Job/Collection/ScheduleLimitInterface.php b/src/Data/Job/Collection/ScheduleLimitInterface.php index 06a4e592..04d7ff6c 100644 --- a/src/Data/Job/Collection/ScheduleLimitInterface.php +++ b/src/Data/Job/Collection/ScheduleLimitInterface.php @@ -12,5 +12,5 @@ public function setJobType(TypeInterface $job); public function getNumberOfCurrentlyScheduledJobs(): int; - public function decrementNumberOfCurrentlyScheduledJobs(): ScheduleLimitInterface; + public function incrementNumberOfCurrentlyScheduledJobs(): ScheduleLimitInterface; } \ No newline at end of file diff --git a/src/Maintainer.php b/src/Maintainer.php index 19e89b15..80449ddc 100644 --- a/src/Maintainer.php +++ b/src/Maintainer.php @@ -37,10 +37,10 @@ public function deleteCompletedJobs(): MaintainerInterface public function rescheduleCrashedJobs(): MaintainerInterface { if ($this->_getSemaphoreResource(self::SEMAPHORE_RESOURCE_NAME_RESCHEDULE_JOBS)->testAndSetLock()) { - try{ + try { $this->_rescheduleCrashedJobs(); $this->_getSemaphoreResource(self::SEMAPHORE_RESOURCE_NAME_RESCHEDULE_JOBS)->releaseLock(); - }catch(\Exception $exception){ + } catch (\Exception $exception) { if ($this->_getSemaphoreResource(self::SEMAPHORE_RESOURCE_NAME_RESCHEDULE_JOBS)->hasLock()) { $this->_getSemaphoreResource(self::SEMAPHORE_RESOURCE_NAME_RESCHEDULE_JOBS)->releaseLock(); } @@ -55,14 +55,14 @@ protected function _rescheduleCrashedJobs(): Maintainer { foreach ($this->_getJobCollectionCrashDetection()->getIterator() as $job) { $jobSemaphoreResource = $this->_getNewJobOwnerResource($job); - try{ + try { if ($jobSemaphoreResource->testAndSetLock()) { $crashUpdate = $this->_getServiceUpdateCrashFactory()->create(); $crashUpdate->setJob($job); $crashUpdate->save(); $jobSemaphoreResource->releaseLock(); } - }catch(\Exception $exception){ + } catch (\Exception $exception) { if ($jobSemaphoreResource->hasLock()) { $jobSemaphoreResource->releaseLock(); } @@ -76,10 +76,10 @@ protected function _rescheduleCrashedJobs(): Maintainer public function updatePendingJobs(): MaintainerInterface { if ($this->_getSemaphoreResource(self::SEMAPHORE_RESOURCE_NAME_UPDATE_PENDING_JOBS)->testAndSetLock()) { - try{ + try { $this->_updatePendingJobs(); $this->_getSemaphoreResource(self::SEMAPHORE_RESOURCE_NAME_UPDATE_PENDING_JOBS)->releaseLock(); - }catch(\Exception $exception){ + } catch (\Exception $exception) { if ($this->_getSemaphoreResource(self::SEMAPHORE_RESOURCE_NAME_UPDATE_PENDING_JOBS)->hasLock()) { $this->_getSemaphoreResource(self::SEMAPHORE_RESOURCE_NAME_UPDATE_PENDING_JOBS)->releaseLock(); } @@ -97,18 +97,18 @@ protected function _updatePendingJobs(): Maintainer $scheduleLimitCollection = $this->_getJobCollectionScheduleLimitByJobType($jobType); $numberOfScheduledJobs = $scheduleLimitCollection->getNumberOfCurrentlyScheduledJobs(); $scheduleLimit = $jobType->getScheduleLimit(); - try{ - if ($numberOfScheduledJobs <= $scheduleLimit) { + try { + if ($numberOfScheduledJobs < $scheduleLimit) { $waitUpdate = $this->_getServiceUpdateWaitFactory()->create(); $waitUpdate->setJob($job); $waitUpdate->save(); - }elseif ($numberOfScheduledJobs > $scheduleLimit + $jobType->getScheduleLimitAllowance()) { + $scheduleLimitCollection->incrementNumberOfCurrentlyScheduledJobs(); + } elseif ($job->getWorkAtDateTime() < new \DateTime('now')) { $failedLimitCheckUpdate = $this->_getServiceUpdateCompleteFailedScheduleLimitCheckFactory()->create(); $failedLimitCheckUpdate->setJob($job); $failedLimitCheckUpdate->save(); - $scheduleLimitCollection->decrementNumberOfCurrentlyScheduledJobs(); } - }catch(\Exception $exception){ + } catch (\Exception $exception) { $updatePanic = $this->_getServiceUpdatePanicFactory()->create(); $updatePanic->setJob($job); $updatePanic->save(); diff --git a/src/Process/Pool/Factory.yml b/src/Process/Pool/Factory.yml index 37f2efcd..e56c10f7 100644 --- a/src/Process/Pool/Factory.yml +++ b/src/Process/Pool/Factory.yml @@ -1,5 +1,5 @@ parameters: - process_pool_strategy.max_child_processes: 10 + process_pool_strategy.max_child_processes: 20 process_pool_strategy.child_process_wait_throttle: 1 process_pool_strategy.max_alarm_time: 5 process_pool_strategy-server.max_child_processes: 1 From 99175c2414b3b03dda549bffd11019a2d1c76ce8 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Thu, 31 May 2018 17:00:14 -0500 Subject: [PATCH 18/19] Updates To Example To Be A Fully Working DLCP Protean Implementation --- example/src/V1/Worker.php | 26 ++++++++++++++------------ example/src/V1/Worker/Queue.php | 9 ++++++++- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/example/src/V1/Worker.php b/example/src/V1/Worker.php index ef1f4cbd..2288a678 100644 --- a/example/src/V1/Worker.php +++ b/example/src/V1/Worker.php @@ -14,18 +14,20 @@ class Worker implements WorkerInterface public function work(): WorkerInterface { - // Wait for one message to become available. - $this->getV1WorkerQueue()->waitForNextMessage(); - - // Schedule another kōjō job of the same type. - $this->_scheduleNextJob(); - - // Delegate the work for the first message. - $this->_delegateWork(); - - // Delegate the work until the observed Queue is empty. - while ($this->getV1WorkerQueue()->hasNextMessage()) { - $this->_delegateWork(); + if ($this->getApiV1WorkerService()->getTimesCrashed() === 0) { + // Wait for one message to become available. + if($this->getV1WorkerQueue()->hasNextMessage()){ + // Schedule another kōjō job of the same type. + $this->_scheduleNextJob(); + + // Delegate the work for the first message. + $this->_delegateWork(); + + // Delegate the work until the observed Queue is empty. + while ($this->getV1WorkerQueue()->hasNextMessage()) { + $this->_delegateWork(); + } + } } // Tell Kōjō that we are done and all is well. diff --git a/example/src/V1/Worker/Queue.php b/example/src/V1/Worker/Queue.php index 8f4626a5..ae9f6ceb 100644 --- a/example/src/V1/Worker/Queue.php +++ b/example/src/V1/Worker/Queue.php @@ -18,6 +18,8 @@ class Queue implements QueueInterface protected const QUEUE_URL = 'QueueUrl'; protected const MESSAGES = 'Messages'; + protected const WAIT_TIME_SECONDS = 'WaitTimeSeconds'; + public function getNextMessage(): MessageInterface { $v1WorkerQueueMessage = $this->getV1WorkerQueueMessage(); @@ -60,7 +62,12 @@ protected function createNextMessage(Model $guzzleServiceResourceModel): QueueIn protected function receiveMessage(): Model { - return $this->getV1AwsSqsSqsClient()->receiveMessage([self::QUEUE_URL => $this->getQueueUrl()]); + return $this->getV1AwsSqsSqsClient()->receiveMessage( + [ + self::QUEUE_URL => $this->getQueueUrl(), + self::WAIT_TIME_SECONDS => 20, + ] + ); } public function setQueueUrl(string $queueUrl): QueueInterface From f2fecafc1db53dcda5a9f9e8c90e291246d87b38 Mon Sep 17 00:00:00 2001 From: Brad Wilson Date: Mon, 11 Jun 2018 12:14:49 -0500 Subject: [PATCH 19/19] Update example --- example/src/V1/Environment/Parameters.yml | 23 +++++++++++++---------- example/src/V1/Worker/Facade.php | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/example/src/V1/Environment/Parameters.yml b/example/src/V1/Environment/Parameters.yml index 009fd245..ede295d8 100644 --- a/example/src/V1/Environment/Parameters.yml +++ b/example/src/V1/Environment/Parameters.yml @@ -1,13 +1,16 @@ parameters: +# Redis. neighborhoods.kojo.environment.parameters.redis_port: '%env(REDIS_PORT)%' neighborhoods.kojo.environment.parameters.redis_host: '%env(REDIS_HOST)%' - neighborhoods.kojo.environment.parameters.database_user_name: '%env(DATABASE_USERNAME)%' - neighborhoods.kojo.environment.parameters.database_password: '%env(DATABASE_PASSWORD)%' - neighborhoods.kojo.environment.parameters.database_adapter: '%env(DATABASE_ADAPTER)%' - neighborhoods.kojo.environment.parameters.database_host: '%env(DATABASE_HOST)%' - neighborhoods.kojo.environment.parameters.database_name: '%env(DATABASE_NAME)%' -# neighborhoods.kojo.environment.parameters.database_user_name: 'nhds' -# neighborhoods.kojo.environment.parameters.database_password: 'nhds2016' -# neighborhoods.kojo.environment.parameters.database_adapter: 'pgsql' -# neighborhoods.kojo.environment.parameters.database_host: 'pgsql' -# neighborhoods.kojo.environment.parameters.database_name: 'kojo' \ No newline at end of file +# MySQL. +# neighborhoods.kojo.environment.parameters.database_user_name: '%env(DATABASE_USERNAME)%' +# neighborhoods.kojo.environment.parameters.database_password: '%env(DATABASE_PASSWORD)%' +# neighborhoods.kojo.environment.parameters.database_adapter: '%env(DATABASE_ADAPTER)%' +# neighborhoods.kojo.environment.parameters.database_host: '%env(DATABASE_HOST)%' +# neighborhoods.kojo.environment.parameters.database_name: '%env(DATABASE_NAME)%' +# Postgres. + neighborhoods.kojo.environment.parameters.database_user_name: 'nhds' + neighborhoods.kojo.environment.parameters.database_password: 'nhds2016' + neighborhoods.kojo.environment.parameters.database_adapter: 'pgsql' + neighborhoods.kojo.environment.parameters.database_host: 'pgsql' + neighborhoods.kojo.environment.parameters.database_name: 'kojo' \ No newline at end of file diff --git a/example/src/V1/Worker/Facade.php b/example/src/V1/Worker/Facade.php index 18948e99..facbeb83 100644 --- a/example/src/V1/Worker/Facade.php +++ b/example/src/V1/Worker/Facade.php @@ -41,7 +41,7 @@ protected function bootstrap(): FacadeInterface return $this; } - public function getContainerBuilderFacade(): DependencyInjection\ContainerBuilder\Facade + public function getContainerBuilderFacade(): DependencyInjection\ContainerBuilder\FacadeInterface { if ($this->containerBuilderFacade === null) { $this->containerBuilderFacade = new DependencyInjection\ContainerBuilder\Facade();