Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flight work with Adapterman (Workerman) #613

Open
joanhey opened this issue Dec 16, 2024 · 12 comments
Open

Flight work with Adapterman (Workerman) #613

joanhey opened this issue Dec 16, 2024 · 12 comments

Comments

@joanhey
Copy link

joanhey commented Dec 16, 2024

Is your feature request related to a problem? Please describe.
I'm trying that this framework work with Adapterman, but only work the first URL.
I'm using the Techempower benchmark to test the frameworks with the async event driven Workerman, that it's working with similar frameworks.

Describe the solution you'd like
I want that work when we bootstrap the app only 1 time, not only for Adapterman but for any platform (swoole, php-runtime,...).
Also I can help to have better performance when it's used like a persistent app.

I write here because one user send me a issue to Adapterman: joanhey/AdapterMan#87

Describe alternatives you've considered
As work the first URL call, and only fail the next URL calls, it seems that it's not cleared the routes or other property of the framework.

Additional context
As you run also the Techempower benchmark, i'll send you the files to reproduce.

Actually

flight-workerman: Adapterman v0.6.1 OK
flight-workerman: Workerman[server.php] start in DEBUG mode
flight-workerman: ------------------------------------------- WORKERMAN --------------------------------------------
flight-workerman: Workerman version:4.2.1          PHP version:8.3.14           Event-Loop:\Workerman\Events\Event
flight-workerman: -------------------------------------------- WORKERS ---------------------------------------------
flight-workerman: proto   user            worker               listen                 processes    status           
flight-workerman: tcp     root            AdapterMan-Flight    http://0.0.0.0:8080    32            [OK]            
flight-workerman: --------------------------------------------------------------------------------------------------
flight-workerman: Press Ctrl+C to stop. Start success.
flight-workerman: Verifying framework URLs
--------------------------------------------------------------------------------
VERIFYING DB                                                                                                                                                   
--------------------------------------------------------------------------------
Accessing URL http://tfb-server:8080/db:                                                                                                                       
Accessing URL http://tfb-server:8080/db: 
--------------------------------------------------------------------------------
VERIFYING QUERY COUNT FOR http://tfb-server:8080/db                                                                                                            
--------------------------------------------------------------------------------
New configuration template added to /home/ubuntu/.siege                                                                                                        
Run siege -C to view the current settings in that file
** SIEGE 4.0.7
** Preparing 512 concurrent users for battle.
The server is now under siege...
Transactions:                    512 hits
Availability:                 100.00 %
Elapsed time:                   0.24 secs
Data transferred:               0.00 MB
Response time:                  0.15 secs
Transaction rate:            2133.33 trans/sec
Throughput:                     0.00 MB/sec
Concurrency:                  317.13
Successful transactions:         512
Failed transactions:               0
Longest transaction:            0.22
Shortest transaction:           0.02
 

   PASS for http://tfb-server:8080/db
     Executed queries: 520/512
   PASS for http://tfb-server:8080/db
     Rows read: 511/512
--------------------------------------------------------------------------------
VERIFYING JSON                                                                                                                                                 
--------------------------------------------------------------------------------
Accessing URL http://tfb-server:8080/json:                                                                                                                     
   FAIL for http://tfb-server:8080/json
     Empty response
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
{'Content-Type': 'text/html;charset=utf-8', 'Server': 'workerman', 'Date': 'Mon, 16 Dec 2024 11:54:50 GMT', 'Content-Length': '0'}
--------------------------------------------------------------------------------
VERIFYING QUERY                                                                                                                                                
--------------------------------------------------------------------------------
...

The files that I use:
index.php

<?php
require_once 'vendor/autoload.php';

error_reporting(-1);

Flight::register('db', PDO::class, [ 'mysql:host=tfb-database;port=3306;dbname=hello_world', 'benchmarkdbuser', 'benchmarkdbpass', [ \PDO::ATTR_PERSISTENT => TRUE ] ]);

// JSON test
Flight::route('/json', function() {
	Flight::json(['message' => 'Hello, World!']);
});

