Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Translator memory leak fixed #70

Merged
merged 1 commit into from
Nov 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog][keepachangelog] and this project adheres to [Semantic Versioning][semver].

## UNRELEASED

### Added

- Listener `FlushTranslatorCacheListener` for memory leak fixing on `Translator` implementation [#69]

[#69]:https://github.com/spiral/roadrunner-laravel/pull/69

## v5.4.0

### Added
Expand Down
1 change: 1 addition & 0 deletions src/Defaults.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public static function afterLoopIteration(): array
Listeners\FlushDumperStackListener::class,
Listeners\FlushLogContextListener::class,
Listeners\FlushArrayCacheListener::class,
Listeners\FlushTranslatorCacheListener::class,
Listeners\ResetDatabaseRecordModificationStateListener::class,
Listeners\FlushDatabaseQueryLogListener::class,
Listeners\ClearInstancesListener::class,
Expand Down
46 changes: 46 additions & 0 deletions src/Listeners/FlushTranslatorCacheListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Spiral\RoadRunnerLaravel\Listeners;

use Illuminate\Translation\Translator;
use Illuminate\Support\NamespacedItemResolver;
use Spiral\RoadRunnerLaravel\Events\Contracts\WithApplication;

/**
* @link https://github.com/laravel/octane/pull/416/files
*/
class FlushTranslatorCacheListener implements ListenerInterface
{
use Traits\InvokerTrait;

/**
* {@inheritdoc}
*/
public function handle($event): void
{
if ($event instanceof WithApplication) {
$app = $event->application();

if (! $app->resolved($translator_abstract = 'translator')) {
return;
}

/** @var Translator $translator */
$translator = $app->make($translator_abstract);

if ($translator instanceof NamespacedItemResolver) {
/**
* Method `flushParsedKeys` for the Translator available since Laravel v8.70.0.
*
* @link https://git.io/JXd0v Source code (v8.70.0)
* @see Translator::flushParsedKeys()
*/
if (! $this->invokeMethod($translator, 'flushParsedKeys')) {
$this->setProperty($translator, 'parsed', []);
}
}
}
}
}
48 changes: 48 additions & 0 deletions tests/Unit/Listeners/FlushTranslatorCacheListenerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace Spiral\RoadRunnerLaravel\Tests\Unit\Listeners;

use Mockery as m;
use Illuminate\Translation\Translator;
use Spiral\RoadRunnerLaravel\Events\Contracts\WithApplication;
use Spiral\RoadRunnerLaravel\Listeners\FlushTranslatorCacheListener;

/**
* @covers \Spiral\RoadRunnerLaravel\Listeners\FlushTranslatorCacheListener
*/
class FlushTranslatorCacheListenerTest extends AbstractListenerTestCase
{
/**
* {@inheritdoc}
*/
public function testHandle(): void
{
/** @var Translator $translator */
$translator = $this->app->make('translator');

$translator->setParsedKey('foo::bar.baz', ['foo', 'bar', 'baz']);

/** @var m\MockInterface|WithApplication $event_mock */
$event_mock = m::mock(WithApplication::class)
->makePartial()
->expects('application')
->andReturn($this->app)
->getMock();

$this->assertNotEmpty($this->getProperty($translator, 'parsed'));

$this->listenerFactory()->handle($event_mock);

$this->assertEmpty($this->getProperty($translator, 'parsed'));
}

/**
* @return FlushTranslatorCacheListener
*/
protected function listenerFactory(): FlushTranslatorCacheListener
{
return new FlushTranslatorCacheListener();
}
}