Skip to content

Commit 6e2093d

Browse files
Baspaclaude
andauthored
perf: queue user login/logout recording to avoid slow DNS lookups (#83)
The gethostbyaddr() call was blocking the login/logout response, causing delays of 1-30+ seconds depending on network conditions. Now the recording is dispatched to a queue job, so the user gets an instant response while the DNS lookup happens in the background. Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent d1fd8fe commit 6e2093d

3 files changed

Lines changed: 73 additions & 28 deletions

File tree

src/Jobs/RecordUserLogin.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace Backstage\Laravel\Users\Jobs;
4+
5+
use Illuminate\Contracts\Queue\ShouldQueue;
6+
use Illuminate\Foundation\Queue\Queueable;
7+
8+
class RecordUserLogin implements ShouldQueue
9+
{
10+
use Queueable;
11+
12+
/**
13+
* @param array<string, mixed>|null $inputs
14+
*/
15+
public function __construct(
16+
public int $userId,
17+
public string $type,
18+
public ?string $url,
19+
public ?string $referrer,
20+
public ?array $inputs,
21+
public ?string $userAgent,
22+
public ?string $ipAddress,
23+
) {}
24+
25+
public function handle(): void
26+
{
27+
$userModel = config('users.eloquent.user.model');
28+
$user = $userModel::find($this->userId);
29+
30+
if (! $user) {
31+
return;
32+
}
33+
34+
$user->logins()->create([
35+
'user_id' => $this->userId,
36+
'type' => $this->type,
37+
'url' => $this->url,
38+
'referrer' => $this->referrer,
39+
'inputs' => $this->inputs ? json_encode($this->inputs) : null,
40+
'user_agent' => $this->userAgent,
41+
'ip_address' => $this->ipAddress,
42+
'hostname' => $this->ipAddress ? gethostbyaddr($this->ipAddress) : null,
43+
]);
44+
}
45+
}

src/Listeners/Auth/HandleUserLogin.php

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,26 @@
22

33
namespace Backstage\Laravel\Users\Listeners\Auth;
44

5+
use Backstage\Laravel\Users\Jobs\RecordUserLogin;
56
use Illuminate\Auth\Events\Login;
67

78
class HandleUserLogin
89
{
9-
public function handle(Login $event)
10+
public function handle(Login $event): void
1011
{
11-
/**
12-
* @var \Backstage\Laravel\Users\Eloquent\Models\User $user
13-
*/
12+
/** @var \Backstage\Laravel\Users\Eloquent\Models\User $user */
1413
$user = $event->user;
1514

1615
$inputs = request()->except('_method', '_token', 'password');
1716

18-
$user->logins()->create([
19-
'user_id' => $user->id,
20-
'type' => 'login',
21-
'url' => request()->url(),
22-
'referrer' => request()->server('HTTP_REFERER'),
23-
'inputs' => count($inputs) ? json_encode($inputs) : null,
24-
'user_agent' => request()->server('HTTP_USER_AGENT'),
25-
'ip_address' => request()->ip(),
26-
'hostname' => gethostbyaddr(request()->ip()),
27-
]);
17+
RecordUserLogin::dispatch(
18+
userId: $user->id,
19+
type: 'login',
20+
url: request()->url(),
21+
referrer: request()->server('HTTP_REFERER'),
22+
inputs: count($inputs) ? $inputs : null,
23+
userAgent: request()->server('HTTP_USER_AGENT'),
24+
ipAddress: request()->ip(),
25+
);
2826
}
2927
}

src/Listeners/Auth/HandleUserLogout.php

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,30 @@
22

33
namespace Backstage\Laravel\Users\Listeners\Auth;
44

5+
use Backstage\Laravel\Users\Jobs\RecordUserLogin;
56
use Illuminate\Auth\Events\Logout;
67

78
class HandleUserLogout
89
{
9-
public function handle(Logout $event)
10+
public function handle(Logout $event): void
1011
{
11-
/**
12-
* @var \Backstage\Laravel\Users\Eloquent\Models\User $user
13-
*/
12+
/** @var \Backstage\Laravel\Users\Eloquent\Models\User|null $user */
1413
$user = $event->user;
1514

15+
if (! $user) {
16+
return;
17+
}
18+
1619
$inputs = request()->except('_method', '_token', 'password');
1720

18-
$user->logins()->create([
19-
'user_id' => $user->id,
20-
'type' => 'logout',
21-
'url' => request()->url(),
22-
'referrer' => request()->server('HTTP_REFERER'),
23-
'inputs' => count($inputs) ? json_encode($inputs) : null,
24-
'user_agent' => request()->server('HTTP_USER_AGENT'),
25-
'ip_address' => request()->ip(),
26-
'hostname' => gethostbyaddr(request()->ip()),
27-
]);
21+
RecordUserLogin::dispatch(
22+
userId: $user->id,
23+
type: 'logout',
24+
url: request()->url(),
25+
referrer: request()->server('HTTP_REFERER'),
26+
inputs: count($inputs) ? $inputs : null,
27+
userAgent: request()->server('HTTP_USER_AGENT'),
28+
ipAddress: request()->ip(),
29+
);
2830
}
2931
}

0 commit comments

Comments
 (0)