// Plaintext test
Flight::route('/plaintext', function() {
	Flight::response()
		->header('Content-Type', 'text/plain')
		->write('Hello, World!')
		->send();
});

// DB test
Flight::route('/db', function() {
	$id = mt_rand(1, 10000);
	$db = Flight::db();
	$stmt = $db->prepare('SELECT * FROM World WHERE id = ?');
    $stmt->execute([ $id ]);
    $world = $stmt->fetch();
    // Cast fields to int so they don't get wrapped with quotes
	$world = [
		'id' => (int) $world['id'],
		'randomNumber' => (int) $world['randomNumber']
	];
	Flight::json($world);
});

// DB multiple test
Flight::route('/db-multiple', function () {
	$queries = Flight::request()->query['queries'];
    if (is_numeric($queries)) {
        $queries = max(1, min($queries, 500));
    } else {
        $queries = 1;
    }

	$db = Flight::db();
	$stmt = $db->prepare('SELECT * FROM World WHERE id = ?');
    $worlds = [];
    for ($i = 0; $i < $queries; ++$i) {
		$random_id = mt_rand(1, 10000);
        $stmt->execute([ $random_id ]);
        $world = $stmt->fetch();
        // Cast fields to int so they don't get wrapped with quotes
        $world = [
			'id' => (int) $world['id'],
			'randomNumber' => (int) $world['randomNumber']
		];
        $worlds[] = $world;
    }
    Flight::json($worlds);
});

// DB Update Test
Flight::route('/updates', function () {
    $queries = Flight::request()->query['queries'];
    if (is_numeric($queries)) {
        $queries = max(1, min($queries, 500));
    } else {
        $queries = 1;
    }

	$db = Flight::db();

    $select_stmt = $db->prepare('SELECT id FROM World WHERE id = ?');
    $update_stmt = $db->prepare('UPDATE World SET randomNumber = ? WHERE id = ?');

    $worlds = [];
    for ($i = 0; $i < $queries; ++$i) {
        $id = mt_rand(1, 10000);
        $random_number = mt_rand(1, 10000);
        $select_stmt->execute([$id]);
        $world = $select_stmt->fetch();
		$world = [
			'id' => (int) $world['id'],
			'randomNumber' => $random_number
		];

        $update_stmt->execute([ $random_number, (int) $world['id'] ]);

        $worlds[] = $world;
    }

	Flight::json($worlds);
});

// Fortunes Test
Flight::route('/fortunes', function() {
	$db = Flight::db();
    $fortunes = $db->query('SELECT * FROM Fortune')->fetchAll(PDO::FETCH_KEY_PAIR);

    $fortunes[0] = 'Additional fortune added at request time.';
    asort($fortunes);

    Flight::render('fortunes.php', [ 'fortunes' => $fortunes ]);
});

//Flight::start() ;

// Workerman
function run()
{
    ob_start();
    Flight::start();
    header(HeaderDate::$date); // To pass the bench, nginx auto add it
    return ob_get_clean();
}

server.php

<?php
require_once __DIR__.'/vendor/autoload.php';

use Adapterman\Adapterman;
use Workerman\Lib\Timer;
use Workerman\Worker;

Adapterman::init();

$http_worker        = new Worker('http://0.0.0.0:8080');
$http_worker->count = (int) shell_exec('nproc') * 4;
$http_worker->name  = 'AdapterMan-Flight';

$http_worker->onWorkerStart = static function () {
    HeaderDate::init();
    require __DIR__.'/index.php';
};

$http_worker->onMessage = static function ($connection) {

    $connection->send(run());
};

Worker::runAll();

class HeaderDate
{
    const NAME = 'Date: ';

    /**
     * Date header
     *
     * @var string
     */
    public static $date;

    public static function init(): void
    {
        self::$date = self::NAME.gmdate('D, d M Y H:i:s').' GMT';
        Timer::add(1, static function () {
            self::$date = self::NAME.gmdate('D, d M Y H:i:s').' GMT';
        });
    }
}

flight-workerman.dockerfile

