Skip to content

Commit 4de2a1a

Browse files
committed
Fixed some balancing issues with high traffic and added many other stuff.
Added hot-code reload, which basically reloads all workers when php code has changed. Added debug option. Added logging option. Increase performance and removed Stackable stuff. Added config command to configure ppm.json. Added static file server. Fixed Symfony bootstrap so the profiler works more correctly (but not yet perfect)
1 parent 117f244 commit 4de2a1a

File tree

5 files changed

+105
-70
lines changed

5 files changed

+105
-70
lines changed

Bootstraps/Laravel.php

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,18 @@
77
/**
88
* A default bootstrap for the Laravel framework
99
*/
10-
class Laravel implements StackableBootstrapInterface
10+
class Laravel implements BootstrapInterface
1111
{
1212
/**
1313
* @var string|null The application environment
1414
*/
1515
protected $appenv;
1616

17+
/**
18+
* @var bool
19+
*/
20+
protected $debug = false;
21+
1722
/**
1823
* Store the application
1924
*
@@ -25,9 +30,11 @@ class Laravel implements StackableBootstrapInterface
2530
* Instantiate the bootstrap, storing the $appenv
2631
* @param string|null $appenv The environment your application will use to bootstrap (if any)
2732
*/
28-
public function __construct($appenv)
33+
public function __construct($appenv, $debug)
2934
{
3035
$this->appenv = $appenv;
36+
$this->debug = $debug;
37+
putenv("APP_DEBUG=" . ($debug ? 'TRUE' : 'FALSE'));
3138
}
3239

3340
/**
@@ -48,21 +55,4 @@ public function getApplication()
4855

4956
throw new \RuntimeException('Laravel bootstrap file not found');
5057
}
51-
52-
/**
53-
* Return the StackPHP stack.
54-
* @param Builder $stack
55-
* @return Builder
56-
*/
57-
public function getStack(Builder $stack)
58-
{
59-
$sessionReject = $this->app->bound('session.reject') ? $this->app['session.reject'] : null;
60-
61-
$stack
62-
->push('Illuminate\Cookie\Guard', $this->app['encrypter'])
63-
->push('Illuminate\Cookie\Queue', $this->app['cookie'])
64-
->push('Illuminate\Session\Middleware', $this->app['session'], $sessionReject);
65-
66-
return $stack;
67-
}
6858
}

Bootstraps/StackableBootstrapInterface.php

Lines changed: 0 additions & 13 deletions
This file was deleted.

Bootstraps/Symfony.php

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,35 @@
11
<?php
22

33
namespace PHPPM\Bootstraps;
4-
5-
use Stack\Builder;
4+
use Symfony\Component\HttpFoundation\Request;
65

76
/**
87
* A default bootstrap for the Symfony framework
98
*/
10-
class Symfony implements StackableBootstrapInterface
9+
class Symfony implements BootstrapInterface
1110
{
1211
/**
1312
* @var string|null The application environment
1413
*/
1514
protected $appenv;
1615

16+
/**
17+
* @var boolean
18+
*/
19+
protected $debug;
20+
1721
/**
1822
* Instantiate the bootstrap, storing the $appenv
1923
*/
20-
public function __construct($appenv)
24+
public function __construct($appenv, $debug)
2125
{
2226
$this->appenv = $appenv;
27+
$this->debug = $debug;
2328
}
2429

2530
/**
2631
* Create a Symfony application
32+
* @return SymfonyAppKernel
2733
*/
2834
public function getApplication()
2935
{
@@ -33,18 +39,16 @@ public function getApplication()
3339

3440
$this->includeAutoload();
3541

36-
$app = new \AppKernel($this->appenv, false);
42+
$app = new SymfonyAppKernel($this->appenv, $this->debug); //which extends \AppKernel
3743
$app->loadClassCache();
44+
$app->boot();
3845

39-
return $app;
40-
}
46+
//warm up
47+
$request = new Request();
48+
$request->setMethod(Request::METHOD_HEAD);
49+
$app->handle($request);
4150

42-
/**
43-
* Return the StackPHP stack.
44-
*/
45-
public function getStack(Builder $stack)
46-
{
47-
return $stack;
51+
return $app;
4852
}
4953

5054
/**

Bootstraps/SymfonyAppKernel.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace PHPPM\Bootstraps;
4+
5+
use Symfony\Component\HttpKernel\KernelInterface;
6+
7+
class SymfonyAppKernel extends \AppKernel implements KernelInterface
8+
{
9+
10+
/**
11+
* Does some necessary preparation before each request.
12+
*/
13+
public function preHandle()
14+
{
15+
//resets Kernels startTime, so Symfony can correctly calculate the execution time
16+
$this->startTime = microtime(true);
17+
}
18+
19+
/**
20+
* Does some necessary clean up after each request.
21+
*/
22+
public function postHandle()
23+
{
24+
//resets stopwatch, so it can correctly calculate the execution time
25+
$this->getContainer()->get('debug.stopwatch')->__construct();
26+
27+
if ($this->getContainer()->has('profiler')) {
28+
// since Symfony does not reset Profiler::disable() calls after each request, we need to do it,
29+
// so the profiler bar is visible after the second request as well.
30+
$this->getContainer()->get('profiler')->enable();
31+
}
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function getRootDir()
38+
{
39+
if (null === $this->rootDir) {
40+
$r = new \ReflectionClass('\AppKernel');
41+
$this->rootDir = dirname($r->getFileName());
42+
}
43+
44+
return $this->rootDir;
45+
}
46+
47+
}

Bridges/HttpKernel.php

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
namespace PHPPM\Bridges;
44

5-
use PHPPM\AppBootstrapInterface;
65
use PHPPM\Bootstraps\BootstrapInterface;
7-
use PHPPM\Bridges\BridgeInterface;
6+
use PHPPM\Bootstraps\SymfonyAppKernel;
87
use React\Http\Request as ReactRequest;
98
use React\Http\Response as ReactResponse;
10-
use Stack\Builder;
119
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
1210
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
1311
use Symfony\Component\HttpFoundation\StreamedResponse as SymfonyStreamedResponse;
@@ -34,9 +32,10 @@ class HttpKernel implements BridgeInterface
3432
*
3533
* @param string $appBootstrap The name of the class used to bootstrap the application
3634
* @param string|null $appenv The environment your application will use to bootstrap (if any)
35+
* @param boolean $debug If debug is enabled
3736
* @see http://stackphp.com
3837
*/
39-
public function bootstrap($appBootstrap, $appenv)
38+
public function bootstrap($appBootstrap, $appenv, $debug)
4039
{
4140
// include applications autoload
4241
$autoloader = dirname(realpath($_SERVER['SCRIPT_NAME'])) . '/vendor/autoload.php';
@@ -46,19 +45,21 @@ public function bootstrap($appBootstrap, $appenv)
4645

4746
$appBootstrap = $this->normalizeAppBootstrap($appBootstrap);
4847

49-
$bootstrap = new $appBootstrap($appenv);
48+
$bootstrap = new $appBootstrap($appenv, $debug);
5049

5150
if ($bootstrap instanceof BootstrapInterface) {
5251
$this->application = $bootstrap->getApplication();
53-
54-
if ($bootstrap instanceof StackableBootstrapInterface) {
55-
$stack = new Builder();
56-
$stack = $bootstrap->getStack($stack);
57-
$this->application = $stack->resolve($this->application);
58-
}
5952
}
6053
}
6154

55+
/**
56+
* {@inheritdoc}
57+
*/
58+
public function getStaticDirectory()
59+
{
60+
return 'web/';
61+
}
62+
6263
/**
6364
* Handle a request using a HttpKernelInterface implementing application.
6465
*
@@ -73,11 +74,10 @@ public function onRequest(ReactRequest $request, ReactResponse $response)
7374

7475
$content = '';
7576
$headers = $request->getHeaders();
76-
$contentLength = isset($headers['Content-Length']) ? (int) $headers['Content-Length'] : 0;
77+
$contentLength = isset($headers['Content-Length']) ? (int)$headers['Content-Length'] : 0;
7778

78-
$request->on('data', function($data)
79-
use ($request, $response, &$content, $contentLength)
80-
{
79+
$request->on('data', function ($data)
80+
use ($request, $response, &$content, $contentLength) {
8181
// read data (may be empty for GET request)
8282
$content .= $data;
8383

@@ -86,18 +86,26 @@ public function onRequest(ReactRequest $request, ReactResponse $response)
8686
$syRequest = self::mapRequest($request, $content);
8787

8888
try {
89+
if ($this->application instanceof SymfonyAppKernel) {
90+
$this->application->preHandle();
91+
}
92+
8993
$syResponse = $this->application->handle($syRequest);
9094
} catch (\Exception $exception) {
9195
$response->writeHead(500); // internal server error
9296
$response->end();
93-
return;
97+
throw $exception;
9498
}
9599

96100
self::mapResponse($response, $syResponse);
97101

98102
if ($this->application instanceof TerminableInterface) {
99103
$this->application->terminate($syRequest, $syResponse);
100104
}
105+
106+
if ($this->application instanceof SymfonyAppKernel) {
107+
$this->application->postHandle();
108+
}
101109
}
102110
});
103111
}
@@ -124,15 +132,15 @@ protected static function mapRequest(ReactRequest $reactRequest, $content)
124132

125133
$cookies = array();
126134
if (isset($headers['Cookie'])) {
127-
$headersCookie = explode(';', $headers['Cookie']);
128-
foreach ($headersCookie as $cookie) {
129-
list($name, $value) = explode('=', trim($cookie));
130-
$cookies[$name] = $value;
131-
}
135+
$headersCookie = explode(';', $headers['Cookie']);
136+
foreach ($headersCookie as $cookie) {
137+
list($name, $value) = explode('=', trim($cookie));
138+
$cookies[$name] = $value;
139+
}
132140
}
133141

134142
$syRequest = new SymfonyRequest(
135-
// $query, $request, $attributes, $cookies, $files, $server, $content
143+
// $query, $request, $attributes, $cookies, $files, $server, $content
136144
$query, $post, array(), $cookies, array(), array(), $content
137145
);
138146

@@ -151,7 +159,7 @@ protected static function mapRequest(ReactRequest $reactRequest, $content)
151159
* @param SymfonyResponse $syResponse
152160
*/
153161
protected static function mapResponse(ReactResponse $reactResponse,
154-
SymfonyResponse $syResponse)
162+
SymfonyResponse $syResponse)
155163
{
156164
$headers = $syResponse->headers->all();
157165
$reactResponse->writeHead($syResponse->getStatusCode(), $headers);
@@ -162,8 +170,7 @@ protected static function mapResponse(ReactResponse $reactResponse,
162170
$syResponse->sendContent();
163171
$content = ob_get_contents();
164172
ob_end_clean();
165-
}
166-
else {
173+
} else {
167174
$content = $syResponse->getContent();
168175
}
169176

0 commit comments

Comments
 (0)