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

Provide a way to operate over original swoole server instance #44

Closed
arku31 opened this issue Nov 25, 2020 · 7 comments · Fixed by #47
Closed

Provide a way to operate over original swoole server instance #44

arku31 opened this issue Nov 25, 2020 · 7 comments · Fixed by #47
Assignees
Milestone

Comments

@arku31
Copy link

arku31 commented Nov 25, 2020

I would be happy to see protected const in that class as by extending the class with private const I am forced to define it in my own and they are not different to the default one.

private const MODES = [

I am extending it to perform some code before the swoole server starts

@weierophinney
Copy link
Contributor

Can you indicate how you would be using this in your own code, exactly?

I only defined that particular constant so that we could internally ensure that the mode provided via configuration is valid, which is something that can be done easily in userland already (e.g., in_array($mode, [SWOOLE_PROCESS, SWOOLE_BASE], true).

@arku31
Copy link
Author

arku31 commented Nov 25, 2020

I would like to perform some actions with the original server instance. (in particular, inject https://github.com/upscalesoftware/swoole-newrelic).

In order to achieve this, I am extending HttpServerFactory and do

    public function __invoke(ContainerInterface $container): SwooleHttpServer
{
   $server = parent::__invoke($container);
   //somestuff with $server;
   return $server;
}

Unfortunately, it doesn't work out because of private constants, they are not available in the child class and it leads to errors :(

P.S. There are several more issues like that, I will create another issue if we would agree on this one :)

@weierophinney
Copy link
Contributor

Where are you injecting? I assume potentially an event listener? If you're using mezzio-swoole v3, you likely will want to do this via our new event system, which ties into all the workflow events of the Swoole HTTP server, and which you can do without needing to change the factory (see the events and listeners documentation).

Alternately, if you are trying to add config settings or otherwise manipulate the instance, potentially try using delegator factories.

@arku31
Copy link
Author

arku31 commented Nov 25, 2020

Unfortunately, this cannot be bootstrapped after the server has been started :(
I am not sure that I understood it correctly but seems like delegator factories is also a wrong way for me.

In the end, to achieve my goals, I only was able to put the code in the SwooleRequestHandlerRunner

Between
...$this->httpServer->on('request', [$this, 'onTaskFinish']);...
and
$this->httpServer->start();

The problem is that to use this library, I have to have server not started but ->on('request') callback already defined.

Unfortunately, this class is also not really extendable because of the private properties that force you to duplicate basically everything.

private EventDispatcherInterface $dispatcher;

UPD:
Currently, I can see two options:

  • simple: make private property protected to allow proper code extension
  • better but also a bit harder - provide a way to inject some code between callbacks definition and the actual server start

@weierophinney
Copy link
Contributor

Please read the documentation - you can add listeners to the various Swoole HTTP Server by instead adding listeners to the event classes found under Mezzio\Swoole\Event. The request handler runner has listeners that dispatch those events, which allows users to attach multiple listeners to them — which is something the Swoole HTTP server does not allow natively.

In this case, if you want it to run via the Swoole HTTP Server 'request' event, and want your listener to trigger first, you'd add configuration like this:

use Laminas\Stdlib\ArrayUtils\MergeReplaceKey;
use Mezzio\Swoole\Event;

return [
    'mezzio-swoole' => [
        'swoole-http-server' => [
            'listeners' => [
                Event\RequestEvent:class => new MergeReplaceKey([
                    YourListenerGoesHere::class, // you can also do a class instance here, but your config will no longer be cacheable
                    Event\StaticResourceRequestListener::class,
                    Event\RequestHandlerRequestListener::class,
                ]),
            ],
        ],
    ],
];

Basically, you should NEVER attach directly to the Swoole HTTP Server lifecycle events; attach listeners to the internal dispatcher instead, as it allows you to compose multiple listeners safely.

@arku31
Copy link
Author

arku31 commented Nov 26, 2020

The problem, why I cannot use Event/Listeners is the fact, that I want to measure the time, that request has taken.
There is already a package that can do it by injecting into swoole server (it takes the current callback and injects in between, so it shouldn't affect anything what is defined on the application level). Alternatively, I can imagine, it can be done with two Listeners, like "Before request" and "Response about to being send" but they doesn't exists, we only have onRequest.

I tried to achieve it by having Listener before and after RequestHandlerRequestListener but after the response is being sent, nothing is executed.

so, once again,
I can currently only see an option to extend SwooleRequestHandlerRunner and overwrite run() method what looks more or less good solution for me but I cannot (simply) do it because of private properties. Can we do them protected or agree that it's not extendable (probably make it final)

@arku31 arku31 changed the title Make constants protected in HttpServerFactory Provide a way to operate over original swoole server instance Nov 27, 2020
@weierophinney weierophinney added this to the 3.1.0 milestone Dec 2, 2020
@weierophinney weierophinney self-assigned this Dec 2, 2020
@arku31
Copy link
Author

arku31 commented Dec 2, 2020

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment