Skip to content
Draft
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
6 changes: 6 additions & 0 deletions extensions/gdpr/src/Jobs/ExportJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@

class ExportJob extends GdprJob
{
/**
* Each run writes an export file and dispatches Exporting/Exported events;
* retries would duplicate the file and fire listeners more than once.
*/
public int $tries = 1;

public function __construct(private User $user, private User $actor)
{
}
Expand Down
25 changes: 24 additions & 1 deletion extensions/package-manager/src/Job/ComposerCommandJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ class ComposerCommandJob extends AbstractJob implements ShouldBeUnique
*/
public int $timeout = 60 * 3;

/**
* Composer commands are not idempotent; a retry after OOM (which bypasses
* the handle() try/catch) could run against a partially-modified vendor/.
*/
public int $tries = 1;

/**
* How long (seconds) the ShouldBeUnique lock is held.
*
* Without an explicit value the default is 0, meaning the lock never
* expires. If the worker crashes mid-install, the lock can otherwise
* block future dispatches until the cache TTL runs down. 600s is
* longer than $timeout above so it won't expire mid-run.
*/
public int $uniqueFor = 600;

public function __construct(
protected AbstractActionCommand $command,
protected string $phpVersion
Expand Down Expand Up @@ -67,7 +83,14 @@ public function failed(Throwable $exception): void
public function middleware(): array
{
return [
new WithoutOverlapping(),
// expireAfter matches $uniqueFor above so a crashed worker
// can't leave the overlap lock permanently held (default 0
// would mean the lock never expires). dontRelease fails a
// duplicate dispatch cleanly instead of tight-looping it
// against the held lock (default releaseAfter=0).
(new WithoutOverlapping())
->expireAfter(600)
->dontRelease(),
];
}
}
6 changes: 6 additions & 0 deletions extensions/subscriptions/src/Job/SendReplyNotification.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ class SendReplyNotification implements ShouldQueue
use Queueable;
use SerializesModels;

/** The maximum number of times the job may be attempted. */
public int $tries = 3;

/** Delay in seconds between retries. */
public array $backoff = [30, 60, 120];

public function __construct(
protected Post $post,
protected ?int $lastPostNumber
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@

class SendNotificationsJob extends AbstractJob
{
/**
* Notification::notify() uses a raw bulk insert (not upsert), so retrying
* would create duplicate notification rows in recipients' feeds.
*/
public int $tries = 1;

public function __construct(
private readonly BlueprintInterface&AlertableInterface $blueprint,
/** @var User[] */
Expand Down
6 changes: 6 additions & 0 deletions framework/core/src/Queue/AbstractJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,10 @@ class AbstractJob implements ShouldQueue
use InteractsWithQueue;
use Queueable;
use SerializesModels;

/** The maximum number of times the job may be attempted. */
public int $tries = 3;

/** Delay in seconds between retries. */
public array $backoff = [30, 60, 120];
}