Skip to content

Commit

Permalink
Merge pull request #2655 from RaiderIO/development
Browse files Browse the repository at this point in the history
Release v11.8.1 - Bugfixes
  • Loading branch information
Wotuu authored Jan 8, 2025
2 parents 362b3ff + 16243d3 commit 810db39
Show file tree
Hide file tree
Showing 235 changed files with 4,079 additions and 821 deletions.
2 changes: 1 addition & 1 deletion app/Console/Commands/Dungeon/CreateMissing.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function handle(): int
foreach (Dungeon::ALL as $expansionKey => $dungeonKeys) {

// Temp, I just want classic dungeons for now
if ($expansionKey !== Expansion::EXPANSION_CLASSIC) {
if ($expansionKey !== Expansion::EXPANSION_MOP) {
continue;
}

Expand Down
3 changes: 3 additions & 0 deletions app/Console/Commands/Dungeon/CreateMissingFloors.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public function handle(): int

$this->info(sprintf('- %s', __($dungeon->name, [], 'en_US')));
$index = 1;
if (!is_array($translatedFloors)) {
throw new \Exception(sprintf('Translated floors should be an array for %s', $dungeon->name));
}
foreach ($translatedFloors as $key => $value) {
$floorKey = sprintf('%s.%s', $floorsTranslationKey, $key);

Expand Down
79 changes: 43 additions & 36 deletions app/Console/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
use App\Console\Commands\Wowhead\FetchSpellData;
use App\Console\Commands\Wowhead\RefreshDisplayIds as RefreshDisplayIdsWowhead;
use App\Console\Commands\WowTools\RefreshDisplayIds;
use App\Logging\StructuredLogging;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\Log;
Expand Down Expand Up @@ -223,58 +224,64 @@ class Kernel extends ConsoleKernel
*/
protected function schedule(Schedule $schedule): void
{
Log::channel('scheduler')->debug('Starting scheduler');
try {
Log::channel('scheduler')->debug('Starting scheduler');

$debug = config('app.debug');
$appType = config('app.type');
if ($this->app->runningInConsole() && !$this->app->runningUnitTests()) {
StructuredLogging::setChannel('stderr');
}

$schedule->command('dungeonroute:updatepopularity')->hourly();
$schedule->command('dungeonroute:updaterating')->everyFifteenMinutes();
$debug = config('app.debug');
$appType = config('app.type');

$schedule->command('dungeonroute:refreshoutdatedthumbnails')->everyFifteenMinutes();
$schedule->command('dungeonroute:deleteexpired')->hourly();
$schedule->command('dungeonroute:updatepopularity')->hourly();
$schedule->command('dungeonroute:updaterating')->everyFifteenMinutes();

if (in_array($appType, ['mapping', 'local'])) {
$schedule->command('mapping:sync')->everyFiveMinutes();
$schedule->command('dungeonroute:refreshoutdatedthumbnails')->everyFifteenMinutes();
$schedule->command('dungeonroute:deleteexpired')->hourly();

// Ensure display IDs are set
$schedule->command('wowhead:refreshdisplayids')->hourly();
}
if (in_array($appType, ['mapping', 'local'])) {
$schedule->command('mapping:sync')->everyFiveMinutes();

$schedule->command('affixgroupeasetiers:refresh')->cron('0 */8 * * *'); // Every 8 hours
// Ensure display IDs are set
$schedule->command('wowhead:refreshdisplayids')->hourly();
}

// https://laravel.com/docs/8.x/horizon
$schedule->command('horizon:snapshot')->everyFiveMinutes();
$schedule->command('affixgroupeasetiers:refresh')->cron('0 */8 * * *'); // Every 8 hours

if ($appType === 'live') {
$schedule->command('scheduler:telemetry')->everyFiveMinutes();
}
// https://laravel.com/docs/8.x/horizon
$schedule->command('horizon:snapshot')->everyFiveMinutes();

// https://laravel.com/docs/8.x/telescope#data-pruning
$schedule->command('telescope:prune --hours=48')->daily();
if ($appType === 'live') {
$schedule->command('scheduler:telemetry')->everyFiveMinutes();
}

// Refresh any membership status - if they're unsubbed, revoke their access. If they're subbed, add access
$schedule->command('patreon:refreshmembers')->hourly();
// https://laravel.com/docs/8.x/telescope#data-pruning
$schedule->command('telescope:prune --hours=48')->daily();

// We don't want the cache when we're debugging to ensure fresh data every time
if (!$debug) {
$schedule->command('discover:cache')->hourly();
$schedule->command('keystoneguru:view cache')->everyTenMinutes();
}
// Refresh any membership status - if they're unsubbed, revoke their access. If they're subbed, add access
$schedule->command('patreon:refreshmembers')->hourly();

// Ensure redis remains healthy
$schedule->command('redis:clearidlekeys 900')->everyFifteenMinutes();
// We don't want the cache when we're debugging to ensure fresh data every time
if (!$debug) {
$schedule->command('discover:cache')->hourly();
$schedule->command('keystoneguru:view cache')->everyTenMinutes();
}

// Aggregate all metrics so they're nice and snappy to load
$schedule->command('metric:aggregate')->everyFiveMinutes();
// Ensure redis remains healthy
$schedule->command('redis:clearidlekeys 900')->everyFifteenMinutes();

// Sync ads.txt
$schedule->command('adprovider:syncadstxt')->everyFifteenMinutes();
// Aggregate all metrics so they're nice and snappy to load
$schedule->command('metric:aggregate')->everyFiveMinutes();

// Cleanup the generated custom thumbnails
$schedule->command('thumbnail:deleteexpiredjobs')->everyFifteenMinutes();
// Sync ads.txt
$schedule->command('adprovider:syncadstxt')->everyFifteenMinutes();

Log::channel('scheduler')->debug('Finished scheduler');
// Cleanup the generated custom thumbnails
$schedule->command('thumbnail:deleteexpiredjobs')->everyFifteenMinutes();
} finally {
Log::channel('scheduler')->debug('Finished scheduler');
}
}

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

namespace App\Jobs\Logging;

use App\Logging\StructuredLogging;

class ProcessRouteFloorThumbnailCustomLogging extends StructuredLogging implements ProcessRouteFloorThumbnailCustomLoggingInterface
{
public function handleStart(string $publicKey, int $floorIndex, int $id, int $attempts, ?int $viewportWidth, ?int $viewportHeight, ?int $imageWidth, ?int $imageHeight, ?float $zoomLevel, ?int $quality): void
{
$this->start(__METHOD__, get_defined_vars());
}

public function handleCreateCustomThumbnailError(): void
{
$this->error(__METHOD__);
}

public function handleFinishedProcessing(): void
{
$this->debug(__METHOD__);
}

public function handleMaxAttemptsReached(): void
{
$this->warning(__METHOD__);
}

public function handleEnd(): void
{
$this->end(__METHOD__);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Jobs\Logging;

interface ProcessRouteFloorThumbnailCustomLoggingInterface
{

public function handleStart(
string $publicKey,
int $floorIndex,
int $id,
int $attempts,
?int $viewportWidth,
?int $viewportHeight,
?int $imageWidth,
?int $imageHeight,
?float $zoomLevel,
?int $quality
): void;

public function handleCreateCustomThumbnailError(): void;

public function handleFinishedProcessing(): void;

public function handleMaxAttemptsReached(): void;

public function handleEnd(): void;
}
35 changes: 35 additions & 0 deletions app/Jobs/Logging/ProcessRouteFloorThumbnailLogging.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace App\Jobs\Logging;

use App\Jobs\Logging\ProcessRouteFloorThumbnailLoggingInterface;
use App\Logging\StructuredLogging;

class ProcessRouteFloorThumbnailLogging extends StructuredLogging implements ProcessRouteFloorThumbnailLoggingInterface
{

public function handleStart(string $publicKey, int $dungeonRouteId, int $mappingVersionId, int $floorIndex, int $attempts): void
{
$this->start(__METHOD__, get_defined_vars());
}

public function handleCreateThumbnailError(): void
{
$this->warning(__METHOD__);
}

public function handleThumbnailAlreadyUpToDate(): void
{
$this->info(__METHOD__);
}

public function handleMaxAttemptsReached(): void
{
$this->warning(__METHOD__);
}

public function handleEnd(bool $result): void
{
$this->end(__METHOD__, get_defined_vars());
}
}
17 changes: 17 additions & 0 deletions app/Jobs/Logging/ProcessRouteFloorThumbnailLoggingInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App\Jobs\Logging;

interface ProcessRouteFloorThumbnailLoggingInterface
{

public function handleStart(string $publicKey, int $dungeonRouteId, int $mappingVersionId, int $floorIndex, int $attempts): void;

public function handleCreateThumbnailError(): void;

public function handleThumbnailAlreadyUpToDate(): void;

public function handleMaxAttemptsReached(): void;

public function handleEnd(bool $result): void;
}
59 changes: 35 additions & 24 deletions app/Jobs/ProcessRouteFloorThumbnail.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Jobs;

use App\Jobs\Logging\ProcessRouteFloorThumbnailLoggingInterface;
use App\Models\DungeonRoute\DungeonRoute;
use App\Service\DungeonRoute\ThumbnailServiceInterface;
use Exception;
Expand All @@ -10,7 +11,6 @@
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class ProcessRouteFloorThumbnail implements ShouldQueue
{
Expand All @@ -22,8 +22,11 @@ class ProcessRouteFloorThumbnail implements ShouldQueue
/**
* Create a new job instance.
*/
public function __construct(protected ThumbnailServiceInterface $thumbnailService, protected DungeonRoute $dungeonRoute, protected int $floorIndex, protected int $attempts = 0)
{
public function __construct(
protected DungeonRoute $dungeonRoute,
protected int $floorIndex,
protected int $attempts = 0
) {
$this->queue = sprintf('%s-%s-thumbnail', config('app.type'), config('app.env'));
}

Expand All @@ -32,33 +35,41 @@ public function __construct(protected ThumbnailServiceInterface $thumbnailServic
*/
public function handle(): void
{
Log::channel('scheduler')->info(
sprintf('Started processing %s:%s (%d)', $this->dungeonRoute->public_key, $this->floorIndex, $this->dungeonRoute->id)
);

$result = false;
if ((int)config('keystoneguru.thumbnail.max_attempts') > $this->attempts) {
// Give some additional space since we're refreshing ALL floors - the first floor may get processed,
// but the floors after that will otherwise think "oh the thumbnail is up-to-date" and not refresh.
if ($this->dungeonRoute->thumbnail_updated_at->isBefore($this->dungeonRoute->updated_at->addHour()) ||
$this->dungeonRoute->thumbnail_updated_at->addDays(config('keystoneguru.thumbnail.refresh_days'))->isBefore(now())) {
$result = $this->thumbnailService->createThumbnail($this->dungeonRoute, $this->floorIndex, $this->attempts);

if (!$result) {
Log::channel('scheduler')->warning(sprintf('Error refreshing thumbnail, attempt %d', $this->attempts));
// Cannot serialize these objects - so we have to create them here
$thumbnailService = app()->make(ThumbnailServiceInterface::class);
$log = app()->make(ProcessRouteFloorThumbnailLoggingInterface::class);

try {
$log->handleStart(
$this->dungeonRoute->public_key,
$this->dungeonRoute->id,
$this->dungeonRoute->mapping_version_id,
$this->floorIndex,
$this->attempts
);

// If there were errors, try again
ProcessRouteFloorThumbnail::dispatch($this->thumbnailService, $this->dungeonRoute, $this->floorIndex, ++$this->attempts);
if ((int)config('keystoneguru.thumbnail.max_attempts') > $this->attempts) {
// Give some additional space since we're refreshing ALL floors - the first floor may get processed,
// but the floors after that will otherwise think "oh the thumbnail is up-to-date" and not refresh.
if ($this->dungeonRoute->thumbnail_updated_at->isBefore($this->dungeonRoute->updated_at->addHour())) {
$result = $thumbnailService->createThumbnail($this->dungeonRoute, $this->floorIndex, $this->attempts);

if (!$result) {
$log->handleCreateThumbnailError();

// If there were errors, try again
ProcessRouteFloorThumbnail::dispatch($this->dungeonRoute, $this->floorIndex, ++$this->attempts);
}
} else {
$log->handleThumbnailAlreadyUpToDate();
}
} else {
Log::channel('scheduler')->warning('Not refreshing thumbnail - thumbnail is already up-to-date');
$log->handleMaxAttemptsReached();
}
} else {
Log::channel('scheduler')->warning(sprintf('Not refreshing thumbnail - max attempts of %d reached', $this->attempts));
} finally {
$log->handleEnd($result);
}

Log::channel('scheduler')->info(
sprintf('Finished processing %s:%s (%d) -> %d', $this->dungeonRoute->public_key, $this->floorIndex, $this->dungeonRoute->id, (int)$result)
);
}
}
Loading

0 comments on commit 810db39

Please sign in to comment.