Skip to content

Commit

Permalink
refactor: process authorized transactions as job (#375)
Browse files Browse the repository at this point in the history
  • Loading branch information
andreiio authored Jun 17, 2024
1 parent 55251dd commit d77145c
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 67 deletions.
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ ENV APP_ENV production
ENV APP_DEBUG false
ENV LOG_CHANNEL stderr

# The number of jobs to process before stopping
ENV WORKER_MAX_JOBS 5

# Number of seconds to sleep when no job is available
ENV WORKER_SLEEP 10

# Number of seconds to rest between jobs
ENV WORKER_REST 1

# The number of seconds a child process can run
ENV WORKER_TIMEOUT 600

# Number of times to attempt a job before logging it failed
ENV WORKER_TRIES 1

ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME 0

EXPOSE 80
63 changes: 0 additions & 63 deletions app/Console/Commands/ProcessEuPlatescTransactions.php

This file was deleted.

4 changes: 2 additions & 2 deletions app/Console/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace App\Console;

use App\Console\Commands\ProcessEuPlatescTransactions;
use App\Jobs\ProcessAuthorizedTransactionsJob;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

Expand All @@ -18,7 +18,7 @@ protected function schedule(Schedule $schedule): void
$schedule->command('model:prune')
->daily();

$schedule->command(ProcessEuPlatescTransactions::class)
$schedule->job(ProcessAuthorizedTransactionsJob::class)
->everyFourHours();
}

Expand Down
58 changes: 58 additions & 0 deletions app/Jobs/CaptureAuthorizedDonationJob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace App\Jobs;

use App\Enums\EuPlatescStatus;
use App\Models\Donation;
use App\Services\EuPlatescService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class CaptureAuthorizedDonationJob implements ShouldQueue, ShouldBeUnique
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;

public Donation $donation;

public EuPlatescService $service;

/**
* The number of seconds after which the job's unique lock will be released.
*
* @var int
*/
public $uniqueFor = 3600;

/**
* Get the unique ID for the job.
*/
public function uniqueId(): int
{
return $this->donation->id;
}

public function __construct(Donation $donation, EuPlatescService $service)
{
$this->donation = $donation;
$this->service = $service;
}

public function handle(): void
{
if ($this->service->recipeTransaction($this->donation)) {
$this->donation->update([
'status' => EuPlatescStatus::CHARGED,
'status_updated_at' => now(),
]);
}
}
}
44 changes: 44 additions & 0 deletions app/Jobs/ProcessAuthorizedTransactionsJob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace App\Jobs;

use App\Models\Donation;
use App\Models\Organization;
use App\Services\EuPlatescService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Database\Query\Builder;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class ProcessAuthorizedTransactionsJob implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;

/**
* Execute the job.
*/
public function handle(): void
{
Organization::query()
->whereHasEuPlatesc()
->withWhereHas('donations', function (Builder $query) {
return $query
->whereAuthorized()
->whereNotNull('ep_id');
})
->get()
->each(function (Organization $organization) {
$service = new EuPlatescService($organization);

$organization->donations
->each(fn (Donation $donation) => CaptureAuthorizedDonationJob::dispatch($donation, $service));
});
}
}
5 changes: 5 additions & 0 deletions app/Models/Donation.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ public function scopeSearch(Builder $query, string $searchedText): Builder
->orWhere('email', 'LIKE', "%{$searchedText}%");
}

public function scopeWhereAuthorized(Builder $query): Builder
{
return $query->where('donations.status', EuPlatescStatus::AUTHORIZED);
}

public function scopeWhereCharged(Builder $query): Builder
{
return $query->where('status', EuPlatescStatus::CHARGED);
Expand Down
7 changes: 5 additions & 2 deletions app/Services/EuPlatescService.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ class EuPlatescService

private string $url;

public function __construct($organizationId)
public function __construct(Organization | int $organization)
{
$organization = Organization::findOrFail($organizationId);
if (! $organization instanceof Organization) {
$organization = Organization::findOrFail($organization);
}

$this->merchantId = $organization->eu_platesc_merchant_id;
$this->privateKey = $organization->eu_platesc_private_key;
$this->userKey = $organization->eu_platesc_merchant_id ?? '';
Expand Down
Empty file.
1 change: 1 addition & 0 deletions docker/s6-rc.d/worker/dependencies
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
laravel
9 changes: 9 additions & 0 deletions docker/s6-rc.d/worker/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/command/with-contenv sh

php /var/www/artisan queue:work \
--max-jobs $WORKER_MAX_JOBS \
--sleep $WORKER_SLEEP \
--rest $WORKER_REST \
--timeout $WORKER_TIMEOUT \
--tries $WORKER_TRIES \
--force
1 change: 1 addition & 0 deletions docker/s6-rc.d/worker/type
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
longrun

0 comments on commit d77145c

Please sign in to comment.