Skip to content
This repository was archived by the owner on Mar 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
208511b
Merge pull request #81 from swooletw/develop
albertcht Jun 12, 2018
51dea74
Merge pull request #84 from swooletw/develop
albertcht Jun 12, 2018
9adb5bf
remove ext-swoole dependency from composer.json becauseof unknown com…
albertcht Jun 12, 2018
32102cf
Merge pull request #87 from swooletw/develop
albertcht Jun 12, 2018
82b0913
fix sandbox enable
albertcht Jun 12, 2018
7e1a9cb
Merge pull request #88 from swooletw/develop
albertcht Jun 12, 2018
b30fc40
Update README.md
albertcht Jun 16, 2018
3b816be
fix parser test in swoole 4.0
albertcht Jun 16, 2018
e5f1cf7
Merge pull request #91 from swooletw/develop
albertcht Jun 16, 2018
b32376c
Update ISSUE_TEMPLATE.md
albertcht Jul 21, 2018
d30f44b
Update ISSUE_TEMPLATE.md
albertcht Jul 27, 2018
7c11d75
Update ISSUE_TEMPLATE.md
albertcht Jul 28, 2018
39229ef
Supported Swoole async task queue driver
damonto Sep 1, 2018
0e97d59
Fix AsyncTaskJob not found
damonto Sep 1, 2018
214b619
Remove ServiceProvider
damonto Sep 1, 2018
db8ffe2
Fix unable create swoole_server
damonto Sep 1, 2018
fc59fa9
fix conflicts
damonto Sep 2, 2018
4034bf3
fix conflicts again
damonto Sep 2, 2018
b7249f6
Merged coroutine feature
damonto Sep 2, 2018
83bcd34
Add phpunit test cases
damonto Sep 2, 2018
5783325
Change comments format
damonto Sep 2, 2018
58087d0
Remove getJobExpiration because of unused
damonto Sep 2, 2018
362fbc0
Don't override createObjectPayload
damonto Sep 2, 2018
d4656bf
Compatible with older versions
damonto Sep 2, 2018
a840966
Fix undefined method getContainer()
damonto Sep 2, 2018
1544615
Move getContainer method to SwooleTaskJob
damonto Sep 2, 2018
6792ed8
Uncomment code
damonto Sep 2, 2018
18c8444
Swoole_timer_after first parameter is microsecond
damonto Sep 2, 2018
7828ef2
Merge branch 'feature/coroutine_feature' into feature/swoole_async_task
albertcht Sep 2, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Please answer these questions before submitting your issue. Thanks!
Make sure you read **Issues Guideline** and answer these questions before submitting your issue. Thanks!
(Any **non-English** issues will be closed immediately.)

1. Please provide your PHP and Swoole version. (`php -v` and `php --ri swoole`)

Expand Down
37 changes: 21 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This package provides a high performance HTTP server to speed up your Laravel/Lu
## Features

