diff --git a/app/Jobs/AddressPoll.php b/app/Jobs/AddressPoll.php index 5470d48..428a21f 100644 --- a/app/Jobs/AddressPoll.php +++ b/app/Jobs/AddressPoll.php @@ -9,6 +9,7 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\ManuallyFailedException; use Illuminate\Queue\MaxAttemptsExceededException; +use Illuminate\Queue\Middleware\Skip; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Log; @@ -36,8 +37,10 @@ class AddressPoll implements ShouldQueue, ShouldBeUnique private Address $ao; private ?Mailer $mo; + // Whether to force poll even if there isnt anything waiting to send + private bool $force = FALSE; - public function __construct(Address $ao,Mailer $mo=NULL) + public function __construct(Address $ao,Mailer $mo=NULL,bool $force=FALSE) { $this->ao = $ao->withoutRelations(); $this->mo = $mo?->withoutRelations(); @@ -77,14 +80,8 @@ class AddressPoll implements ShouldQueue, ShouldBeUnique /** * When calling MessageProcess - we assume that the packet is from a valid source */ - public function handle() + public function handle(): void { - if (! $this->ao->system->mailer_preferred->count() || ($this->mo && (! $this->ao->system->mailer_preferred->find($this->mo)))) { - $this->fail('Missing mailer details'); - - return; - } - Log::info(sprintf('%s:- Polling [%s] - attempt [%d]',self::LOGKEY,$this->ao->ftn,$this->attempts())); $setup = Config::get('setup',Setup::findOrFail(config('app.id'))); @@ -144,15 +141,15 @@ class AddressPoll implements ShouldQueue, ShouldBeUnique switch (get_class($exception)) { case ManuallyFailedException::class: Log::error(sprintf('%s:! Address Poll failed for [%s] (%s)',self::LOGKEY,$this->ao->ftn,$exception->getMessage())); - break; + exit(0); case MaxAttemptsExceededException::class: Log::error(sprintf('%s:! Address Poll was tried too many times for [%s]',self::LOGKEY,$this->ao->ftn)); - Notification::route('netmail',$this->ao)->notify(new PollingFailed); + Notification::route('netmail',$this->ao) + ->notify(new PollingFailed); $this->ao->system->autohold = TRUE; $this->ao->system->save(); - exit(0); default: @@ -160,6 +157,38 @@ class AddressPoll implements ShouldQueue, ShouldBeUnique } } + public function middleware(): array + { + return [ + // If there are no mailer details, we cant poll + Skip::when(function(): bool { + if (! $this->ao->system->mailer_preferred->count() + // If we specify a mailer, make sure it is preferred by the system + || ($this->mo && (! $this->ao->system->mailer_preferred->find($this->mo)))) { + Log::error(sprintf('%s:! No mailer details, cannot poll [%s]',self::LOGKEY,$this->ao->ftn)); + + return TRUE; + } + + return FALSE; + }), + + // If there is no mail anymore, no need trying + Skip::unless(function(): bool { + if ($this->force + || ($this->ao->echomailWaitingCount() > 0) + || ($this->ao->fileWaitingCount() > 0) + || ($this->ao->netmailWaitingCount() > 0)) { + + return TRUE; + } + + Log::info(sprintf('%s:/ Nothing waiting - abandoning poll [%s]',self::LOGKEY,$this->ao->ftn)); + return FALSE; + }), + ]; + } + public function uniqueId(): string { return $this->ao->id; diff --git a/app/Jobs/MailSend.php b/app/Jobs/MailSend.php index 46a77a8..9621c60 100644 --- a/app/Jobs/MailSend.php +++ b/app/Jobs/MailSend.php @@ -15,10 +15,14 @@ class MailSend #implements ShouldQueue private const LOGKEY = 'JMS'; + private bool $mode; + /** * @param bool $crash Send crash mail only */ - public function __construct(private ?bool $crash=NULL) {} + public function __construct(?bool $mode=NULL) { + $this->mode = $mode; + } /** * Execute the job. @@ -30,6 +34,7 @@ class MailSend #implements ShouldQueue ->HubStats(Carbon::now()) ->get() ->transform(function($item) { + // Add the list of queued items to the uplink if ($x=$item->uplink()) { $x->uncollected_echomail = $item->uncollected_echomail; $x->uncollected_netmail = $item->uncollected_netmail; @@ -41,15 +46,13 @@ class MailSend #implements ShouldQueue return $item; } }) - ->filter(function($item) { - if ($item->system->autohold) - return NULL; - - return is_null($this->crash) || ($item->system->pollmode) || ($item->system->pollmode === $this->crash) ? $item : NULL; - }); + ->filter(fn($item)=>(! $item->system->autohold) // System is not on autohold + && (is_null($this->mode) // If we didnt specify a poll mode, poll anyway + || ($item->system->pollmode) // If system poll mode is set to crash + || ($item->system->pollmode === $this->mode))); // If the sytem poll mode is the same as mode calling this send foreach ($u->groupBy('ftn') as $oo) { - if (Job::where('queue','poll')->get()->pluck('command.address.id')->search(($x=$oo->first())->id) === FALSE) { + if (! Job::where('queue','poll')->get()->pluck('command.address.id')->contains(($x=$oo->first())->id)) { Log::info(sprintf('%s:- Polling [%s] - we have mail for [%d] links. (%d Netmail,%d Echomail,%d Files)', self::LOGKEY, $x->ftn, diff --git a/app/Models/Address.php b/app/Models/Address.php index ce4e77b..32aaee2 100644 --- a/app/Models/Address.php +++ b/app/Models/Address.php @@ -920,12 +920,12 @@ class Address extends Model // If this system is not marked to default route for this address if (! $this->is_default_route) { - $children = $this->children() + $downlinks = $this->children() ->push($this); // We route everything for this domain } else { - $children = self::select('addresses.*') + $downlinks = self::select('addresses.*') ->join('zones',['zones.id'=>'addresses.zone_id']) ->where('addresses.id','<>',$this->id) ->where('domain_id',$this->zone->domain_id) @@ -936,9 +936,15 @@ class Address extends Model } // If there are no children - if (! $children->count()) + if (! $downlinks->count()) return new Collection; + // Exclude any children of our addresses + $downlinks = $downlinks + ->diff(($x=our_address($this->zone->domain,FALSE)) + ->flatMap(fn($item)=>$item->children()) + ->merge($x)); + // Exclude links and their children. $exclude = collect(); foreach (our_nodes($this->zone->domain)->diff([$this]) as $o) { @@ -951,7 +957,7 @@ class Address extends Model $exclude->push($o); } - return $children->diff($exclude); + return $downlinks->diff($exclude); } /**