set DXVar.pm defaults into console.pl
[spider.git] / perl / cluster.pl
index 98efced91288e9543eff6879f0cbde30da9a0af6..6495027be2a3a97f5276685434c908be7005ccde 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/env perl
+#!/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'};
@@ -29,18 +52,25 @@ BEGIN {
        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;
@@ -51,11 +81,16 @@ BEGIN {
 
        $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;
@@ -118,16 +153,6 @@ use Web;
 
 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
-                       $broadcast_debug
-                  );
 
 @inqueue = ();                                 # the main input queue, an array of hashes
 $systime = 0;                                  # the time now (in seconds)
@@ -146,7 +171,8 @@ $log_flush_interval = 2;            # interval to wait between log flushes
 
 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
@@ -342,77 +368,6 @@ sub AGWrestart
        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
 {
@@ -439,6 +394,7 @@ sub setup_start
        }
        STDOUT->autoflush(1);
 
+       
        # try to load the database
        if (DXSql::init($dsn)) {
                $dbh = DXSql->new($dsn);
@@ -495,15 +451,25 @@ sub setup_start
 
        # 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
@@ -627,11 +593,112 @@ sub setup_start
        #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();