* Run **Laravel/Lumen** application on top of **Swoole**.
* Outstanding performance boosting up to **30x**.
* Outstanding performance boosting up to **5x** faster.
* Sandbox mode to isolate app container.
* Support running websocket server in **Laravel**.
* Support `Socket.io` protocol.
Expand All @@ -28,7 +28,8 @@ Please see [Wiki](https://github.com/swooletw/laravel-swoole/wiki)

## Benchmark

Test with clean Lumen 5.5, using MacBook Air 13, 2015.
Test with clean Lumen 5.6, using DigitalOcean 3 CPUs / 1 GB Memory / PHP 7.2 / Ubuntu 16.04.4 x64

Benchmarking Tool: [wrk](https://github.com/wg/wrk)

```
Expand All @@ -38,27 +39,31 @@ wrk -t4 -c100 http://your.app
### Nginx with FPM

```
Running 10s test @ http://lumen.app:9999
4 threads and 100 connections
wrk -t4 -c10 http://lumen-swoole.local

Running 10s test @ http://lumen-swoole.local
4 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.14s 191.03ms 1.40s 90.31%
Req/Sec 22.65 10.65 50.00 65.31%
815 requests in 10.07s, 223.65KB read
Requests/sec: 80.93
Transfer/sec: 22.21KB
Latency 6.41ms 1.56ms 19.71ms 71.32%
Req/Sec 312.99 28.71 373.00 72.00%
12469 requests in 10.01s, 3.14MB read
Requests/sec: 1245.79
Transfer/sec: 321.12KB
```

### Swoole HTTP Server

```
Running 10s test @ http://127.0.0.1:1215
4 threads and 100 connections
wrk -t4 -c10 http://lumen-swoole.local:1215

Running 10s test @ http://lumen-swoole.local:1215
4 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 11.58ms 4.74ms 68.73ms 81.63%
Req/Sec 2.19k 357.43 2.90k 69.50%
87879 requests in 10.08s, 15.67MB read
Requests/sec: 8717.00
Transfer/sec: 1.55MB
Latency 2.39ms 4.88ms 105.21ms 94.55%
Req/Sec 1.26k 197.13 1.85k 68.75%
50248 requests in 10.02s, 10.88MB read
Requests/sec: 5016.94
Transfer/sec: 1.09MB
```

## Q&A
Expand Down
16 changes: 15 additions & 1 deletion src/HttpServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use SwooleTW\Http\Commands\HttpServerCommand;
use Swoole\Websocket\Server as WebsocketServer;
use SwooleTW\Http\Coroutine\Connectors\MySqlConnector;
use SwooleTW\Http\Task\Connectors\SwooleTaskConnector;

/**
* @codeCoverageIgnore
Expand Down Expand Up @@ -45,6 +46,7 @@ public function register()
$this->registerManager();
$this->registerCommands();
$this->registerDatabaseDriver();
$this->registerSwooleQueueDriver();
}

/**
Expand Down Expand Up @@ -129,7 +131,7 @@ protected function configureSwooleServer()
$config = $this->app['config']->get('swoole_http.server.options');

// only enable task worker in websocket mode
if (! $this->isWebsocket) {
if (env('QUEUE_DRIVER') !== 'swoole' && ! $this->isWebsocket) {
unset($config['task_worker_num']);
}

Expand Down Expand Up @@ -174,4 +176,16 @@ protected function registerDatabaseDriver()
});
});
}

/**
* Register queue driver for swoole async task.
*/
protected function registerSwooleQueueDriver()
{
$this->app->afterResolving('queue', function ($manager) {
$manager->addConnector('swoole', function () {
return new SwooleTaskConnector(static::$server);
});
});
}
}
20 changes: 15 additions & 5 deletions src/Server/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Throwable;
use Swoole\Http\Server;
use SwooleTW\Http\Server\Sandbox;
use SwooleTW\Http\Task\SwooleTaskJob;
use Illuminate\Support\Facades\Facade;
use SwooleTW\Http\Websocket\Websocket;
use SwooleTW\Http\Transformers\Request;
Expand Down Expand Up @@ -228,13 +229,22 @@ public function onTask($server, $taskId, $srcWorkerId, $data)
$this->container['events']->fire('swoole.task', func_get_args());

try {
// push websocket message
if ($this->isWebsocket
&& array_key_exists('action', $data)
&& $data['action'] === Websocket::PUSH_ACTION) {
$this->pushMessage($server, $data['data'] ?? []);
if (is_array($data)) {
// push websocket message
if ($this->isWebsocket
&& array_key_exists('action', $data)
&& $data['action'] === Websocket::PUSH_ACTION) {
$this->pushMessage($server, $data['data'] ?? []);
}
} elseif (is_string($data)) {
$decoded= json_decode($data, true);

if (JSON_ERROR_NONE === json_last_error() && isset($decoded['job'])) {
(new SwooleTaskJob($this->container, $server, $data, $taskId, $srcWorkerId))->fire();
}
}
} catch (Throwable $e) {
dump($e);
$this->logServerError($e);
}
}
Expand Down
38 changes: 38 additions & 0 deletions src/Task/Connectors/SwooleTaskConnector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace SwooleTW\Http\Task\Connectors;

use SwooleTW\Http\Task\SwooleTaskQueue;
use Illuminate\Queue\Connectors\ConnectorInterface;

class SwooleTaskConnector implements ConnectorInterface
{
/**
* Swoole Server Instance
*
* @var \Swoole\Http\Server
*/
protected $swoole;

/**
* Create a new Swoole Async task connector instance.
*
* @param \Swoole\Http\Server $swoole
* @return void
*/
public function __construct($swoole)
{
$this->swoole = $swoole;
}

/**
* Establish a queue connection.
*
* @param array $config
* @return \Illuminate\Contracts\Queue\Queue
*/
public function connect(array $config)
{
return new SwooleTaskQueue($this->swoole);
}
}
107 changes: 107 additions & 0 deletions src/Task/SwooleTaskJob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

namespace SwooleTW\Http\Task;

use Illuminate\Queue\Jobs\Job;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Queue\Job as JobContract;

class SwooleTaskJob extends Job implements JobContract
{
/**
* The Swoole Server instance.
*
* @var \Swoole\Http\Server
*/
protected $swoole;

/**
* The Swoole async job raw payload.
*
* @var array
*/
protected $job;

/**
* The Task id
*
* @var int
*/
protected $taskId;

/**
* The src worker Id
*
* @var int
*/
protected $srcWrokerId;

/**
* Create a new job instance.
*
* @param \Illuminate\Container\Container $container
* @param \Swoole\Http\Server $swoole
* @param string $job
* @return void
*/
public function __construct(Container $container, $swoole, $job, $taskId, $srcWrokerId)
{
$this->container = $container;
$this->swoole = $swoole;
$this->job = $job;
$this->taskId = $taskId;
$this->srcWorkderId = $srcWrokerId;
}

/**
* Fire the job.
*
* @return void
*/
public function fire()
{
if (method_exists($this, 'resolveAndFire')) {
$this->resolveAndFire(json_decode($this->getRawBody(), true));
} else {
parent::fire();
}
}

/**
* Get the number of times the job has been attempted.
* @return int
*/
public function attempts()
{
return ($this->job['attempts'] ?? null) + 1;
}

/**
* Get the raw body string for the job.
* @return string
*/
public function getRawBody()
{
return $this->job;
}


/**
* Get the job identifier.
* @return string
*/
public function getJobId()
{
return $this->taskId;
}

/**
* Get the service container instance.
*
* @return \Illuminate\Container\Container
*/
public function getContainer()
{
return $this->container;
}
}
Loading