Open razonyang opened 2 years ago
Why wouldn't you use setLocale()
?
Why wouldn't you use
setLocale()
?
Sorry, I didn't notice that, is this method can be used in RoadRunner and Swoole safely?
Why wouldn't you use
setLocale()
?Sorry, I didn't notice that, is this method can be used in RoadRunner and Swoole safely?
I haven't checked it, but seems it may occur problems. @yiisoft/yii3 has anyone checked this case?
Hi @xepozz, I just tested it in RR and Swoole, the RR seems fine with the setLocale
, but Swoole does not.
I guess requests are blocking in RR single worker, the next request won't be handled until the current request was done. And Swoole Coroutine won't blocking requests, if the current request is suspend, other requests will be handled. The DI resetter isn't useful in this case.
I wrote a simple test case as the following.
The response will be affected by other requests.
<?php
// Middleware
class TranslatorMiddleware implements MiddlewareInterface
{
public function __construct(
private TranslatorInterface $translator,
) {
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$this->translator->setLocale($request->getQueryParams()['locale']);
sleep(5);
return $handler->handle($request);
}
}
<?php
// Controller
class InfoController
{
public const TITLE = 'New Tab API';
public const VERSION = '1.0.0';
public function index(DataResponseFactoryInterface $responseFactory, TranslatorInterface $translator): ResponseInterface
{
return $responseFactory->createResponse([
'title' => self::TITLE,
'version' => self::VERSION,
't' => $translator->translate('home'),
]);
}
}
As the image shown, the Application Runner does invoke the StateResetter::reset
method to reset the locale per request.
<?php
private function afterRespond(
Application $application,
ContainerInterface $container,
?ResponseInterface $response,
): void {
$application->afterEmit($response);
/** @psalm-suppress MixedMethodCall */
$container
->get(StateResetter::class)
->reset(); // We should reset the state of such services every request.
var_dump('reset service state');
gc_collect_cycles();
}
I'm not sure am I test it in a right way.
The HTTP server is running with Swoole 5 Coroutine
Hi, I forked the yiisoft/app-api and created the swoole branch for checking this case.
Changes can be found at https://github.com/razonyang/yii-app-demo/commit/13300e05cafe016785e439c92ef81f36308c7e76 and https://github.com/razonyang/yii-app-demo/commit/d1e9ccb58e56b18dfef27cb4b7e1a53533429b7e Swoole runnner adapter https://github.com/razonyang/yii-runner-swoole
Steps for testing:
$ git clone -b swoole git@github.com:razonyang/yii-app-demo.git
$ cd yii-app-demo
$ docker-compose up --build -d php
$ docker-compose exec php bash
root@***:/app# composer install
root@***:/app# exit
$ docker-compose up --build -d swoole
And then make some concurrent requests.
$ curl "http://localhost:9501?locale=zh-CN"
$ curl "http://localhost:9501?locale=en-US"
I think it would be better if we are able to use withLocale
instead of setLocale
, and then inject the runtime translator into Rule Handlers.
Hi, I would like to format the error message with runtime Yii translator, a middleware that store the translator instance into request
attributes
, according to theAccept-Language
header or URL query parameters.I extend the RequestModel class like this:
Is there any way to hack the runtime formatter into rules? The formatter is belongs to RuleHandler, not Rule, so I could not do it in the
getRules
function.