joanhey / AdapterMan

Run almost any PHP app faster and asynchronously with Workerman, without touch 1 line of code in your fw or app. Also use it as Serverless.
https://twitter.com/adaptermanphp
MIT License
730 stars 44 forks source link

Can you help create recipe for Easeapp PHP Framework #44

Open raghuveer opened 1 year ago

raghuveer commented 1 year ago

Hi

Easeapp PHP Framework is similar to Laravel application in folder structure perspective while it is a simple PSR compliant micro framework in PHP.

EABlueprint (Application): https://github.com/easeappphp/EABlueprint EaseApp framework (library in composer vendor folder): https://github.com/easeappphp/EaseApp

Adapterman project is interesting. Can you help create a recipe for running EABlueprint (Application) using Adapterman?

Thank you

joanhey commented 1 year ago

Thank you!!! I think that will be easy, but I want your feedback with real apps.

I was busy these days, my mother was sick. In 1-2 days we'll have a recipe for Easeapp. In github, and also announced in our twiter(X) channel.

raghuveer commented 1 year ago

Thank you

P.S. Please take care of your mother

joanhey commented 1 year ago

Please, could you try it ?

start.php

<?php
declare(strict_types=1);

ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);

/*
*--------------------------------------------------------------------------
* Prevent Direct Access
*--------------------------------------------------------------------------
*
* This is to prevent direct access to a file inside public root or public_html or www folder.
*
*/
defined('START') or define("START", "No Direct Access");

/*
*--------------------------------------------------------------------------
* Build Foundation - Register the Auto Loader
*--------------------------------------------------------------------------
*
* Composer provides a convenient, automatically generated class loader to autoload files for
* this application.
*
*/
require_once __DIR__ . '/vendor/autoload.php';

use EaseAppPHP\App;

/*
*--------------------------------------------------------------------------
* Construct your Dream Building - Bootstrap the Application
*--------------------------------------------------------------------------
*
* Bootstrap the building, i.e., load dependencies and connect them to the PSR-11 compatible dependency injection container.
*
*/
global $app; // workerman

$container = require_once __DIR__.'/bootstrap/app.php';

$application = new App($container);
$container->instance('App', $application);

$app = $container->get('App');

$app->init();

/*
*--------------------------------------------------------------------------
* Enjoy the moments - Run the Application
*--------------------------------------------------------------------------
*
* Once we have the application, we can handle incoming server requests for web (web pages / Ajax calls / REST APIs / SOAP
* APIs) with a response back to the client's browser.
*
*/

function run(): string
{
    global $app;
    ob_start();

    $app->run();

    return ob_get_clean();
}

After check the Easephp code, I think that you need to move the request get from superglobals, from the bootstrap/app https://github.com/easeappphp/EABlueprint/blob/master/bootstrap/app.php#L98

Because with any persistent app (worker), the bootstrap will run only 1 time. And always will have the same request. That need to be moved to the $app->run() to take the new request each time. And the $serverRequest will be outside of the bootstrap.

Also the server timezone is static, and only need to run 1 time, and it isn't necessary to depend on the request.

joanhey commented 1 year ago

Later I'll try to add Easeapp to the Techempower benchmark. With normal php-fpm and Adapterman, to compare the performance change.

joanhey commented 1 year ago

Why you don't change this code ?

$container = require_once __DIR__.'/bootstrap/app.php';

$application = new App($container);
$container->instance('App', $application);

$app = $container->get('App');

$app->init();

$app->run();

with:

$container = require_once __DIR__.'/bootstrap/app.php';

$app = new App($container);
$container->instance('App', $app);

$app->init();

$app->run();

For me it's redundant, and make the app slower with php-fpm. :thinking: possibly it's necessary use the first.

raghuveer commented 1 year ago

I have created start.php in the application root folder beside composer.json and committed the code on github. Hope this is the folder we keep start.php in know?.

https://github.com/easeappphp/EABlueprint/blob/master/start.php

Moved serverRequest initialization and timezone setting from bootstrap/app.php of EABlueprint to App.php of Easeapp framework as you suggested.

P.S This application works on PHP 7.4. Post successful usage with Adapterman, I will make changes in dependencies and in the framework code as needed to make it compatible to PHP 8.1 and PHP 8.2

Thank you

raghuveer commented 1 year ago

Why you don't change this code ?

$container = require_once __DIR__.'/bootstrap/app.php';

$application = new App($container);
$container->instance('App', $application);

$app = $container->get('App');

$app->init();

$app->run();

with:

