Skip to content

Make all possible queued classes silenceable (question for PR) #1239

@lioneaglesolutions

Description

@lioneaglesolutions

I really like the new Silence feature but notice that id doesn't work for queued Listeners - only Jobs. Is this by design?

I was hacking on a PR which I have working but when it comes to writing tests, I need access to the config helper in JobPayload which means it can't be a unit test. I wanted to see if there's any reason we can move this into a Feature test?

The main thing the PR does it move the logic that determines if a job is silenced, from the MarkJobAsComplete listener into the JobPayload.

// MarkJobAsComplete.php

$isSilenced = in_array($event->payload->commandName(), config('horizon.silenced', [])) ||
    is_a($event->payload->commandName(), Silenced::class, true);

$this->jobs->completed($event->payload, $event->job->hasFailed(), $isSilenced);

This becomes;

$this->jobs->completed($event->payload, $event->job->hasFailed(), $event->payload->isSilenced());

And then in the JobPayload class;

public function prepare($job)
{
    return $this->set([
        'type' => $this->determineType($job),
        'tags' => $this->determineTags($job),
+       'silenced' => $this->determineIfJobIsSilenced($job),
        'pushedAt' => str_replace(',', '.', microtime(true)),
    ]);
}

New methods;

public function isSilenced()
{
    return isset($this->decoded['silenced']) ?? false;
}

public function determineIfJobIsSilenced($job)
{
    $jobClass = $this->underlyingJobClass($job);

    return in_array(get_class($jobClass), config('horizon.silenced', [])) ||
                is_a($jobClass, Silenced::class, true);
}

public function underlyingJobClass($job)
{
    switch (true) {
        case $job instanceof BroadcastEvent:
            return $job->event;
        case $job instanceof CallQueuedListener:
            return $job->class;
        case $job instanceof SendQueuedMailable:
            return $job->mailable;
        case $job instanceof SendQueuedNotifications:
            return $job->notification;
        default:
            return $job;
    }
}

The only issue here is config('horizon.silenced', []) is not available in the unit tests and wanted to see if there would be anything wrong with a PR that moves those tests into Feature and then this would allow you to Silence anything that is queueable - not just jobs. I feel like being able to silence any queued job - especially listeners would be great.

Happy to do the PR - just didn't want to go ahead before knowing if it's possible with the above change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions