-#!/usr/bin/perl -w
+#!/usr/bin/env perl
#
# This is the DX cluster 'daemon'. It sits in the middle of its little
# web of client routines sucking and blowing data where it may.
#
#
+package main;
+
require 5.10.1;
+use warnings;
+
+use vars qw($root $is_win $systime $lockfn @inqueue $starttime $lockfn @outstanding_connects
+ $zombies @listeners $lang $myalias @debug $userfn $clusteraddr
+ $clusterport $mycall $decease $routeroot $me $reqreg $bumpexisting
+ $allowdxby $dbh $dsn $dbuser $dbpass $do_xml $systime_days $systime_daystart
+ $can_encode $maxconnect_user $maxconnect_node $idle_interval $log_flush_interval
+ $broadcast_debug
+ );
+
+$lang = 'en'; # default language
+$clusteraddr = '127.0.0.1'; # cluster tcp host address - used for things like console.pl
+$clusterport = 27754; # cluster tcp port
+$yes = 'Yes'; # visual representation of yes
+$no = 'No'; # ditto for no
+$user_interval = 11*60; # the interval between unsolicited prompts if no traffic
# make sure that modules are searched in the order local then perl
BEGIN {
umask 002;
+ # take into account any local::lib that might be present
+ eval {
+ require local::lib;
+ };
+ import local::lib unless ($@);
+
# root of directory tree for this system
$root = "/spider";
$root = $ENV{'DXSPIDER_ROOT'} if $ENV{'DXSPIDER_ROOT'};
die "$root/local doesn't exist, please RTFM" unless -d "$root/local";
die "$root/local/DXVars.pm doesn't exist, please RTFM" unless -e "$root/local/DXVars.pm";
- mkdir "$root/local_cmd", 0777 unless -d "$root/local_cmd";
+ # create some directories
+ mkdir "$root/local_cmd", 02774 unless -d "$root/local_cmd";
+ # locally stored data lives here
+ my $local_data = "$root/local_data";
+ mkdir $local_data, 02774 unless -d $local_data;
# try to create and lock a lockfile (this isn't atomic but
# should do for now
- $lockfn = "$root/local/cluster.lck"; # lock file name
+ $lockfn = "$root/local_data/cluster.lck"; # lock file name
if (-w $lockfn) {
open(CLLOCK, "$lockfn") or die "Can't open Lockfile ($lockfn) $!";
my $pid = <CLLOCK>;
if ($pid) {
chomp $pid;
- die "Lockfile ($lockfn) and process $pid exist, another cluster running?" if kill 0, $pid;
+ if (kill 0, $pid) {
+ warn "Lockfile ($lockfn) and process $pid exist, another cluster running?\n";
+ exit 1;
+ }
}
unlink $lockfn;
close CLLOCK;
$is_win = ($^O =~ /^MS/ || $^O =~ /^OS-2/) ? 1 : 0; # is it Windows?
$systime = time;
+
}
+use DXVars;
+use SysVar;
+
+use strict;
+
use Mojo::IOLoop;
-use DXVars;
use Msg;
use IntMsg;
use Internet;
use Local;
-package main;
-
-use strict;
-use vars qw(@inqueue $systime $starttime $lockfn @outstanding_connects
- $zombies $root @listeners $lang $myalias @debug $userfn $clusteraddr
- $clusterport $mycall $decease $is_win $routeroot $me $reqreg $bumpexisting
- $allowdxby $dbh $dsn $dbuser $dbpass $do_xml $systime_days $systime_daystart
- $can_encode $maxconnect_user $maxconnect_node $idle_interval $log_flush_interval
- );
@inqueue = (); # the main input queue, an array of hashes
$systime = 0; # the time now (in seconds)
$idle_interval = 0.500; # the wait between invocations of the main idle loop processing.
$log_flush_interval = 2; # interval to wait between log flushes
-our $ending; # signal that we are ending;
+our $ending; # signal that we are ending;
+our $broadcast_debug; # allow broadcasting of debug info down "enhanced" user connections
+our $clssecs; # the amount of cpu time the DXSpider process have consumed
+our $cldsecs; # the amount of cpu time any child processes have consumed
# send a message to call on conn and disconnect
AGWMsg::init(\&new_channel);
}
-our $io_disconnected;
-
-sub idle_loop
-{
- my $timenow = time;
-
- BPQMsg::process();
-# DXChannel::process();
-
- # $DB::trace = 0;
-
- # do timed stuff, ongoing processing happens one a second
- if ($timenow != $systime) {
- reap() if $zombies;
- $systime = $timenow;
- my $days = int ($systime / 86400);
- if ($systime_days != $days) {
- $systime_days = $days;
- $systime_daystart = $days * 86400;
- }
- IsoTime::update($systime);
- DXCron::process(); # do cron jobs
- DXCommandmode::process(); # process ongoing command mode stuff
- DXXml::process();
- DXProt::process(); # process ongoing ak1a pcxx stuff
- DXConnect::process();
- DXMsg::process();
- DXDb::process();
- DXUser::process();
- DXDupe::process();
- DXCron::process(); # do cron jobs
- IsoTime::update($systime);
- DXProt::process(); # process ongoing ak1a pcxx stuff
- DXConnect::process();
- DXUser::process();
- AGWMsg::process();
-
- Timer::handler();
- DXLog::flushall();
- }
-
- if (defined &Local::process) {
- eval {
- Local::process(); # do any localised processing
- };
- dbg("Local::process error $@") if $@;
- }
-
- while ($ending) {
- my $dxchan;
-
- dbg("DXSpider Ending $ending");
-
- unless ($io_disconnected++) {
-
- # disconnect users
- foreach $dxchan (DXChannel::get_all_users) {
- $dxchan->disconnect;
- }
-
- # disconnect nodes
- foreach $dxchan (DXChannel::get_all_nodes) {
- next if $dxchan == $main::me;
- $dxchan->disconnect(2);
- }
- $main::me->disconnect;
- }
-
- Mojo::IOLoop->stop if --$ending <= 0;
- }
-}
sub setup_start
{
}
# open the debug file, set various FHs to be unbuffered
- dbginit(\&DXCommandmode::broadcast_debug);
+ dbginit($broadcast_debug ? \&DXCommandmode::broadcast_debug : undef);
foreach (@debug) {
dbgadd($_);
}
STDOUT->autoflush(1);
+
# try to load the database
if (DXSql::init($dsn)) {
$dbh = DXSql->new($dsn);
# initialise User file system
dbg("loading user file system ...");
- DXUser->init($userfn, 1);
+ DXUser::init(1);
# look for the sysop and the alias user and complain if they aren't there
{
die "\$myalias \& \$mycall are the same ($mycall)!, they must be different (hint: make \$mycall = '${mycall}-2';). Oh and don't forget to rerun create_sysop.pl!" if $mycall eq $myalias;
my $ref = DXUser::get($mycall);
die "$mycall missing, run the create_sysop.pl script and please RTFM" unless $ref && $ref->priv == 9;
+ my $oldsort = $ref->sort;
+ if ($oldsort ne 'S') {
+ $ref->sort('S');
+ dbg "Resetting node type from $oldsort -> DXSpider ('S')";
+ }
$ref = DXUser::get($myalias);
die "$myalias missing, run the create_sysop.pl script and please RTFM" unless $ref && $ref->priv == 9;
+ $oldsort = $ref->sort;
+ if ($oldsort ne 'U') {
+ $ref->sort('U');
+ dbg "Resetting sysop user type from $oldsort -> User ('U')";
+ }
}
# start listening for incoming messages/connects
#open(DB::OUT, "|tee /tmp/aa");
}
+our $io_disconnected;
+
+sub idle_loop
+{
+ BPQMsg::process();
+
+ if (defined &Local::process) {
+ eval {
+ Local::process(); # do any localised processing
+ };
+ dbg("Local::process error $@") if $@;
+ }
+
+ while ($ending) {
+ my $dxchan;
+
+ dbg("DXSpider Ending $ending");
+
+ unless ($io_disconnected++) {
+
+ # disconnect users
+ foreach $dxchan (DXChannel::get_all_users) {
+ $dxchan->disconnect;
+ }
+
+ # disconnect nodes
+ foreach $dxchan (DXChannel::get_all_nodes) {
+ next if $dxchan == $main::me;
+ $dxchan->disconnect(2);
+ }
+ $main::me->disconnect;
+ }
+
+ Mojo::IOLoop->stop if --$ending <= 0;
+ }
+}
+
+sub per_sec
+{
+ my $timenow = time;
+
+ reap() if $zombies;
+ $systime = $timenow;
+ my $days = int ($systime / 86400);
+ if ($systime_days != $days) {
+ $systime_days = $days;
+ $systime_daystart = $days * 86400;
+ }
+ IsoTime::update($systime);
+ DXCron::process(); # do cron jobs
+ DXCommandmode::process(); # process ongoing command mode stuff
+ DXXml::process();
+ DXProt::process(); # process ongoing ak1a pcxx stuff
+ DXConnect::process();
+ DXMsg::process();
+ DXDb::process();
+ DXUser::process();
+ DXDupe::process();
+ DXCron::process(); # do cron jobs
+ IsoTime::update($systime);
+ DXProt::process(); # process ongoing ak1a pcxx stuff
+ DXConnect::process();
+ DXUser::process();
+ AGWMsg::process();
+
+ Timer::handler();
+ DXLog::flushall();
+}
+
+sub per_10_sec
+{
+
+}
+
+
+sub per_minute
+{
+
+}
+
+sub per_10_minute
+{
+
+}
+
+sub per_hour
+{
+
+}
+
+sub per_day
+{
+
+}
setup_start();
my $main_loop = Mojo::IOLoop->recurring($idle_interval => \&idle_loop);
my $log_flush_loop = Mojo::IOLoop->recurring($log_flush_interval => \&DXLog::flushall);
+my $cpusecs_loop = Mojo::IOLoop->recurring(5 => sub {my @t = times; $clssecs = $t[0]+$t[1]; $cldsecs = $t[2]+$t[3]});
+my $persec = Mojo::IOLoop->recurring(1 => \&per_sec);
+my $per10sec = Mojo::IOLoop->recurring(10 => \&per_10_sec);
+my $permin = Mojo::IOLoop->recurring(60 => \&per_minute);
+my $per10min = Mojo::IOLoop->recurring(600 => \&per_10_minute);
+my $perhour = Mojo::IOLoop->recurring(3600 => \&per_hour);
+my $perday = Mojo::IOLoop->recurring(86400 => \&per_day);
Web::start_node();