$container = require_once __DIR__.'/bootstrap/app.php';

$app = new App($container);
$container->instance('App', $app);

$app->init();

$app->run();

For me it's redundant, and make the app slower with php-fpm. 🤔 possibly it's necessary use the first.

Are these changes recommended to be done in the newly created "start.php" or in "public/index.php"?

Note: I quickly tried in "public/index.php". But I started getting Emitter exceptions in the lines of "headers already sent, even though the message is slightly different in there". I have uncommented the container get instance to prevent that error scenario.

raghuveer commented 1 year ago

Is there any formula to check how many CPU cores & how much memory is required to run a predefined number of workerman workers through Adapterman.

While I thought to upgrade to PHP 8.1, errors are happening, so I have reverted to older versions and the framework works on php 7.4 correctly now. How will be the next steps to run with Adapterman @joanhey ?

Thank you

joanhey commented 1 year ago

Adapterman need PHP >= 8.0.

Workerman use less memory than php-fpm. Tested in the benchmark with stads: Workerman: 1,259 PHP-FPM: 2,341

A good start is 1 worker per CPU core, but you can use 3-4 workers x core. Only 1 worker is very fast (only 1 not per core), and if you have more than 1 app, you can choose per app, depending on the app demand.

But don't worry with an event loop, only work when necessary.

raghuveer commented 1 year ago

Hi @joanhey

Adapterman need PHP >= 8.0.

Thanks for the confirmation about minimally required PHP version. Here is the update. I tried with PHP 8.0, it is working.

https://blueprint-dev.easeapp.org/ image

Workerman use less memory than php-fpm. Tested in the benchmark with stads: Workerman: 1,259 PHP-FPM: 2,341

A good start is 1 worker per CPU core, but you can use 3-4 workers x core. Only 1 worker is very fast (only 1 not per core), and if you have more than 1 app, you can choose per app, depending on the app demand.

But don't worry with an event loop, only work when necessary.

Thanks for the info on CPU cores and number of workers required.

I have few other questions,

1) If we wanted SSL to be terminated at nginx scope, then we need to update nginx config recipe to also handle SSL or else use the default nginx recipe in the recipes folder (https://github.com/joanhey/AdapterMan/blob/master/recipes/nginx-config.md), and handle SSL in workerman scope?

2) Coming to user sessions for web applications, hope we can use the "odan/session library from Slim framework", that is currently in use, in the Easeapp framework?

Similar to Laravel & Lumen, where "Artisan" is used as reference, are you going to use something like "console.php" or some other file for the file exists check w.r.t. the EaseApp framework in https://github.com/joanhey/AdapterMan/blob/master/src/frameworks/index.php ?

Will you use the previously created "start.php" in https://github.com/joanhey/AdapterMan/blob/master/src/frameworks/ path or how?

I am really eager to start trying Adapterman and in seeing benchmark results with Adapterman and PHP-FPM too :)

Thank you

raghuveer commented 1 year ago

Hi @joanhey

I have created server.php in framework's application root. After deploying adapterman through composer ran the following,

php server.php start

It showed errors about defining few php functions as disable_functions in php.ini file.

Testing the application on port 8080 and I will update as I make progress

Thank you

joanhey commented 1 year ago

You need to use the https://github.com/joanhey/AdapterMan/blob/master/cli-php.ini (that you can change like you want) only maintain the disable_functionshttps://github.com/joanhey/AdapterMan/blob/master/cli-php.ini#L13

php -c cli-php.ini server.php start

raghuveer commented 1 year ago

Hi @joanhey

1) When I ran

Command: php server.php start

To be disabled function addition is mandated in: /etc/php80rc/php.ini

2) Alternatively when I ran

Command: php -c cli-php.ini server.php start

To be disabled function addition is mandated in: php.ini

As I have PHP 8.0 on this server and since those functions are disabled already, the php-fpm based deployment stopped working at session_status() function call in Odan/session library.

will keep you posted with the updates

Thank you

joanhey commented 1 year ago

Don't touch your /etc/php80rc/php.ini . If you disable that functions will not work correctly fpm. And remember that each SAPI (fpm, cli, ... ) use a different php.ini,

image

Only use: php -c cli-php.ini server.php start with the cli-php.ini from the repo.

The -c is to pass a path to any .ini to this php cli run.

PD: if you disable the functions in your cli .ini, it isn't a problem as 99% of the functions are not useful in CLI. But it's better use your own cli .ini, and pass it in the php call with -c.

raghuveer commented 1 year ago

will do as you suggested, thank you