2024-05-25 12:25:57 +00:00
< ? 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 ;
2024-05-26 11:41:02 +00:00
use App\Classes\FTN\Message ;
2024-06-12 13:12:51 +00:00
use App\Models\ { Address , Domain , System };
2024-05-25 12:25:57 +00:00
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 ;
$this -> ao = $ao ;
}
/**
* Execute the job .
*/
public function handle () : void
{
$result = collect ();
// Delist DOWN nodes
foreach ( $this -> old ( $this -> do , config ( 'fido.idle.delist' ), Address :: NODE_DOWN , $this -> ao ) as $ao ) {
// Only delist system that has been marked down
2024-09-08 10:39:10 +00:00
// Only mark delist them if its been 14 days since they were marked DOWN
if (( ! $ao -> is_down ) || ( $ao -> updated_at -> greaterThan ( Carbon :: now () -> subWeeks ( 2 ))))
2024-05-25 12:25:57 +00:00
continue ;
Log :: info ( sprintf ( '%s:- Delisting [%s], not seen for [%d] days' , self :: LOGKEY , $ao -> ftn , config ( 'fido.idle.delist' )));
$contact = FALSE ;
2024-05-26 11:41:02 +00:00
// Remove echomail not collected from echomail_seenby
DB :: table ( 'echomail_seenby' )
-> where ( 'address_id' , $ao -> id )
-> whereNotNull ( 'export_at' )
-> whereNull ( 'sent_at' )
-> delete ();
// Remove FLAG_INTRANSIT from netmail that hasnt been delivered
DB :: table ( 'netmails' )
-> where ( 'tftn_id' , $ao -> id )
-> whereRaw ( sprintf ( '(flags & %d) > 0' , Message :: FLAG_INTRANSIT ))
-> update ([ 'flags' => DB :: raw ( sprintf ( '(flags & ~%d)' , Message :: FLAG_INTRANSIT ))]);
// Remove files not collected
DB :: table ( 'file_seenby' )
-> where ( 'address_id' , $ao -> id )
-> whereNotNull ( 'export_at' )
-> whereNull ( 'sent_at' )
-> delete ();
// Remove subscribed echoareas
$ao -> echoareas () -> detach ();
// Remove subscribed fileareas
$ao -> fileareas () -> detach ();
2024-05-25 12:25:57 +00:00
$ao -> active = FALSE ;
2024-05-26 11:41:02 +00:00
$ao -> validated = FALSE ;
2024-05-25 12:25:57 +00:00
$ao -> save ();
// Email Alert
if ( $ao -> system -> users -> count ()) {
Notification :: send ( $ao -> system -> users , new NodeDelistedEmail ( $ao -> withoutRelations ()));
$contact = TRUE ;
}
// Netmail Alert (to othernet network address)
2024-05-26 10:53:59 +00:00
if ( $ao -> system -> uncommon () -> count ()) {
Notification :: route ( 'netmail' , $ao -> system -> uncommon () -> first () -> withoutRelations ()) -> notify ( new NodeDelistedNetmail ( $ao -> withoutRelations ()));
2024-05-25 12:25:57 +00:00
$contact = TRUE ;
}
2024-06-30 01:40:53 +00:00
$ao -> contacted = $contact ;
2024-05-25 12:25:57 +00:00
$result -> push ( $ao );
}
// Mark nodes DOWN
foreach ( $this -> old ( $this -> do , config ( 'fido.idle.down' ), Address :: NODE_HOLD , $this -> ao ) as $ao ) {
Log :: info ( sprintf ( '%s:- Marking [%s] as DOWN, not seen for [%d] days' , self :: LOGKEY , $ao -> ftn , config ( 'fido.idle.down' )));
$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)
2024-05-26 10:53:59 +00:00
if ( $ao -> system -> uncommon () -> count ()) {
Notification :: route ( 'netmail' , $ao -> system -> uncommon () -> first () -> withoutRelations ()) -> notify ( new NodeMarkedDownNetmail ( $ao -> withoutRelations ()));
2024-05-25 12:25:57 +00:00
$contact = TRUE ;
}
// Mark as DOWN
$ao -> role &= ~ Address :: NODE_HOLD ;
$ao -> role |= Address :: NODE_DOWN ;
$ao -> save ();
2024-06-30 01:40:53 +00:00
$ao -> contacted = $contact ;
2024-05-25 12:25:57 +00:00
$result -> push ( $ao );
}
2024-09-08 10:39:10 +00:00
// @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)
2024-05-25 12:25:57 +00:00
// Mark nodes as HOLD
2024-09-08 10:39:10 +00:00
foreach ( $this -> old ( $this -> do , config ( 'fido.idle.hold' ), Address :: NODE_ALL , $this -> ao ) as $ao ) {
2024-06-12 13:12:51 +00:00
// 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 ;
}
2024-05-25 12:25:57 +00:00
// Ignore any systems already marked hold or down
if ( $ao -> role & ( Address :: NODE_DOWN | Address :: NODE_HOLD ))
continue ;
$contact = FALSE ;
Log :: info ( sprintf ( '%s:- Marking [%s] as HOLD, not seen for [%d] days' , self :: LOGKEY , $ao -> ftn , config ( 'fido.idle.hold' )));
// Email Alert
if ( $ao -> system -> users -> count ()) {
Notification :: send ( $ao -> system -> users , new NodeMarkedHoldEmail ( $ao -> withoutRelations ()));
$contact = TRUE ;
}
// Netmail Alert (to othernet network address)
2024-05-26 10:53:59 +00:00
if ( $ao -> system -> uncommon () -> count ()) {
Notification :: route ( 'netmail' , $ao -> system -> uncommon () -> first () -> withoutRelations ()) -> notify ( new NodeMarkedHoldNetmail ( $ao -> withoutRelations ()));
2024-05-25 12:25:57 +00:00
$contact = TRUE ;
}
// Mark as DOWN
$ao -> role |= Address :: NODE_HOLD ;
$ao -> save ();
2024-06-30 01:40:53 +00:00
$ao -> contacted = $contact ;
2024-05-25 12:25:57 +00:00
$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
{
$age = Carbon :: now () -> subDays ( $days ) -> endOfDay ();
return Address :: select ([
'a.id' ,
'a.system_id' ,
'a.zone_id' ,
'addresses.region_id' ,
'a.host_id' ,
'a.node_id' ,
'a.point_id' ,
'addresses.active' ,
'addresses.hub_id' ,
'addresses.role' ,
'addresses.updated_at' ,
DB :: raw ( 'sum(a.uncollected_echomail) as uncollected_echomail' ),
DB :: raw ( 'sum(a.uncollected_netmail) as uncollected_netmail' ),
DB :: raw ( 'sum(a.uncollected_files) as uncollected_files' )
])
-> from (
Address :: UncollectedEchomailTotal ()
-> union ( Address :: UncollectedNetmailTotal ())
-> union ( Address :: UncollectedFilesTotal ()), 'a' )
-> where ( 'systems.active' , TRUE )
-> where ( 'addresses.active' , TRUE )
-> where ( 'zones.active' , TRUE )
-> where ( 'domains.active' , TRUE )
2024-06-30 01:40:53 +00:00
-> where ( fn ( $query ) => $query -> where ( 'a.point_id' , 0 ) -> orWhereNull ( 'a.point_id' ))
2024-05-25 12:25:57 +00:00
-> whereNotIn ( 'a.id' , our_address () -> pluck ( 'id' ))
-> when ( $ao , fn ( $query ) => $query -> where ( 'addresses.id' , $ao -> id ))
-> where ( 'last_session' , '<' , $age )
-> where ( 'domains.id' , $do -> id )
-> whereRaw ( sprintf ( '((role IS NULL) OR ((role & %d) > 0))' , $flags ))
-> join ( 'addresses' ,[ 'addresses.id' => 'a.id' ])
-> join ( 'systems' ,[ 'systems.id' => 'a.system_id' ])
-> join ( 'zones' ,[ 'zones.id' => 'addresses.zone_id' ])
-> join ( 'domains' ,[ 'domains.id' => 'zones.domain_id' ])
-> ftnOrder ()
-> groupBy ( 'a.system_id' , 'a.id' , 'a.zone_id' , 'addresses.region_id' , 'a.host_id' , 'a.node_id' , 'a.point_id' , 'addresses.hub_id' , 'addresses.role' , 'addresses.active' , 'addresses.updated_at' )
-> with ([ 'system' , 'zone.domain' ])
-> dontCache ()
-> get ();
}
}