FROM ubuntu:24.04

ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get update -yqq && apt-get install -yqq software-properties-common > /dev/null
RUN LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php
RUN apt-get update -yqq > /dev/null && \
    apt-get install -yqq nginx git unzip php8.3 php8.3-common php8.3-cli php8.3-fpm php8.3-mysql  > /dev/null

COPY deploy/conf/* /etc/php/8.3/fpm/

WORKDIR /flight
COPY . .

ENV FLIGHT_DIR="/flight/src"

COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

RUN apt-get install -y php-pear php8.3-dev libevent-dev php8.3-xml > /dev/null
RUN pecl install event-3.1.4 > /dev/null && echo "extension=event.so" > /etc/php/8.3/cli/conf.d/event.ini

RUN composer require joanhey/adapterman:^0.6
RUN composer install --optimize-autoloader --classmap-authoritative --no-dev --quiet

RUN sed -i "s|Flight::start() ;|//Flight::start() ;|g" index.php

RUN chmod -R 777 /flight

EXPOSE 8080

CMD php -c deploy/conf/cli-php.ini \
    server.php start

It'll be easier for you to find the problem. As the bench don't report any error, only empty response.
I'm at your disposition for any extra info or help.

Thank you.

@n0nag0n
Copy link
Collaborator

n0nag0n commented Dec 17, 2024

Hey @joanhey long time no see :)

So one thing that may be worth noting is I'm pretty sure that the techempower benchmarks are using Flight v2 and the framework is now at Flight v3. Have you tried with v3 of the framework with any luck?

@joanhey
Copy link
Author

joanhey commented Dec 18, 2024

Hi @n0nag0n

I'll update the benchmark to use Flight v3, I only needed to change the plaintext code.
And later we'll compare the results from both versions.

Flight v3 with Adapterman:

flight-workerman: Adapterman v0.6.1 OK
flight-workerman: Workerman[server.php] start in DEBUG mode
flight-workerman: ------------------------------------------- WORKERMAN --------------------------------------------
flight-workerman: Workerman version:4.2.1          PHP version:8.3.14           Event-Loop:\Workerman\Events\Event
flight-workerman: -------------------------------------------- WORKERS ---------------------------------------------
flight-workerman: proto   user            worker               listen                 processes    status           
flight-workerman: tcp     root            AdapterMan-Flight    http://0.0.0.0:8080    32            [OK]            
flight-workerman: --------------------------------------------------------------------------------------------------
flight-workerman: Press Ctrl+C to stop. Start success.
flight-workerman: Verifying framework URLs
--------------------------------------------------------------------------------
VERIFYING DB                                                                                                                                                   
--------------------------------------------------------------------------------
Accessing URL http://tfb-server:8080/db:                                                                                                                       
   FAIL for http://tfb-server:8080/db
     Empty response
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
{'Content-Type': 'text/html;charset=utf-8', 'Server': 'workerman', 'Date': 'Wed, 18 Dec 2024 10:55:47 GMT', 'Content-Length': '0'}
--------------------------------------------------------------------------------
VERIFYING JSON                                                                                                                                                 
--------------------------------------------------------------------------------
Accessing URL http://tfb-server:8080/json:                                                                                                                     
Accessing URL http://tfb-server:8080/json: 
   PASS for http://tfb-server:8080/json
--------------------------------------------------------------------------------
VERIFYING QUERY                                                                                                                                                
--------------------------------------------------------------------------------
Accessing URL http://tfb-server:8080/db-multiple?queries=2:                                                                                                    
Accessing URL http://tfb-server:8080/db-multiple?queries=2: 
Accessing URL http://tfb-server:8080/db-multiple?queries=0: 
Accessing URL http://tfb-server:8080/db-multiple?queries=0: 
Accessing URL http://tfb-server:8080/db-multiple?queries=foo: 
Accessing URL http://tfb-server:8080/db-multiple?queries=501: 
Accessing URL http://tfb-server:8080/db-multiple?queries=501: 
Accessing URL http://tfb-server:8080/db-multiple?queries=: 
Accessing URL http://tfb-server:8080/db-multiple?queries=: 
--------------------------------------------------------------------------------
VERIFYING QUERY COUNT FOR http://tfb-server:8080/db-multiple?queries=20                                                                                        
--------------------------------------------------------------------------------
New configuration template added to /home/ubuntu/.siege                                                                                                        
Run siege -C to view the current settings in that file
** SIEGE 4.0.7
** Preparing 512 concurrent users for battle.
The server is now under siege...
Transactions:                    512 hits
Availability:                 100.00 %
Elapsed time:                   0.40 secs
Data transferred:               0.02 MB
Response time:                  0.22 secs
Transaction rate:            1280.00 trans/sec
Throughput:                     0.04 MB/sec
Concurrency:                  287.55
Successful transactions:         512
Failed transactions:               0
Longest transaction:            0.37
Shortest transaction:           0.04
 

   FAIL for http://tfb-server:8080/db-multiple?queries=2
     Empty response
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/db-multiple?queries=2
     Invalid Content-Type header, found "text/html;charset=utf-8", did not match "^application/json(; ?charset=(UTF|utf)-8)?$".
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/db-multiple?queries=0
     Empty response
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/db-multiple?queries=0
     Invalid Content-Type header, found "text/html;charset=utf-8", did not match "^application/json(; ?charset=(UTF|utf)-8)?$".
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/db-multiple?queries=foo
     Empty response given for stringy `queries` parameter foo
     Suggestion: modify your /queries route to handle this case (this will be a failure in future rounds, please fix)
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/db-multiple?queries=501
     Empty response
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/db-multiple?queries=501
     Invalid Content-Type header, found "text/html;charset=utf-8", did not match "^application/json(; ?charset=(UTF|utf)-8)?$".
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/db-multiple?queries=20
     Only 7107 executed queries in the database out of roughly 10240 expected.
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/db-multiple?queries=20
     Only 7000 rows read in the database out of roughly 10240 expected.
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
{'Content-Type': 'text/html;charset=utf-8', 'Server': 'workerman', 'Date': 'Wed, 18 Dec 2024 10:56:03 GMT', 'Content-Length': '0'}
--------------------------------------------------------------------------------
VERIFYING UPDATE                                                                                                                                               
--------------------------------------------------------------------------------
Accessing URL http://tfb-server:8080/updates?queries=2:                                                                                                        
Accessing URL http://tfb-server:8080/updates?queries=2: 
Accessing URL http://tfb-server:8080/updates?queries=0: 
Accessing URL http://tfb-server:8080/updates?queries=0: 
Accessing URL http://tfb-server:8080/updates?queries=foo: 
Accessing URL http://tfb-server:8080/updates?queries=501: 
Accessing URL http://tfb-server:8080/updates?queries=501: 
Accessing URL http://tfb-server:8080/updates?queries=: 
--------------------------------------------------------------------------------
VERIFYING QUERY COUNT FOR http://tfb-server:8080/updates?queries=20                                                                                            
--------------------------------------------------------------------------------
** SIEGE 4.0.7                                                                                                                                                 
** Preparing 512 concurrent users for battle.
The server is now under siege...
Transactions:                    512 hits
Availability:                 100.00 %
Elapsed time:                   0.30 secs
Data transferred:               0.00 MB
Response time:                  0.17 secs
Transaction rate:            1706.67 trans/sec
Throughput:                     0.00 MB/sec
Concurrency:                  287.33
Successful transactions:         512
Failed transactions:               0
Longest transaction:            0.28
Shortest transaction:           0.00
 

   FAIL for http://tfb-server:8080/updates?queries=2
     Empty response
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/updates?queries=2
     Invalid Content-Type header, found "text/html;charset=utf-8", did not match "^application/json(; ?charset=(UTF|utf)-8)?$".
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/updates?queries=0
     Empty response
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/updates?queries=0
     Invalid Content-Type header, found "text/html;charset=utf-8", did not match "^application/json(; ?charset=(UTF|utf)-8)?$".
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/updates?queries=foo
     Empty response given for stringy `queries` parameter foo
     Suggestion: modify your /queries route to handle this case (this will be a failure in future rounds, please fix)
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/updates?queries=501
     Empty response
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/updates?queries=501
     Invalid Content-Type header, found "text/html;charset=utf-8", did not match "^application/json(; ?charset=(UTF|utf)-8)?$".
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/updates?queries=501
     No items were updated in the database.
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/updates?queries=
     Empty response given for stringy `queries` parameter 
     Suggestion: modify your /queries route to handle this case (this will be a failure in future rounds, please fix)
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/updates?queries=20
     Only 5271 executed queries in the database out of roughly 20480 expected.
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/updates?queries=20
     Only 5133 rows read in the database out of roughly 10240 expected.
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
   FAIL for http://tfb-server:8080/updates?queries=20
     Only 59 rows updated in the database out of roughly 10240 expected.
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
{'Content-Type': 'text/html;charset=utf-8', 'Server': 'workerman', 'Date': 'Wed, 18 Dec 2024 10:56:12 GMT', 'Content-Length': '0'}
--------------------------------------------------------------------------------
VERIFYING FORTUNE                                                                                                                                              
--------------------------------------------------------------------------------
Accessing URL http://tfb-server:8080/fortunes:                                                                                                                 
   FAIL for http://tfb-server:8080/fortunes
     Empty response
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
{'Content-Type': 'text/html;charset=utf-8', 'Server': 'workerman', 'Date': 'Wed, 18 Dec 2024 10:56:13 GMT', 'Content-Length': '0'}
--------------------------------------------------------------------------------
VERIFYING PLAINTEXT                                                                                                                                            
--------------------------------------------------------------------------------
Accessing URL http://tfb-server:8080/plaintext:                                                                                                                
   FAIL for http://tfb-server:8080/plaintext
     Empty response
     See https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview#specific-test-requirements
{'Content-Type': 'text/html;charset=utf-8', 'Server': 'workerman', 'Date': 'Wed, 18 Dec 2024 10:56:13 GMT', 'Content-Length': '0'}
Auditing /FrameworkBenchmarks/frameworks/PHP/flight:
No problems to report
wrk: Build time: 1s
techempower/mysql:latest: Build time: 1s
flight-workerman: Build time: 1m 57s
flight-workerman: Time starting database: 13s
flight-workerman: Time until accepting requests: 0s
flight-workerman: Verify time: 25s
flight-workerman: Failed verify!
flight-workerman: Total test time: 2m 37s
tfb: Total time building so far: 1m 59s
tfb: Total time verifying so far: 25s
tfb: Total execution time so far: 2m 40s
================================================================================
Verification Summary                                                                                                                                           
--------------------------------------------------------------------------------
| flight-workerman                                                                                                                                             
|       db            : FAIL                                                                                                                                   
|       json          : PASS                                                                                                                                   
|       query         : FAIL                                                                                                                                   
|       update        : FAIL                                                                                                                                   
|       fortune       : FAIL                                                                                                                                   
|       plaintext     : FAIL                                                                                                                                   
================================================================================ 

It's very similar to v2.
As don't show any error, I tried the bench in debug mode with manual calls from the browser, but also no errors.
Only send a 200 OK empty, after the first call that is OK. Also it don't send the application/json header

image

@joanhey
Copy link
Author

joanhey commented Dec 18, 2024

The good think of use Request - Response is that it can be used with only one initial bootstrap and have faster runtime as persistent app.
It seems that in some step is not cleared the routes or request. The router need to create a new Request.

PD: if the first url don't exist, return a 404, but later all the urls return a 404

@n0nag0n
Copy link
Collaborator

n0nag0n commented Dec 19, 2024

Ahh ok, I think I know what's going on. Flight really was built for only "regular" PHP event handling. In another discussion I did get it to work with Swoole with some customizations and some of these customizations might make sense to you. I've never worked with workerman, but I assume the same rule applies to Workerman as it does to Swoole.

#519 (comment)

Basically, you need to handle the headers by hand and deregister/register the request and response objects as they are static in the framework.

I have another project for the flightphp org to get async working with swoole and I have it all working, but there is a memory leak somewhere and eventually the swoole server has to be restarted as it runs out of memory. I'm not sure where the leak is as it's basically impossible to track variable sizes in swoole servers without xdebug or any type of friendly debug.

Hopefully this points you in a direction. I know you want Adapterman out of the box, and maybe it still can, but it looks like it may need a little help.

@joanhey
Copy link
Author

joanhey commented Dec 19, 2024

You don't need to touch any app code with Adapterman.
But for every new request the router need to create a new Request object, nothing else !!

PD: actually it isn't so because the framework repeat the requests, even when change.

@joanhey
Copy link
Author

joanhey commented Dec 19, 2024

And please, later try with swoole, frankenphp, ... all are slow compared with Adapterman !!

@joanhey
Copy link
Author

joanhey commented Dec 19, 2024

Remember to separate the code that is configuration, and never change, with a new Request that create the router.

@abda11ah
Copy link

I found an interesting information when i asked Perplexity AI, here is its answer :

In analyzing the FlightPHP core source code and its potential issues with FrankenPHP's worker mode, several areas could lead to buggy behavior, especially concerning shared data across requests:
Potential Issues in FlightPHP with Worker Mode
Static State Management:
FlightPHP relies on static methods and properties, such as Flight::set() and Flight::get(), which can lead to shared state across requests if not properly reset between requests1. In a worker mode, where the application remains in memory, this could result in data from one request being inadvertently shared with another.
Request/Response Objects:
FlightPHP uses static methods to manage request and response objects (Flight::request() and Flight::response()). If these objects are not re-initialized for each request, data from previous requests might persist, leading to incorrect responses or data leakage between users1.
Session Handling:
If sessions are not managed correctly, especially when using a shared in-memory approach, session data might be improperly shared or corrupted across different user sessions.
Mitigation Strategies
Reset Static Data: Ensure that any static data or state is reset at the beginning of each request. This can be done by explicitly clearing or reinitializing stateful components.
Isolate Request/Response Lifecycle: Recreate request and response objects for each new request to avoid data leakage.
Use Middleware for Cleanup: Implement middleware that resets or cleans up any global or static state after each request is processed.
By addressing these areas, you can mitigate the risk of shared data issues when using FlightPHP with FrankenPHP's worker mode.

@joanhey
Copy link
Author

joanhey commented Dec 20, 2024

Some of that problems don't affect in Adapterman.

Adapterman use forks, and each is independent. In reality we use the same PHP superglobals ($_GET, $_POST, ...) without problems. But still the framework need to recreate a new Request in each request.

Swoole and FrankenPHP (Worker mode) use threads, and all global variables and static properties are shared. So they need a more careful code to encapsulate the Resquest - Response objects to avoid conflicts.

@joanhey
Copy link
Author

joanhey commented Dec 21, 2024

The only change is here: https://github.com/flightphp/core/blob/master/flight/Engine.php#L475-L481

public function _start(): void
    {
        $dispatched = false;
        $self = $this;
        $request = $this->request();
        $response = $this->response();
        $router = $this->router();

The $request and $response need a newInstance().

The framework will be as fast as before, because the first time create a new instance, but subsequent calls return the same instanced Request and Response.

PD: perhaps with only a new instance for $request will be enough.
I'll try it in local.

@joanhey
Copy link
Author

joanhey commented Dec 21, 2024

Another problem with persistent applications is to avoid exit(), as this will close the master CLI app.
It's better to use an ExitException().

@n0nag0n
Copy link
Collaborator

n0nag0n commented Dec 22, 2024

Sorry I haven't gotten to this til now. I appreciate your help with figuring this out! I have seen the same problems and I would need to alter the core, without breaking past functionality to get it working correctly. I'll pin this in the todo list to see if I can get it working sometime soon cause I would be interested to get this working with some type of async handler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants