clrghouz/app/Jobs/AddressIdle.php
Deon George e963675fd3
All checks were successful
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 26s
Create Docker Image / Build Docker Image (arm64) (push) Successful in 1m31s
Create Docker Image / Final Docker Image Manifest (push) Successful in 8s
Continue to show all common addresses in Items Waiting tab, Add Address Clear Queue job to delete anything in the queue for an address
2024-11-04 15:59:00 +11:00

213 lines
7.5 KiB
PHP

<?php
namespace App\Jobs;
use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
use App\Classes\FTN\Message;
use App\Models\{Address,Domain,System};
use App\Notifications\Echomails\AbsentNodes;
use App\Notifications\Emails\NodeMarkedDown as NodeMarkedDownEmail;
use App\Notifications\Netmails\NodeMarkedDown as NodeMarkedDownNetmail;
use App\Notifications\Emails\NodeMarkedHold as NodeMarkedHoldEmail;
use App\Notifications\Netmails\NodeMarkedHold as NodeMarkedHoldNetmail;
use App\Notifications\Emails\NodeDelisted as NodeDelistedEmail;
use App\Notifications\Netmails\NodeDelisted as NodeDelistedNetmail;
class AddressIdle implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private const LOGKEY = 'JAI';
private ?Address $ao; // System address
private Domain $do; // Domain we are processing
/**
* Create a new job instance.
*/
public function __construct(Domain $do,Address $ao=NULL)
{
$this->do = $do->withoutRelations();
$this->ao = $ao?->withoutRelations();
}
/**
* Execute the job.
*/
public function handle(): void
{
$result = collect();
// Delist DOWN nodes
if (config('fido.idle.delist')) {
$age = Carbon::now()->subDays(config('fido.idle.delist'));
foreach ($this->old($this->do,config('fido.idle.delist'),Address::NODE_DOWN,$this->ao) as $ao) {
Log::debug(sprintf('%s:- Evaluating DOWN node [%s], not seen for at least [%d] days, last update [%d] days',self::LOGKEY,$ao->ftn,$ao->system->last_seen?->diffInDays(),$ao->updated_at->diffInDays()));
// Only delist system that has been marked down
// Only delist them if its been 14 days since they were marked DOWN
if ((! $ao->is_down) || ($ao->updated_at->greaterThan(Carbon::now()->subWeeks(2))))
continue;
// Validate that the last seen was infact that long ago
if ($ao->system->last_seen && $ao->system->last_seen->greaterThan($age))
continue;
Log::info(sprintf('%s:- Delisting [%s], not seen for at least [%d] days',self::LOGKEY,$ao->ftn,$ao->system->last_seen?->diffInDays()));
$contact = FALSE;
// Remove subscribed echoareas
$ao->echoareas()->detach();
// Remove subscribed fileareas
$ao->fileareas()->detach();
$ao->active = FALSE;
$ao->validated = FALSE;
$ao->save();
// Clear the queue
AddressClearQueue::dispatchSync($ao);
// Email Alert
if ($ao->system->users->count()) {
Notification::send($ao->system->users,new NodeDelistedEmail($ao->withoutRelations()));
$contact = TRUE;
}
// Netmail Alert (to othernet network address)
if ($ao->system->aka_unknown()->count()) {
Notification::route('netmail',$ao->system->aka_unknown()->first()->withoutRelations())->notify(new NodeDelistedNetmail($ao->withoutRelations()));
$contact = TRUE;
}
$ao->contacted = $contact;
$result->push($ao);
}
}
// Mark nodes DOWN
if (config('fido.idle.down')) {
$age = Carbon::now()->subDays(config('fido.idle.down'));
foreach ($this->old($this->do,config('fido.idle.down'),Address::NODE_HOLD,$this->ao) as $ao) {
Log::debug(sprintf('%s:- Evaluating HOLD node [%s], not seen for at least [%d] days, last update [%d] days',self::LOGKEY,$ao->ftn,$ao->system->last_seen?->diffInDays(),$ao->updated_at->diffInDays()));
// Only mark down system that has been marked down
// Only mark down them if its been 14 days since they were marked HOLD
if ((! $ao->is_hold) || ($ao->updated_at->greaterThan(Carbon::now()->subWeeks(2))))
continue;
// Validate that the last seen was infact that long ago
if ($ao->system->last_seen && $ao->system->last_seen->greaterThan($age))
continue;
Log::info(sprintf('%s:- Marking [%s] as DOWN, not seen for at least [%d] days',self::LOGKEY,$ao->ftn,$ao->system->last_seen?->diffInDays()));
$contact = FALSE;
// Email Alert
if ($ao->system->users->count()) {
Notification::send($ao->system->users,new NodeMarkedDownEmail($ao->withoutRelations()));
$contact = TRUE;
}
// Netmail Alert (to othernet network address)
if ($ao->system->aka_unknown()->count()) {
Notification::route('netmail',$ao->system->aka_unknown()->first()->withoutRelations())->notify(new NodeMarkedDownNetmail($ao->withoutRelations()));
$contact = TRUE;
}
// Mark as DOWN
$ao->role &= ~Address::NODE_HOLD;
$ao->role |= Address::NODE_DOWN;
$ao->save();
$ao->contacted = $contact;
$result->push($ao);
}
}
// @todo Make sure we only process addresses that we are responsible for, eg: 1/999 shouldnt have been processed even though 3/999 as eligible (and they are were connected to the same system)
// Mark nodes as HOLD
if (config('fido.idle.hold')) {
$age = Carbon::now()->subDays(config('fido.idle.hold'));
foreach ($this->old($this->do,config('fido.idle.hold'),Address::NODE_ALL,$this->ao) as $ao) {
Log::debug(sprintf('%s:- Evaluating IDLE node [%s], not seen for at least [%d] days',self::LOGKEY,$ao->ftn,$ao->system->last_seen?->diffInDays()));
// Ignore any systems that are a Discoverd System
if ($ao->system->name === System::default) {
Log::alert(sprintf('%s:! Ignoring HOLD for discovered System [%s]',self::LOGKEY,$ao->ftn));
continue;
}
// Ignore any systems already marked hold or down
if ($ao->role & (Address::NODE_DOWN|Address::NODE_HOLD))
continue;
// Validate that the last seen was infact that long ago
if ($ao->system->last_seen && $ao->system->last_seen->greaterThan($age))
continue;
$contact = FALSE;
Log::info(sprintf('%s:- Marking [%s] as HOLD, not seen for at least [%d] days',self::LOGKEY,$ao->ftn,$ao->system->last_seen?->diffInDays()));
// Email Alert
if ($ao->system->users->count()) {
Notification::send($ao->system->users,new NodeMarkedHoldEmail($ao->withoutRelations()));
$contact = TRUE;
}
// Netmail Alert (to othernet network address)
if ($ao->system->aka_unknown()->count()) {
Notification::route('netmail',$ao->system->aka_unknown()->first()->withoutRelations())->notify(new NodeMarkedHoldNetmail($ao->withoutRelations()));
$contact = TRUE;
}
// Mark as DOWN
$ao->role |= Address::NODE_HOLD;
$ao->save();
$ao->contacted = $contact;
$result->push($ao);
}
}
if ($result->count())
Notification::route('echomail',$this->do->nodestatusarea)->notify(new AbsentNodes($result));
}
private function old(Domain $do,int $days,int $flags=0,Address $ao=NULL): Collection
{
// Ignore dates that are zero
if (! $days)
return collect();
$age = Carbon::now()->subDays($days)->endOfDay();
return Address::FTN()
->ActiveFTN()
->addSelect(['addresses.updated_at'])
->where(fn($query)=>$query->where('point_id',0)->orWhereNull('point_id'))
->whereIn('addresses.id',our_nodes($do)->pluck('id'))
->when($ao,fn($query)=>$query->where('addresses.id',$ao->id))
->where(fn($q)=>$q->where('last_session','<',$age)->orWhereNull('last_session'))
->whereRaw(sprintf('((role IS NULL) OR (role=0) OR ((role & %d) > 0))',$flags))
->whereRaw(sprintf('((role IS NULL) OR ((role & %d) = 0))',Address::NODE_KEEP))
->join('systems',['systems.id'=>'addresses.system_id'])
//->with(['system','zone.domain'])
->get();
}
}