summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValery Piashchynski <[email protected]>2020-11-17 16:25:35 +0300
committerValery Piashchynski <[email protected]>2020-11-17 16:25:35 +0300
commit3cbdd3d3e44b3b4e72565d666391e3b732950774 (patch)
tree7c60fafe1c33076631e39fe26be187c9ca359a3e
parenta57d064407e2ed7f35dd591101b5d421c64605e1 (diff)
Get http working with new container
-rwxr-xr-xcomposer.json7
-rwxr-xr-xcomposer.lock389
-rwxr-xr-xgo.mod4
-rwxr-xr-xgo.sum4
-rw-r--r--interfaces/app/interface.go15
-rw-r--r--plugins/http/config.go59
-rw-r--r--plugins/http/plugin.go252
-rw-r--r--plugins/http/response.go4
-rw-r--r--plugins/http/rpc.go62
-rw-r--r--plugins/http/test/.rr-http.yaml37
-rw-r--r--plugins/http/test/http_test.go53
-rw-r--r--plugins/http/test/psr-worker.php23
-rw-r--r--plugins/http/test/rr-http.yaml34
-rw-r--r--plugins/server/plugin.go78
-rw-r--r--src/Diactoros/ServerRequestFactory.php26
-rw-r--r--src/Diactoros/StreamFactory.php57
-rw-r--r--src/Diactoros/UploadedFileFactory.php36
-rw-r--r--[-rwxr-xr-x]src/Exception/MetricException.php0
-rw-r--r--[-rwxr-xr-x]src/Exception/RoadRunnerException.php2
-rw-r--r--src/Exceptions/RoadRunnerException.php18
-rw-r--r--src/HttpClient.php (renamed from src/Http/HttpClient.php)0
-rw-r--r--src/Logger/.empty0
-rw-r--r--src/Metrics.php (renamed from src/Metrics/Metrics.php)0
-rw-r--r--src/MetricsInterface.php (renamed from src/Metrics/MetricsInterface.php)0
-rw-r--r--src/PSR7Client.php (renamed from src/Http/PSR7Client.php)0
-rw-r--r--[-rwxr-xr-x]src/Worker.php0
-rw-r--r--src/WorkerInterface.php0
-rwxr-xr-xstatic_pool.go3
28 files changed, 789 insertions, 374 deletions
diff --git a/composer.json b/composer.json
index aef75b08..283eaab1 100755
--- a/composer.json
+++ b/composer.json
@@ -18,14 +18,15 @@
"ext-json": "*",
"ext-curl": "*",
"spiral/goridge": "^2.4.2",
- "symfony/console": "^2.5.0 || ^3.0.0 || ^4.0.0 || ^5.0.0"
+ "psr/http-factory": "^1.0",
+ "psr/http-message": "^1.0",
+ "symfony/console": "^2.5.0 || ^3.0.0 || ^4.0.0 || ^5.0.0",
+ "laminas/laminas-diactoros": "^1.3 || ^2.0"
},
"config": {
"vendor-dir": "vendor_php"
},
"require-dev": {
- "psr/http-factory": "^1.0",
- "psr/http-message": "^1.0",
"phpstan/phpstan": "~0.12"
},
"scripts": {
diff --git a/composer.lock b/composer.lock
index 183f9fef..ded194f5 100755
--- a/composer.lock
+++ b/composer.lock
@@ -4,9 +4,168 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "95535b37e4eb6476a2f89ea1b0f16e48",
+ "content-hash": "439018483d4d3a37c3d369d2587b8311",
"packages": [
{
+ "name": "laminas/laminas-diactoros",
+ "version": "2.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laminas/laminas-diactoros.git",
+ "reference": "36ef09b73e884135d2059cc498c938e90821bb57"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/36ef09b73e884135d2059cc498c938e90821bb57",
+ "reference": "36ef09b73e884135d2059cc498c938e90821bb57",
+ "shasum": ""
+ },
+ "require": {
+ "laminas/laminas-zendframework-bridge": "^1.0",
+ "php": "^7.1",
+ "psr/http-factory": "^1.0",
+ "psr/http-message": "^1.0"
+ },
+ "conflict": {
+ "phpspec/prophecy": "<1.9.0"
+ },
+ "provide": {
+ "psr/http-factory-implementation": "1.0",
+ "psr/http-message-implementation": "1.0"
+ },
+ "replace": {
+ "zendframework/zend-diactoros": "^2.2.1"
+ },
+ "require-dev": {
+ "ext-curl": "*",
+ "ext-dom": "*",
+ "ext-gd": "*",
+ "ext-libxml": "*",
+ "http-interop/http-factory-tests": "^0.5.0",
+ "laminas/laminas-coding-standard": "~1.0.0",
+ "php-http/psr7-integration-tests": "^1.0",
+ "phpunit/phpunit": "^7.5.18"
+ },
+ "type": "library",
+ "extra": {
+ "laminas": {
+ "config-provider": "Laminas\\Diactoros\\ConfigProvider",
+ "module": "Laminas\\Diactoros"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions/create_uploaded_file.php",
+ "src/functions/marshal_headers_from_sapi.php",
+ "src/functions/marshal_method_from_sapi.php",
+ "src/functions/marshal_protocol_version_from_sapi.php",
+ "src/functions/marshal_uri_from_sapi.php",
+ "src/functions/normalize_server.php",
+ "src/functions/normalize_uploaded_files.php",
+ "src/functions/parse_cookie_header.php",
+ "src/functions/create_uploaded_file.legacy.php",
+ "src/functions/marshal_headers_from_sapi.legacy.php",
+ "src/functions/marshal_method_from_sapi.legacy.php",
+ "src/functions/marshal_protocol_version_from_sapi.legacy.php",
+ "src/functions/marshal_uri_from_sapi.legacy.php",
+ "src/functions/normalize_server.legacy.php",
+ "src/functions/normalize_uploaded_files.legacy.php",
+ "src/functions/parse_cookie_header.legacy.php"
+ ],
+ "psr-4": {
+ "Laminas\\Diactoros\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "PSR HTTP Message implementations",
+ "homepage": "https://laminas.dev",
+ "keywords": [
+ "http",
+ "laminas",
+ "psr",
+ "psr-17",
+ "psr-7"
+ ],
+ "support": {
+ "chat": "https://laminas.dev/chat",
+ "docs": "https://docs.laminas.dev/laminas-diactoros/",
+ "forum": "https://discourse.laminas.dev",
+ "issues": "https://github.com/laminas/laminas-diactoros/issues",
+ "rss": "https://github.com/laminas/laminas-diactoros/releases.atom",
+ "source": "https://github.com/laminas/laminas-diactoros"
+ },
+ "funding": [
+ {
+ "url": "https://funding.communitybridge.org/projects/laminas-project",
+ "type": "community_bridge"
+ }
+ ],
+ "time": "2020-09-03T14:29:41+00:00"
+ },
+ {
+ "name": "laminas/laminas-zendframework-bridge",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laminas/laminas-zendframework-bridge.git",
+ "reference": "6ede70583e101030bcace4dcddd648f760ddf642"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6ede70583e101030bcace4dcddd648f760ddf642",
+ "reference": "6ede70583e101030bcace4dcddd648f760ddf642",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3",
+ "squizlabs/php_codesniffer": "^3.5"
+ },
+ "type": "library",
+ "extra": {
+ "laminas": {
+ "module": "Laminas\\ZendFrameworkBridge"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/autoload.php"
+ ],
+ "psr-4": {
+ "Laminas\\ZendFrameworkBridge\\": "src//"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "Alias legacy ZF class names to Laminas Project equivalents.",
+ "keywords": [
+ "ZendFramework",
+ "autoloading",
+ "laminas",
+ "zf"
+ ],
+ "support": {
+ "forum": "https://discourse.laminas.dev/",
+ "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues",
+ "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom",
+ "source": "https://github.com/laminas/laminas-zendframework-bridge"
+ },
+ "funding": [
+ {
+ "url": "https://funding.communitybridge.org/projects/laminas-project",
+ "type": "community_bridge"
+ }
+ ],
+ "time": "2020-09-14T14:23:00+00:00"
+ },
+ {
"name": "psr/container",
"version": "1.0.0",
"source": {
@@ -60,6 +219,114 @@
"time": "2017-02-14T16:28:37+00:00"
},
{
+ "name": "psr/http-factory",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-factory.git",
+ "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+ "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0.0",
+ "psr/http-message": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interfaces for PSR-7 HTTP message factories",
+ "keywords": [
+ "factory",
+ "http",
+ "message",
+ "psr",
+ "psr-17",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-factory/tree/master"
+ },
+ "time": "2019-04-30T12:38:16+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-message/tree/master"
+ },
+ "time": "2016-08-06T14:39:51+00:00"
+ },
+ {
"name": "spiral/goridge",
"version": "v2.4.5",
"source": {
@@ -851,16 +1118,16 @@
"packages-dev": [
{
"name": "phpstan/phpstan",
- "version": "0.12.53",
+ "version": "0.12.56",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
- "reference": "dbbdb0d7c2434ecd5289f6114d16473e694caa67"
+ "reference": "007fd5d700c41e1bb27795fae15a2383f8fa4ba1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dbbdb0d7c2434ecd5289f6114d16473e694caa67",
- "reference": "dbbdb0d7c2434ecd5289f6114d16473e694caa67",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/007fd5d700c41e1bb27795fae15a2383f8fa4ba1",
+ "reference": "007fd5d700c41e1bb27795fae15a2383f8fa4ba1",
"shasum": ""
},
"require": {
@@ -891,7 +1158,7 @@
"description": "PHPStan - PHP Static Analysis Tool",
"support": {
"issues": "https://github.com/phpstan/phpstan/issues",
- "source": "https://github.com/phpstan/phpstan/tree/0.12.53"
+ "source": "https://github.com/phpstan/phpstan/tree/0.12.56"
},
"funding": [
{
@@ -907,115 +1174,7 @@
"type": "tidelift"
}
],
- "time": "2020-11-01T14:51:50+00:00"
- },
- {
- "name": "psr/http-factory",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-factory.git",
- "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
- "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
- "shasum": ""
- },
- "require": {
- "php": ">=7.0.0",
- "psr/http-message": "^1.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interfaces for PSR-7 HTTP message factories",
- "keywords": [
- "factory",
- "http",
- "message",
- "psr",
- "psr-17",
- "psr-7",
- "request",
- "response"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-factory/tree/master"
- },
- "time": "2019-04-30T12:38:16+00:00"
- },
- {
- "name": "psr/http-message",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-message.git",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interface for HTTP messages",
- "homepage": "https://github.com/php-fig/http-message",
- "keywords": [
- "http",
- "http-message",
- "psr",
- "psr-7",
- "request",
- "response"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-message/tree/master"
- },
- "time": "2016-08-06T14:39:51+00:00"
+ "time": "2020-11-16T22:59:18+00:00"
}
],
"aliases": [],
diff --git a/go.mod b/go.mod
index 21500c30..0cbbfc70 100755
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,7 @@ go 1.15
require (
github.com/fatih/color v1.10.0
+ github.com/hashicorp/go-multierror v1.0.0
github.com/json-iterator/go v1.1.10
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.7.1
@@ -16,6 +17,7 @@ require (
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a
go.uber.org/multierr v1.6.0
go.uber.org/zap v1.16.0
+ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1
-) \ No newline at end of file
+)
diff --git a/go.sum b/go.sum
index 343f4fcf..dcec5726 100755
--- a/go.sum
+++ b/go.sum
@@ -115,10 +115,12 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
@@ -341,7 +343,9 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200222125558-5a598a2470a0 h1:MsuvTghUPjX762sGLnGsxC3HM0B5r83wEtYcYR8/vRs=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
diff --git a/interfaces/app/interface.go b/interfaces/app/interface.go
deleted file mode 100644
index 4db7a094..00000000
--- a/interfaces/app/interface.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package app
-
-import (
- "context"
- "os/exec"
-
- "github.com/spiral/roadrunner/v2"
-)
-
-// WorkerFactory creates workers for the application.
-type WorkerFactory interface {
- CmdFactory(env map[string]string) (func() *exec.Cmd, error)
- NewWorker(ctx context.Context, env map[string]string) (roadrunner.WorkerBase, error)
- NewWorkerPool(ctx context.Context, opt roadrunner.PoolConfig, env map[string]string) (roadrunner.Pool, error)
-}
diff --git a/plugins/http/config.go b/plugins/http/config.go
index b3d16b62..7922f485 100644
--- a/plugins/http/config.go
+++ b/plugins/http/config.go
@@ -11,9 +11,6 @@ import (
"github.com/spiral/roadrunner/v2"
)
-type PoolConfig struct {
-}
-
type ServerConfig struct {
// Command includes command strings with all the parameters, example: "php worker.php pipes".
Command string
@@ -32,7 +29,7 @@ type ServerConfig struct {
// Pool defines worker pool configuration, number of workers, timeouts and etc. This config section might change
// while server is running.
- PoolCfg *roadrunner.PoolConfig
+
env map[string]string
}
@@ -61,8 +58,8 @@ type Config struct {
// Uploads configures uploads configuration.
Uploads *UploadsConfig
- // Workers configures rr server and worker pool.
- Workers *ServerConfig
+ // Pool configures worker pool.
+ Pool *roadrunner.PoolConfig
}
// FCGIConfig for FastCGI server.
@@ -135,10 +132,10 @@ func (c *Config) EnableFCGI() bool {
}
// Hydrate must populate Config values using given Config source. Must return error if Config is not valid.
-func (c *Config) Hydrate(cfg service.Config) error {
- if c.Workers == nil {
- c.Workers = &roadrunner.ServerConfig{}
- }
+func (c *Config) Hydrate(cfg Config) error {
+ //if c.Workers == nil {
+ // c.Workers = &ServerConfig{}
+ //}
if c.HTTP2 == nil {
c.HTTP2 = &HTTP2Config{}
@@ -164,16 +161,16 @@ func (c *Config) Hydrate(cfg service.Config) error {
if err != nil {
return err
}
- err = c.Workers.InitDefaults()
- if err != nil {
- return err
- }
-
- if err := cfg.Unmarshal(c); err != nil {
- return err
- }
-
- c.Workers.UpscaleDurations()
+ //err = c.Workers.InitDefaults()
+ //if err != nil {
+ // return err
+ //}
+ //
+ //if err := cfg.Unmarshal(c); err != nil {
+ // return err
+ //}
+ //
+ //c.Workers.UpscaleDurations()
if c.TrustedSubnets == nil {
// @see https://en.wikipedia.org/wiki/Reserved_IP_addresses
@@ -238,17 +235,17 @@ func (c *Config) Valid() error {
return errors.New("malformed http2 config")
}
- if c.Workers == nil {
- return errors.New("malformed workers config")
- }
-
- if c.Workers.Pool == nil {
- return errors.New("malformed workers config (pool config is missing)")
- }
-
- if err := c.Workers.Pool.Valid(); err != nil {
- return err
- }
+ //if c.Workers == nil {
+ // return errors.New("malformed workers config")
+ //}
+ //
+ //if c.Workers.Pool == nil {
+ // return errors.New("malformed workers config (pool config is missing)")
+ //}
+
+ //if err := c.Workers.Pool.Valid(); err != nil {
+ // return err
+ //}
if !c.EnableHTTP() && !c.EnableTLS() && !c.EnableFCGI() {
return errors.New("unable to run http service, no method has been specified (http, https, http/2 or FastCGI)")
diff --git a/plugins/http/plugin.go b/plugins/http/plugin.go
index 24eaa68c..94b6c74b 100644
--- a/plugins/http/plugin.go
+++ b/plugins/http/plugin.go
@@ -12,11 +12,13 @@ import (
"strings"
"sync"
+ "github.com/hashicorp/go-multierror"
"github.com/spiral/errors"
"github.com/spiral/roadrunner/v2"
- factory "github.com/spiral/roadrunner/v2/interfaces/app"
"github.com/spiral/roadrunner/v2/interfaces/log"
+ factory "github.com/spiral/roadrunner/v2/interfaces/server"
"github.com/spiral/roadrunner/v2/plugins/config"
+ "github.com/spiral/roadrunner/v2/util"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"golang.org/x/sys/cpu"
@@ -79,7 +81,7 @@ func (s *Plugin) AddListener(l func(event int, ctx interface{})) {
// Init must return configure svc and return true if svc hasStatus enabled. Must return error in case of
// misconfiguration. Services must not be used without proper configuration pushed first.
-func (s *Plugin) Init(cfg config.Configurer, log log.Logger, app factory.WorkerFactory) error {
+func (s *Plugin) Init(cfg config.Configurer, log log.Logger, server factory.WorkerFactory) error {
const op = errors.Op("http Init")
err := cfg.UnmarshalKey(ServiceName, &s.cfg)
if err != nil {
@@ -88,14 +90,18 @@ func (s *Plugin) Init(cfg config.Configurer, log log.Logger, app factory.WorkerF
s.log = log
- p, err := app.NewWorkerPool(context.Background(), roadrunner.PoolConfig{
- Debug: s.cfg.Workers.PoolCfg.Debug,
- NumWorkers: s.cfg.Workers.PoolCfg.NumWorkers,
- MaxJobs: s.cfg.Workers.PoolCfg.MaxJobs,
- AllocateTimeout: s.cfg.Workers.PoolCfg.AllocateTimeout,
- DestroyTimeout: s.cfg.Workers.PoolCfg.DestroyTimeout,
+ // Set needed env vars
+ env := make(map[string]string)
+ env["RR_HTTP"] = "true"
+
+ p, err := server.NewWorkerPool(context.Background(), roadrunner.PoolConfig{
+ Debug: s.cfg.Pool.Debug,
+ NumWorkers: s.cfg.Pool.NumWorkers,
+ MaxJobs: s.cfg.Pool.MaxJobs,
+ AllocateTimeout: s.cfg.Pool.AllocateTimeout,
+ DestroyTimeout: s.cfg.Pool.DestroyTimeout,
Supervisor: nil,
- }, nil)
+ }, env)
if err != nil {
return errors.E(op, err)
@@ -117,27 +123,29 @@ func (s *Plugin) Init(cfg config.Configurer, log log.Logger, app factory.WorkerF
}
// Serve serves the svc.
-func (s *Plugin) Serve() error {
+func (s *Plugin) Serve() chan error {
s.Lock()
+ const op = errors.Op("serve http")
+ errCh := make(chan error, 2)
- if s.env != nil {
- if err := s.env.Copy(s.cfg.Workers); err != nil {
- return nil
- }
- }
-
- s.cfg.Workers.CommandProducer = s.cprod
- s.cfg.Workers.SetEnv("RR_HTTP", "true")
-
- s.rr = roadrunner.NewServer(s.cfg.Workers)
- s.rr.Listen(s.throw)
-
- if s.controller != nil {
- s.rr.Attach(s.controller)
- }
+ //if s.env != nil {
+ // if err := s.env.Copy(s.cfg.Workers); err != nil {
+ // return nil
+ // }
+ //}
+ //
+ //s.cfg.Workers.CommandProducer = s.cprod
+ //s.cfg.Workers.SetEnv("RR_HTTP", "true")
+ //
+ //s.rr = roadrunner.NewServer(s.cfg.Workers)
+ //s.rr.Listen(s.throw)
+ //
+ //if s.controller != nil {
+ // s.rr.Attach(s.controller)
+ //}
s.handler = &Handler{cfg: s.cfg, rr: s.rr}
- s.handler.Listen(s.throw)
+ //s.handler.Listen(s.throw)
if s.cfg.EnableHTTP() {
if s.cfg.EnableH2C() {
@@ -152,13 +160,15 @@ func (s *Plugin) Serve() error {
if s.cfg.SSL.RootCA != "" {
err := s.appendRootCa()
if err != nil {
- return err
+ errCh <- errors.E(op, err)
+ return errCh
}
}
if s.cfg.EnableHTTP2() {
if err := s.initHTTP2(); err != nil {
- return err
+ errCh <- errors.E(op, err)
+ return errCh
}
}
}
@@ -169,21 +179,19 @@ func (s *Plugin) Serve() error {
s.Unlock()
- if err := s.rr.Start(); err != nil {
- return err
- }
- defer s.rr.Stop()
-
- err := make(chan error, 3)
+ //if err := s.rr.Start(); err != nil {
+ // return err
+ //}
+ //defer s.rr.Stop()
if s.http != nil {
go func() {
httpErr := s.http.ListenAndServe()
if httpErr != nil && httpErr != http.ErrServerClosed {
- err <- httpErr
- } else {
- err <- nil
+ errCh <- errors.E(op, httpErr)
+ return
}
+ return
}()
}
@@ -195,10 +203,10 @@ func (s *Plugin) Serve() error {
)
if httpErr != nil && httpErr != http.ErrServerClosed {
- err <- httpErr
+ errCh <- errors.E(op, httpErr)
return
}
- err <- nil
+ return
}()
}
@@ -206,72 +214,54 @@ func (s *Plugin) Serve() error {
go func() {
httpErr := s.serveFCGI()
if httpErr != nil && httpErr != http.ErrServerClosed {
- err <- httpErr
+ errCh <- errors.E(op, httpErr)
return
}
- err <- nil
+ return
}()
}
- return <-err
+ return errCh
}
// Stop stops the http.
-func (s *Plugin) Stop() {
+func (s *Plugin) Stop() error {
s.Lock()
defer s.Unlock()
+ var err error
if s.fcgi != nil {
- s.Add(1)
- go func() {
- defer s.Done()
- err := s.fcgi.Shutdown(context.Background())
- if err != nil && err != http.ErrServerClosed {
- // Stop() error
- // push error from goroutines to the channel and block unil error or success shutdown or timeout
- s.log.Error(fmt.Errorf("error shutting down the fcgi server, error: %v", err))
- return
- }
- }()
+ err = s.fcgi.Shutdown(context.Background())
+ if err != nil && err != http.ErrServerClosed {
+ s.log.Error("error shutting down the fcgi server", "error", err)
+ // write error and try to stop other transport
+ err = multierror.Append(err)
+ }
}
if s.https != nil {
- s.Add(1)
- go func() {
- defer s.Done()
- err := s.https.Shutdown(context.Background())
- if err != nil && err != http.ErrServerClosed {
- s.log.Error(fmt.Errorf("error shutting down the https server, error: %v", err))
- return
- }
- }()
+ err = s.https.Shutdown(context.Background())
+ if err != nil && err != http.ErrServerClosed {
+ s.log.Error("error shutting down the https server", "error", err)
+ // write error and try to stop other transport
+ err = multierror.Append(err)
+ }
}
if s.http != nil {
- s.Add(1)
- go func() {
- defer s.Done()
- err := s.http.Shutdown(context.Background())
- if err != nil && err != http.ErrServerClosed {
- s.log.Error(fmt.Errorf("error shutting down the http server, error: %v", err))
- return
- }
- }()
+ err = s.http.Shutdown(context.Background())
+ if err != nil && err != http.ErrServerClosed {
+ s.log.Error("error shutting down the http server", "error", err)
+ // write error and try to stop other transport
+ err = multierror.Append(err)
+ }
}
- s.Wait()
-}
-
-// Server returns associated rr server (if any).
-func (s *Plugin) Server() *roadrunner.Server {
- s.Lock()
- defer s.Unlock()
-
- return s.rr
+ return err
}
// ServeHTTP handles connection using set of middleware and rr PSR-7 server.
-func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+func (s *Plugin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if s.https != nil && r.TLS == nil && s.cfg.SSL.Redirect {
target := &url.URL{
Scheme: "https",
@@ -288,7 +278,7 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
}
- r = attributes.Init(r)
+ //r = attributes.Init(r)
// chaining middleware
f := s.handler.ServeHTTP
@@ -300,9 +290,10 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// append RootCA to the https server TLS config
func (s *Plugin) appendRootCa() error {
+ const op = errors.Op("append root CA")
rootCAs, err := x509.SystemCertPool()
if err != nil {
- s.throw(EventInitSSL, nil)
+ //s.throw(EventInitSSL, nil)
return nil
}
if rootCAs == nil {
@@ -311,20 +302,20 @@ func (s *Plugin) appendRootCa() error {
CA, err := ioutil.ReadFile(s.cfg.SSL.RootCA)
if err != nil {
- s.throw(EventInitSSL, nil)
+ //s.throw(EventInitSSL, nil)
return err
}
// should append our CA cert
ok := rootCAs.AppendCertsFromPEM(CA)
if !ok {
- return couldNotAppendPemError
+ return errors.E(op, errors.Str("could not append Certs from PEM"))
}
- config := &tls.Config{
+ cfg := &tls.Config{
InsecureSkipVerify: false,
RootCAs: rootCAs,
}
- s.http.TLSConfig = config
+ s.http.TLSConfig = cfg
return nil
}
@@ -394,7 +385,7 @@ func (s *Plugin) initSSL() *http.Server {
PreferServerCipherSuites: true,
},
}
- s.throw(EventInitSSL, server)
+ //s.throw(EventInitSSL, server)
return server
}
@@ -422,16 +413,16 @@ func (s *Plugin) serveFCGI() error {
}
// throw handles service, server and pool events.
-func (s *Plugin) throw(event int, ctx interface{}) {
- for _, l := range s.lsns {
- l(event, ctx)
- }
-
- if event == roadrunner.EventServerFailure {
- // underlying rr server is dead
- s.Stop()
- }
-}
+//func (s *Plugin) throw(event int, ctx interface{}) {
+// for _, l := range s.lsns {
+// l(event, ctx)
+// }
+//
+// if event == roadrunner.EventServerFailure {
+// // underlying rr server is dead
+// s.Stop()
+// }
+//}
// tlsAddr replaces listen or host port with port configured by SSL config.
func (s *Plugin) tlsAddr(host string, forcePort bool) string {
@@ -444,3 +435,66 @@ func (s *Plugin) tlsAddr(host string, forcePort bool) string {
return host
}
+
+// Server returns associated rr workers
+func (s *Plugin) Workers() []roadrunner.WorkerBase {
+ return s.rr.Workers()
+}
+
+func (s *Plugin) Reset() error {
+ // re-read the config
+ // destroy the pool
+ // attach new one
+
+ //s.mup.Lock()
+ //defer s.mup.Unlock()
+ //
+ //s.mu.Lock()
+ //if !s.started {
+ // s.cfg = cfg
+ // s.mu.Unlock()
+ // return nil
+ //}
+ //s.mu.Unlock()
+ //
+ //if s.cfg.Differs(cfg) {
+ // return errors.New("unable to reconfigure server (cmd and pool changes are allowed)")
+ //}
+ //
+ //s.mu.Lock()
+ //previous := s.pool
+ //pWatcher := s.pController
+ //s.mu.Unlock()
+ //
+ //pool, err := NewPool(cfg.makeCommand(), s.factory, *cfg.Pool)
+ //if err != nil {
+ // return err
+ //}
+ //
+ //pool.Listen(s.poolListener)
+ //
+ //s.mu.Lock()
+ //s.cfg.Pool, s.pool = cfg.Pool, pool
+ //
+ //if s.controller != nil {
+ // s.pController = s.controller.Attach(pool)
+ //}
+ //
+ //s.mu.Unlock()
+ //
+ //s.throw(EventPoolConstruct, pool)
+ //
+ //if previous != nil {
+ // go func(previous Pool, pWatcher Controller) {
+ // s.throw(EventPoolDestruct, previous)
+ // if pWatcher != nil {
+ // pWatcher.Detach()
+ // }
+ //
+ // previous.Destroy()
+ // }(previous, pWatcher)
+ //}
+ //
+ //return nil
+ return nil
+}
diff --git a/plugins/http/response.go b/plugins/http/response.go
index 88848b9d..c3de434f 100644
--- a/plugins/http/response.go
+++ b/plugins/http/response.go
@@ -6,9 +6,9 @@ import (
"strings"
json "github.com/json-iterator/go"
+ "github.com/spiral/roadrunner/v2"
)
-
// Response handles PSR7 response logic.
type Response struct {
// Status contains response status.
@@ -22,7 +22,7 @@ type Response struct {
}
// NewResponse creates new response based on given rr payload.
-func NewResponse(p *roadrunner.Payload) (*Response, error) {
+func NewResponse(p roadrunner.Payload) (*Response, error) {
r := &Response{body: p.Body}
j := json.ConfigCompatibleWithStandardLibrary
if err := j.Unmarshal(p.Context, r); err != nil {
diff --git a/plugins/http/rpc.go b/plugins/http/rpc.go
index 7b38dece..56d8f1a1 100644
--- a/plugins/http/rpc.go
+++ b/plugins/http/rpc.go
@@ -1,34 +1,34 @@
package http
-import (
- "github.com/pkg/errors"
- "github.com/spiral/roadrunner/util"
-)
+//import (
+// "github.com/pkg/errors"
+// "github.com/spiral/roadrunner/util"
+//)
-type rpcServer struct{ svc *Service }
-
-// WorkerList contains list of workers.
-type WorkerList struct {
- // Workers is list of workers.
- Workers []*util.State `json:"workers"`
-}
-
-// Reset resets underlying RR worker pool and restarts all of it's workers.
-func (rpc *rpcServer) Reset(reset bool, r *string) error {
- if rpc.svc == nil || rpc.svc.handler == nil {
- return errors.New("http server is not running")
- }
-
- *r = "OK"
- return rpc.svc.Server().Reset()
-}
-
-// Workers returns list of active workers and their stats.
-func (rpc *rpcServer) Workers(list bool, r *WorkerList) (err error) {
- if rpc.svc == nil || rpc.svc.handler == nil {
- return errors.New("http server is not running")
- }
-
- r.Workers, err = util.ServerState(rpc.svc.Server())
- return err
-}
+//type rpcServer struct{ svc *Plugin }
+//
+//// WorkerList contains list of workers.
+//type WorkerList struct {
+// // Workers is list of workers.
+// Workers []*util.State `json:"workers"`
+//}
+//
+//// Reset resets underlying RR worker pool and restarts all of it's workers.
+//func (rpc *rpcServer) Reset(reset bool, r *string) error {
+// if rpc.svc == nil || rpc.svc.handler == nil {
+// return errors.New("http server is not running")
+// }
+//
+// *r = "OK"
+// return rpc.svc.Server().Reset()
+//}
+//
+//// Workers returns list of active workers and their stats.
+//func (rpc *rpcServer) Workers(list bool, r *WorkerList) (err error) {
+// if rpc.svc == nil || rpc.svc.handler == nil {
+// return errors.New("http server is not running")
+// }
+//
+// r.Workers, err = util.ServerState(rpc.svc.Server())
+// return err
+//}
diff --git a/plugins/http/test/.rr-http.yaml b/plugins/http/test/.rr-http.yaml
new file mode 100644
index 00000000..6fbfd378
--- /dev/null
+++ b/plugins/http/test/.rr-http.yaml
@@ -0,0 +1,37 @@
+server:
+ command: "php psr-worker.php"
+ user: ""
+ group: ""
+ env:
+ "RR_HTTP": "true"
+ relay: "pipes"
+ relayTimeout: "20s"
+
+http:
+ debug: true
+ address: 0.0.0.0:8080
+ maxRequestSize: 200
+ middleware: [ "" ]
+ uploads:
+ forbid: [ ".php", ".exe", ".bat" ]
+ trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ]
+ pool:
+ numWorkers: 4
+ maxJobs: 0
+ allocateTimeout: 60s
+ destroyTimeout: 60s
+
+ # ssl:
+ # port: 443
+ # redirect: true
+ # cert: server.crt
+ # key: server.key
+ # rootCa: root.crt
+ fcgi:
+ address: tcp://0.0.0.0:6920
+ http2:
+ enabled: false
+ h2c: false
+ maxConcurrentStreams: 128
+
+
diff --git a/plugins/http/test/http_test.go b/plugins/http/test/http_test.go
index c109d930..07925d33 100644
--- a/plugins/http/test/http_test.go
+++ b/plugins/http/test/http_test.go
@@ -1,10 +1,18 @@
package test
import (
+ "os"
+ "os/signal"
+ "syscall"
"testing"
+ "time"
"github.com/spiral/endure"
"github.com/spiral/roadrunner/v2/plugins/config"
+ "github.com/spiral/roadrunner/v2/plugins/http"
+ "github.com/spiral/roadrunner/v2/plugins/logger"
+ //rpcPlugin "github.com/spiral/roadrunner/v2/plugins/rpc"
+ "github.com/spiral/roadrunner/v2/plugins/server"
"github.com/stretchr/testify/assert"
)
@@ -14,10 +22,51 @@ func TestHTTPInit(t *testing.T) {
cfg := &config.Viper{
Path: ".rr-http.yaml",
- Prefix: "",
+ Prefix: "rr",
}
+
err = cont.RegisterAll(
+ cfg,
+ //&rpcPlugin.Plugin{},
+ &logger.ZapLogger{},
+ &server.Plugin{},
+ &http.Plugin{},
+ )
+ assert.NoError(t, err)
+
+ err = cont.Init()
+ if err != nil {
+ t.Fatal(err)
+ }
- )
+ ch, err := cont.Serve()
assert.NoError(t, err)
+
+ sig := make(chan os.Signal, 1)
+ signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
+
+ tt := time.NewTimer(time.Minute * 3)
+ for {
+ select {
+ case e := <-ch:
+ assert.Fail(t, "error", e.Error.Error())
+ err = cont.Stop()
+ if err != nil {
+ assert.FailNow(t, "error", err.Error())
+ }
+ case <-sig:
+ err = cont.Stop()
+ if err != nil {
+ assert.FailNow(t, "error", err.Error())
+ }
+ return
+ case <-tt.C:
+ // timeout
+ err = cont.Stop()
+ if err != nil {
+ assert.FailNow(t, "error", err.Error())
+ }
+ return
+ }
+ }
}
diff --git a/plugins/http/test/psr-worker.php b/plugins/http/test/psr-worker.php
new file mode 100644
index 00000000..65fc6bde
--- /dev/null
+++ b/plugins/http/test/psr-worker.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * @var Goridge\RelayInterface $relay
+ */
+use Spiral\Goridge;
+use Spiral\RoadRunner;
+
+ini_set('display_errors', 'stderr');
+require dirname(__DIR__) . "/../../vendor_php/autoload.php";
+
+$worker = new RoadRunner\Worker(new Goridge\StreamRelay(STDIN, STDOUT));
+$psr7 = new RoadRunner\PSR7Client($worker);
+
+while ($req = $psr7->acceptRequest()) {
+ try {
+ $resp = new \Zend\Diactoros\Response();
+ $resp->getBody()->write("hello world");
+
+ $psr7->respond($resp);
+ } catch (\Throwable $e) {
+ $psr7->getWorker()->error((string)$e);
+ }
+} \ No newline at end of file
diff --git a/plugins/http/test/rr-http.yaml b/plugins/http/test/rr-http.yaml
deleted file mode 100644
index 8a04a1f1..00000000
--- a/plugins/http/test/rr-http.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-http:
- address: 0.0.0.0:8080
- maxRequestSize: 200
- middlewares: [ "" ]
- uploads:
- forbid: [ ".php", ".exe", ".bat" ]
- trustedSubnets: [ "10.0.0.0/8", "127.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", "fe80::/10" ]
- workers:
- command: "php psr-worker.php pipes"
- user: ""
-
- # connection method (pipes, tcp://:9000, unix://socket.unix). default "pipes"
- relay: "pipes"
-
- pool:
- numWorkers: 4
- maxJobs: 0
- allocateTimeout: 60
- destroyTimeout: 60
-
- ssl:
- port: 443
- redirect: true
- cert: server.crt
- key: server.key
- rootCa: root.crt
- fcgi:
- address: tcp://0.0.0.0:6920
- http2:
- enabled: true
- h2c: true
- maxConcurrentStreams: 128
-
-
diff --git a/plugins/server/plugin.go b/plugins/server/plugin.go
index e096708a..4d606390 100644
--- a/plugins/server/plugin.go
+++ b/plugins/server/plugin.go
@@ -25,49 +25,47 @@ type Plugin struct {
}
// Init application provider.
-func (app *Plugin) Init(cfg config.Configurer, log log.Logger) error {
+func (server *Plugin) Init(cfg config.Configurer, log log.Logger) error {
const op = errors.Op("Init")
- err := cfg.UnmarshalKey(ServiceName, &app.cfg)
+ err := cfg.UnmarshalKey(ServiceName, &server.cfg)
if err != nil {
return errors.E(op, errors.Init, err)
}
- app.cfg.InitDefaults()
- app.log = log
+ server.cfg.InitDefaults()
+ server.log = log
+
+ server.factory, err = server.initFactory()
+ if err != nil {
+ return errors.E(errors.Op("Init factory"), err)
+ }
return nil
}
// Name contains service name.
-func (app *Plugin) Name() string {
+func (server *Plugin) Name() string {
return ServiceName
}
-func (app *Plugin) Serve() chan error {
+func (server *Plugin) Serve() chan error {
errCh := make(chan error, 1)
- var err error
-
- app.factory, err = app.initFactory()
- if err != nil {
- errCh <- errors.E(errors.Op("init factory"), err)
- }
-
return errCh
}
-func (app *Plugin) Stop() error {
- if app.factory == nil {
+func (server *Plugin) Stop() error {
+ if server.factory == nil {
return nil
}
- return app.factory.Close(context.Background())
+ return server.factory.Close(context.Background())
}
// CmdFactory provides worker command factory assocated with given context.
-func (app *Plugin) CmdFactory(env server.Env) (func() *exec.Cmd, error) {
+func (server *Plugin) CmdFactory(env server.Env) (func() *exec.Cmd, error) {
var cmdArgs []string
// create command according to the config
- cmdArgs = append(cmdArgs, strings.Split(app.cfg.Command, " ")...)
+ cmdArgs = append(cmdArgs, strings.Split(server.cfg.Command, " ")...)
return func() *exec.Cmd {
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
@@ -75,67 +73,67 @@ func (app *Plugin) CmdFactory(env server.Env) (func() *exec.Cmd, error) {
// if user is not empty, and OS is linux or macos
// execute php worker from that particular user
- if app.cfg.User != "" {
- err := util.ExecuteFromUser(cmd, app.cfg.User)
+ if server.cfg.User != "" {
+ err := util.ExecuteFromUser(cmd, server.cfg.User)
if err != nil {
return nil
}
}
- cmd.Env = app.setEnv(env)
+ cmd.Env = server.setEnv(env)
return cmd
}, nil
}
// NewWorker issues new standalone worker.
-func (app *Plugin) NewWorker(ctx context.Context, env server.Env) (roadrunner.WorkerBase, error) {
+func (server *Plugin) NewWorker(ctx context.Context, env server.Env) (roadrunner.WorkerBase, error) {
const op = errors.Op("new worker")
- spawnCmd, err := app.CmdFactory(env)
+ spawnCmd, err := server.CmdFactory(env)
if err != nil {
return nil, errors.E(op, err)
}
- w, err := app.factory.SpawnWorkerWithContext(ctx, spawnCmd())
+ w, err := server.factory.SpawnWorkerWithContext(ctx, spawnCmd())
if err != nil {
return nil, errors.E(op, err)
}
- w.AddListener(app.collectLogs)
+ w.AddListener(server.collectLogs)
return w, nil
}
// NewWorkerPool issues new worker pool.
-func (app *Plugin) NewWorkerPool(ctx context.Context, opt roadrunner.PoolConfig, env server.Env) (roadrunner.Pool, error) {
- spawnCmd, err := app.CmdFactory(env)
+func (server *Plugin) NewWorkerPool(ctx context.Context, opt roadrunner.PoolConfig, env server.Env) (roadrunner.Pool, error) {
+ spawnCmd, err := server.CmdFactory(env)
if err != nil {
return nil, err
}
- p, err := roadrunner.NewPool(ctx, spawnCmd, app.factory, opt)
+ p, err := roadrunner.NewPool(ctx, spawnCmd, server.factory, opt)
if err != nil {
return nil, err
}
- p.AddListener(app.collectLogs)
+ p.AddListener(server.collectLogs)
return p, nil
}
// creates relay and worker factory.
-func (app *Plugin) initFactory() (roadrunner.Factory, error) {
+func (server *Plugin) initFactory() (roadrunner.Factory, error) {
const op = errors.Op("network factory init")
- if app.cfg.Relay == "" || app.cfg.Relay == "pipes" {
+ if server.cfg.Relay == "" || server.cfg.Relay == "pipes" {
return roadrunner.NewPipeFactory(), nil
}
- dsn := strings.Split(app.cfg.Relay, "://")
+ dsn := strings.Split(server.cfg.Relay, "://")
if len(dsn) != 2 {
return nil, errors.E(op, errors.Network, errors.Str("invalid DSN (tcp://:6001, unix://file.sock)"))
}
- lsn, err := util.CreateListener(app.cfg.Relay)
+ lsn, err := util.CreateListener(server.cfg.Relay)
if err != nil {
return nil, errors.E(op, errors.Network, err)
}
@@ -143,16 +141,16 @@ func (app *Plugin) initFactory() (roadrunner.Factory, error) {
switch dsn[0] {
// sockets group
case "unix":
- return roadrunner.NewSocketServer(lsn, app.cfg.RelayTimeout), nil
+ return roadrunner.NewSocketServer(lsn, server.cfg.RelayTimeout), nil
case "tcp":
- return roadrunner.NewSocketServer(lsn, app.cfg.RelayTimeout), nil
+ return roadrunner.NewSocketServer(lsn, server.cfg.RelayTimeout), nil
default:
return nil, errors.E(op, errors.Network, errors.Str("invalid DSN (tcp://:6001, unix://file.sock)"))
}
}
-func (app *Plugin) setEnv(e server.Env) []string {
- env := append(os.Environ(), fmt.Sprintf("RR_RELAY=%s", app.cfg.Relay))
+func (server *Plugin) setEnv(e server.Env) []string {
+ env := append(os.Environ(), fmt.Sprintf("RR_RELAY=%s", server.cfg.Relay))
for k, v := range e {
env = append(env, fmt.Sprintf("%s=%s", strings.ToUpper(k), v))
}
@@ -160,13 +158,13 @@ func (app *Plugin) setEnv(e server.Env) []string {
return env
}
-func (app *Plugin) collectLogs(event interface{}) {
+func (server *Plugin) collectLogs(event interface{}) {
if we, ok := event.(roadrunner.WorkerEvent); ok {
switch we.Event {
case roadrunner.EventWorkerError:
- app.log.Error(we.Payload.(error).Error(), "pid", we.Worker.Pid())
+ server.log.Error(we.Payload.(error).Error(), "pid", we.Worker.Pid())
case roadrunner.EventWorkerLog:
- app.log.Debug(strings.TrimRight(string(we.Payload.([]byte)), " \n\t"), "pid", we.Worker.Pid())
+ server.log.Debug(strings.TrimRight(string(we.Payload.([]byte)), " \n\t"), "pid", we.Worker.Pid())
}
}
}
diff --git a/src/Diactoros/ServerRequestFactory.php b/src/Diactoros/ServerRequestFactory.php
new file mode 100644
index 00000000..3fcf8e29
--- /dev/null
+++ b/src/Diactoros/ServerRequestFactory.php
@@ -0,0 +1,26 @@
+<?php
+
+/**
+ * High-performance PHP process supervisor and load balancer written in Go
+ *
+ * @author Wolfy-J
+ */
+declare(strict_types=1);
+
+namespace Spiral\RoadRunner\Diactoros;
+
+use Psr\Http\Message\ServerRequestFactoryInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Zend\Diactoros\ServerRequest;
+
+final class ServerRequestFactory implements ServerRequestFactoryInterface
+{
+ /**
+ * @inheritdoc
+ */
+ public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
+ {
+ $uploadedFiles = [];
+ return new ServerRequest($serverParams, $uploadedFiles, $uri, $method);
+ }
+}
diff --git a/src/Diactoros/StreamFactory.php b/src/Diactoros/StreamFactory.php
new file mode 100644
index 00000000..cc0a5306
--- /dev/null
+++ b/src/Diactoros/StreamFactory.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * High-performance PHP process supervisor and load balancer written in Go
+ *
+ * @author Wolfy-J
+ */
+declare(strict_types=1);
+
+namespace Spiral\RoadRunner\Diactoros;
+
+use RuntimeException;
+use Psr\Http\Message\StreamFactoryInterface;
+use Psr\Http\Message\StreamInterface;
+use Zend\Diactoros\Stream;
+
+final class StreamFactory implements StreamFactoryInterface
+{
+ /**
+ * @inheritdoc
+ * @throws RuntimeException
+ */
+ public function createStream(string $content = ''): StreamInterface
+ {
+ $resource = fopen('php://temp', 'rb+');
+
+ if (! \is_resource($resource)) {
+ throw new RuntimeException('Cannot create stream');
+ }
+
+ fwrite($resource, $content);
+ rewind($resource);
+ return $this->createStreamFromResource($resource);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function createStreamFromFile(string $file, string $mode = 'rb'): StreamInterface
+ {
+ $resource = fopen($file, $mode);
+
+ if (! \is_resource($resource)) {
+ throw new RuntimeException('Cannot create stream');
+ }
+
+ return $this->createStreamFromResource($resource);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function createStreamFromResource($resource): StreamInterface
+ {
+ return new Stream($resource);
+ }
+}
diff --git a/src/Diactoros/UploadedFileFactory.php b/src/Diactoros/UploadedFileFactory.php
new file mode 100644
index 00000000..45773287
--- /dev/null
+++ b/src/Diactoros/UploadedFileFactory.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * High-performance PHP process supervisor and load balancer written in Go
+ *
+ * @author Wolfy-J
+ */
+declare(strict_types=1);
+
+namespace Spiral\RoadRunner\Diactoros;
+
+use Psr\Http\Message\StreamInterface;
+use Psr\Http\Message\UploadedFileFactoryInterface;
+use Psr\Http\Message\UploadedFileInterface;
+use Zend\Diactoros\UploadedFile;
+
+final class UploadedFileFactory implements UploadedFileFactoryInterface
+{
+ /**
+ * @inheritdoc
+ */
+ public function createUploadedFile(
+ StreamInterface $stream,
+ int $size = null,
+ int $error = \UPLOAD_ERR_OK,
+ string $clientFilename = null,
+ string $clientMediaType = null
+ ): UploadedFileInterface {
+ if ($size === null) {
+ $size = (int) $stream->getSize();
+ }
+
+ /** @var resource $stream */
+ return new UploadedFile($stream, $size, $error, $clientFilename, $clientMediaType);
+ }
+}
diff --git a/src/Exception/MetricException.php b/src/Exception/MetricException.php
index d5b738b8..d5b738b8 100755..100644
--- a/src/Exception/MetricException.php
+++ b/src/Exception/MetricException.php
diff --git a/src/Exception/RoadRunnerException.php b/src/Exception/RoadRunnerException.php
index cd657502..f83c3dd4 100755..100644
--- a/src/Exception/RoadRunnerException.php
+++ b/src/Exception/RoadRunnerException.php
@@ -9,6 +9,6 @@ declare(strict_types=1);
namespace Spiral\RoadRunner\Exception;
-class RoadRunnerException extends \RuntimeException
+class RoadRunnerException extends \Spiral\RoadRunner\Exceptions\RoadRunnerException
{
}
diff --git a/src/Exceptions/RoadRunnerException.php b/src/Exceptions/RoadRunnerException.php
new file mode 100644
index 00000000..43967893
--- /dev/null
+++ b/src/Exceptions/RoadRunnerException.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * Spiral Framework.
+ *
+ * @license MIT
+ * @author Anton Titov (Wolfy-J)
+ */
+declare(strict_types=1);
+
+namespace Spiral\RoadRunner\Exceptions;
+
+/**
+ * @deprecated use \Spiral\RoadRunner\Exception\RoadRunnerException instead
+ */
+class RoadRunnerException extends \RuntimeException
+{
+}
diff --git a/src/Http/HttpClient.php b/src/HttpClient.php
index 4ca152c8..4ca152c8 100644
--- a/src/Http/HttpClient.php
+++ b/src/HttpClient.php
diff --git a/src/Logger/.empty b/src/Logger/.empty
deleted file mode 100644
index e69de29b..00000000
--- a/src/Logger/.empty
+++ /dev/null
diff --git a/src/Metrics/Metrics.php b/src/Metrics.php
index d6b6e1da..d6b6e1da 100644
--- a/src/Metrics/Metrics.php
+++ b/src/Metrics.php
diff --git a/src/Metrics/MetricsInterface.php b/src/MetricsInterface.php
index ec2009b0..ec2009b0 100644
--- a/src/Metrics/MetricsInterface.php
+++ b/src/MetricsInterface.php
diff --git a/src/Http/PSR7Client.php b/src/PSR7Client.php
index 777dd891..777dd891 100644
--- a/src/Http/PSR7Client.php
+++ b/src/PSR7Client.php
diff --git a/src/Worker.php b/src/Worker.php
index d509562e..d509562e 100755..100644
--- a/src/Worker.php
+++ b/src/Worker.php
diff --git a/src/WorkerInterface.php b/src/WorkerInterface.php
deleted file mode 100644
index e69de29b..00000000
--- a/src/WorkerInterface.php
+++ /dev/null
diff --git a/static_pool.go b/static_pool.go
index 4e49b212..d5511018 100755
--- a/static_pool.go
+++ b/static_pool.go
@@ -54,6 +54,9 @@ type StaticPool struct {
// NewPool creates new worker pool and task multiplexer. StaticPool will initiate with one worker.
func NewPool(ctx context.Context, cmd func() *exec.Cmd, factory Factory, cfg PoolConfig, options ...PoolOptions) (Pool, error) {
const op = errors.Op("NewPool")
+ if factory == nil {
+ return nil, errors.E(op, errors.Str("no factory initialized"))
+ }
cfg.InitDefaults()
if cfg.Debug {