Skip to content

Commit

Permalink
feat(service-reset): add possibility to mark some services to be rese…
Browse files Browse the repository at this point in the history
…t on each request
  • Loading branch information
Rastusik committed Feb 6, 2023
1 parent 522e5ba commit 3661ff1
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 7 deletions.
5 changes: 4 additions & 1 deletion docs/configuration-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,16 @@ services:
some_stateful_service:
class: My\Stateful\ServiceClass
tags: [{ name: swoole_bundle.stateful_service, resetter: my_custom_resetter}]
tags: [{ name: swoole_bundle.stateful_service, resetter: my_custom_resetter, reset_on_each_request: true}]
some_unmanaged_factory:
class: My\Unmanaged\FactoryClass2
tags: [{ name: swoole_bundle.unmanaged_factory, resetter: my_custom_resetter}]
```

By default, each resetted service is being reset on first usage during request. But there are some services,
that need to be reset on each request. To activate this, use the `reset_on_each_request` attribute.

### Stability checkers

Stability checkers are services services which make run-time checks for paired stateful services. They check,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
final class StatefulServiceTag
{
/**
* @var array{limit?: int, resetter?: string}
* @var array{limit?: int, resetter?: string, reset_on_each_request?: bool}
*/
private array $tag;

/**
* @param array{limit?: int, resetter?: string} $tag
* @param array{limit?: int, resetter?: string, reset_on_each_request?: bool} $tag
*/
public function __construct(array $tag)
{
Expand All @@ -28,4 +28,9 @@ public function getResetter(): ?string
{
return $this->tag['resetter'] ?? null;
}

public function getResetOnEachRequest(): ?bool
{
return $this->tag['reset_on_each_request'] ?? null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use K911\Swoole\Bridge\Symfony\Bundle\DependencyInjection\CompilerPass\StatefulServices\CompileProcessor;
use K911\Swoole\Bridge\Symfony\Bundle\DependencyInjection\CompilerPass\StatefulServices\FinalClassesProcessor;
use K911\Swoole\Bridge\Symfony\Bundle\DependencyInjection\CompilerPass\StatefulServices\Proxifier;
use K911\Swoole\Bridge\Symfony\Bundle\DependencyInjection\CompilerPass\StatefulServices\Tags;
use K911\Swoole\Bridge\Symfony\Bundle\DependencyInjection\CompilerPass\StatefulServices\UnmanagedFactoryProxifier;
use K911\Swoole\Bridge\Symfony\Bundle\DependencyInjection\ContainerConstants;
use K911\Swoole\Bridge\Symfony\Container\BlockingContainer;
Expand Down Expand Up @@ -66,7 +67,7 @@ public function process(ContainerBuilder $container): void
$resetters = $this->getServiceResetters($container);
$this->proxifyKnownStatefulServices($container, $proxifier, $resetters);
$this->proxifyUnmanagedFactories($container, $finalProcessor, $resetters);
$this->cancelServiceResetting($container);
$this->reduceServiceResetters($container);
$this->configureServicePoolContainer($container, $proxifier);
}

Expand Down Expand Up @@ -225,13 +226,36 @@ private function getServiceResetters(ContainerBuilder $container): array
return array_map(fn (array $r): string => $r[0], $resetters);
}

private function cancelServiceResetting(ContainerBuilder $container): void
private function reduceServiceResetters(ContainerBuilder $container): void
{
$resetterDef = $container->findDefinition('services_resetter');
/** @var ServiceLocatorArgument $resetters */
$resetters = $resetterDef->getArgument(0);
$resetters->setValues([]);
$resetterDef->setArgument(1, []);
$resetMethods = $resetterDef->getArgument(1);
$newResetters = [];
$newResetMethods = [];

foreach ($resetters->getValues() as $serviceId => $value) {
$valueDef = $container->findDefinition((string) $value);
/** @var class-string $classString */
$classString = $valueDef->getClass();
$tags = new Tags($classString, $valueDef->getTags());
$tag = $tags->findStatefulServiceTag();

if (null === $tag) {
continue;
}

if (!$tag->getResetOnEachRequest()) {
continue;
}

$newResetters[$serviceId] = $value;
$newResetMethods[$serviceId] = $resetMethods[$serviceId];
}

$resetters->setValues($newResetters);
$resetterDef->setArgument(1, $newResetMethods);
}

private function configureServicePoolContainer(ContainerBuilder $container, Proxifier $proxifier): void
Expand Down
2 changes: 2 additions & 0 deletions tests/Feature/SwooleServerCoroutinesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public function testCoroutinesWithDebugOn(): void
$this->assertStringContainsString('Service was proxified.', $response['body']);
$this->assertStringContainsString('Service2 was proxified.', $response['body']);
$this->assertStringContainsString('Service2 limit is 10.', $response['body']);
$this->assertStringContainsString('Always reset works.', $response['body']);
$this->assertStringContainsString('TmpRepo was proxified.', $response['body']);
$this->assertStringContainsString('TmpRepo limit is 15.', $response['body']);
$this->assertStringContainsString('Connection limit is 12.', $response['body']);
Expand Down Expand Up @@ -136,6 +137,7 @@ public function testCoroutinesWithDebugOff(): void
$this->assertStringContainsString('Service was proxified.', $response['body']);
$this->assertStringContainsString('Service2 was proxified.', $response['body']);
$this->assertStringContainsString('Service2 limit is 10.', $response['body']);
$this->assertStringContainsString('Always reset works.', $response['body']);
$this->assertStringContainsString('TmpRepo was proxified.', $response['body']);
$this->assertStringContainsString('TmpRepo limit is 15.', $response['body']);
$this->assertStringContainsString('Connection limit is 12.', $response['body']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public function index()
$limitProperty = $rc->getProperty('instancesLimit');
$limitProperty->setAccessible(true);
$limit = $limitProperty->getValue($servicePool);
$alwaysResetWorks = $this->shouldBeProxified->wasDummyReset();

$rc2 = new \ReflectionClass(DefaultDummyService::class);
$tmpRepoProperty = $rc2->getProperty('tmpRepository');
Expand All @@ -97,6 +98,7 @@ public function index()
"<html><body>Sleep was fine. Count was {$counter}. Check was {$check}. "
."Checks: {$checks}. "
."Service {$isProxified} proxified. Service2 {$isProxified2} proxified. "
.'Always reset '.($alwaysResetWorks ? 'works' : 'did not work').'. '
."Service2 limit is {$limit}. TmpRepo {$isProxified3} proxified. "
."TmpRepo limit is {$limit2}. "
."Connection limit is {$connlimit}.</body></html>"
Expand Down
22 changes: 22 additions & 0 deletions tests/Fixtures/Symfony/TestBundle/Service/AlwaysReset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace K911\Swoole\Tests\Fixtures\Symfony\TestBundle\Service;

use Symfony\Contracts\Service\ResetInterface;

final class AlwaysReset implements ResetInterface
{
private bool $wasReset = false;

public function reset(): void
{
$this->wasReset = true;
}

public function getWasReset(): bool
{
return $this->wasReset;
}
}
11 changes: 11 additions & 0 deletions tests/Fixtures/Symfony/TestBundle/Service/ShouldBeProxified.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,15 @@

final class ShouldBeProxified
{
private AlwaysReset $dummy;

public function __construct(AlwaysReset $dummy)
{
$this->dummy = $dummy;
}

public function wasDummyReset(): bool
{
return $this->dummy->getWasReset();
}
}
4 changes: 4 additions & 0 deletions tests/Fixtures/Symfony/app/config/coroutines/swoole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,7 @@ services:
K911\Swoole\Tests\Fixtures\Symfony\TestBundle\MessageHandler\RunDummyHandler:
tags:
- messenger.message_handler

K911\Swoole\Tests\Fixtures\Symfony\TestBundle\Service\AlwaysReset:
tags:
- { name: 'swoole_bundle.stateful_service', reset_on_each_request: true }

0 comments on commit 3661ff1

Please sign in to comment.