Skip to content

Commit 2f04900

Browse files
feat: add cleanupjob for jobFailed and JobException. Refactr for constants
1 parent 8b96c9b commit 2f04900

File tree

6 files changed

+44
-16
lines changed

6 files changed

+44
-16
lines changed

app/Audit/AuditContext.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919

2020
class AuditContext
2121
{
22+
23+
public const CONTAINER_KEY = 'audit.context';
24+
25+
26+
public const UI_CONTEXT_CONTAINER_KEY = 'ui.context';
27+
2228
public function __construct(
2329
public ?int $userId = null,
2430
public ?string $userEmail = null,

app/Audit/AuditEventListener.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ private function getAuditStrategy($em): ?IAuditStrategy
9898
private function buildAuditContext(): AuditContext
9999
{
100100
if (app()->runningInConsole()) {
101-
if (app()->bound('audit.context')) {
102-
$context = app('audit.context');
101+
if (app()->bound(AuditContext::CONTAINER_KEY)) {
102+
$context = app(AuditContext::CONTAINER_KEY);
103103
if ($context instanceof AuditContext) {
104104
return $context;
105105
}

app/Listeners/CleanupJobAuditContextListener.php

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,43 @@
1414
* limitations under the License.
1515
**/
1616

17+
use App\Audit\AuditContext;
1718
use Illuminate\Queue\Events\JobProcessed;
19+
use Illuminate\Queue\Events\JobFailed;
20+
use Illuminate\Queue\Events\JobExceptionOccurred;
1821
use Illuminate\Support\Facades\Log;
1922

2023
/**
2124
* Cleans up audit context after job processing to prevent context leakage between jobs
2225
*/
2326
class CleanupJobAuditContextListener
2427
{
25-
public function handle(JobProcessed $event): void
28+
public function handleJobProcessed(JobProcessed $event): void
29+
{
30+
$this->cleanup(get_class($event->job));
31+
}
32+
33+
public function handleJobFailed(JobFailed $event): void
34+
{
35+
$this->cleanup(get_class($event->job));
36+
}
37+
38+
public function handleJobExceptionOccurred(JobExceptionOccurred $event): void
39+
{
40+
$this->cleanup(get_class($event->job));
41+
}
42+
43+
private function cleanup(string $jobClass): void
2644
{
2745
if (!config('opentelemetry.enabled', false)) {
2846
return;
2947
}
3048

3149
try {
32-
if (app()->bound('audit.context')) {
33-
app()->forgetInstance('audit.context');
50+
if (app()->bound(AuditContext::CONTAINER_KEY)) {
51+
app()->forgetInstance(AuditContext::CONTAINER_KEY);
3452
Log::debug('CleanupJobAuditContextListener: audit context cleaned after job', [
35-
'job' => get_class($event->job),
53+
'job' => $jobClass,
3654
]);
3755
}
3856
} catch (\Exception $e) {

app/Listeners/RestoreJobAuditContextListener.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
class RestoreJobAuditContextListener
2222
{
23-
private const CONTAINER_BINDING_KEY = 'audit.context';
2423
private const PAYLOAD_DATA_KEY = 'data';
2524
private const PAYLOAD_CONTEXT_KEY = 'auditContext';
2625
private const LOG_CONTEXT_KEY = 'event_name';
@@ -36,7 +35,7 @@ public function handle(JobProcessing $event): void
3635
$context = $this->extractContextFromPayload($event->job->payload());
3736

3837
if ($context !== null) {
39-
app()->instance(self::CONTAINER_BINDING_KEY, $context);
38+
app()->instance(AuditContext::CONTAINER_KEY, $context);
4039
}
4140
} catch (\Exception $e) {
4241
Log::warning('Failed to restore audit context from queue job', [

app/Providers/EventServiceProvider.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,13 @@ final class EventServiceProvider extends ServiceProvider
6666
'App\Listeners\RestoreJobAuditContextListener',
6767
],
6868
\Illuminate\Queue\Events\JobProcessed::class => [
69-
'App\Listeners\CleanupJobAuditContextListener',
69+
'App\Listeners\CleanupJobAuditContextListener@handleJobProcessed',
70+
],
71+
\Illuminate\Queue\Events\JobFailed::class => [
72+
'App\Listeners\CleanupJobAuditContextListener@handleJobFailed',
73+
],
74+
\Illuminate\Queue\Events\JobExceptionOccurred::class => [
75+
'App\Listeners\CleanupJobAuditContextListener@handleJobExceptionOccurred',
7076
],
7177
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
7278
// ... other providers

tests/OpenTelemetry/Listeners/RestoreJobAuditContextListenerTest.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class RestoreJobAuditContextListenerTest extends TestCase
2727
{
2828
use CreatesApplication;
2929

30-
private const CONTAINER_BINDING_KEY = 'audit.context';
3130
private const DEFAULT_QUEUE_NAME = 'default';
3231

3332
private const TEST_USER_ID = 42;
@@ -124,8 +123,8 @@ public function testListenerRestoresContextFromPayload(): void
124123
$this->listener->handle($event);
125124

126125
// Assert: Context was bound to container
127-
$this->assertTrue(App::bound(self::CONTAINER_BINDING_KEY));
128-
$restoredContext = App::make(self::CONTAINER_BINDING_KEY);
126+
$this->assertTrue(App::bound(AuditContext::CONTAINER_KEY));
127+
$restoredContext = App::make(AuditContext::CONTAINER_KEY);
129128

130129
$this->assertInstanceOf(AuditContext::class, $restoredContext);
131130
$this->assertEquals(self::TEST_USER_ID, $restoredContext->userId);
@@ -144,7 +143,7 @@ public function testListenerDoesNotBindMissingContext(): void
144143
$this->listener->handle($event);
145144

146145
// Assert: No context binding occurs
147-
$this->assertFalse(App::bound(self::CONTAINER_BINDING_KEY));
146+
$this->assertFalse(App::bound(AuditContext::CONTAINER_KEY));
148147
}
149148

150149
public function testListenerSkipsWhenOTLPDisabled(): void
@@ -160,7 +159,7 @@ public function testListenerSkipsWhenOTLPDisabled(): void
160159
$this->listener->handle($event);
161160

162161
// Assert: No context binding even though context exists
163-
$this->assertFalse(App::bound(self::CONTAINER_BINDING_KEY));
162+
$this->assertFalse(App::bound(AuditContext::CONTAINER_KEY));
164163
}
165164

166165
public function testListenerHandlesInvalidSerializedData(): void
@@ -178,7 +177,7 @@ public function testListenerHandlesInvalidSerializedData(): void
178177
$this->listener->handle($event);
179178

180179
// Assert: Error is handled gracefully, no context bound
181-
$this->assertFalse(App::bound(self::CONTAINER_BINDING_KEY));
180+
$this->assertFalse(App::bound(AuditContext::CONTAINER_KEY));
182181
}
183182

184183
public function testListenerHandlesPayloadRetrievalException(): void
@@ -193,6 +192,6 @@ public function testListenerHandlesPayloadRetrievalException(): void
193192
$event = new JobProcessing(self::DEFAULT_QUEUE_NAME, $mockJob);
194193
$this->listener->handle($event);
195194

196-
$this->assertFalse(App::bound(self::CONTAINER_BINDING_KEY));
195+
$this->assertFalse(App::bound(AuditContext::CONTAINER_KEY));
197196
}
198197
}

0 commit comments

Comments
 (0)