/[meteor]/googlecode.com/svn/trunk/meteord
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /googlecode.com/svn/trunk/meteord

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 5 by andrew.betts, Mon Nov 20 18:05:33 2006 UTC revision 9 by andrew.betts, Fri Dec 8 16:52:58 2006 UTC
# Line 1  Line 1 
1  #!/usr/bin/perl -w  #!/usr/bin/perl -w
2  ###############################################################################  ###############################################################################
3  #   Meteor  #   Meteor
4  #   An HTTP server for the 2.0 web  #   An HTTP server for the 2.0 web
5  #   Copyright (c) 2006 contributing authors  #   Copyright (c) 2006 contributing authors
6  #  #
7  #   The Meteor daemon  #   The Meteor daemon
8  #  #
9  ###############################################################################  #       Main program should call Meteor::Config::setCommandLineParameters(@ARGV),.
10  #  #       Afterwards anybody can access $::CONF{<parameterName>}, where
11  #   This program is free software; you can redistribute it and/or modify it  #       <parameterName> is any valid parameter (except 'Help') listed in the
12  #   under the terms of the GNU General Public License as published by the Free  #       @DEFAULTS array below.
13  #   Software Foundation; either version 2 of the License, or (at your option)  #
14  #   any later version.  ###############################################################################
15  #  #
16  #   This program is distributed in the hope that it will be useful, but WITHOUT  #   This program is free software; you can redistribute it and/or modify it
17  #   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or  #   under the terms of the GNU General Public License as published by the Free
18  #   FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for  #   Software Foundation; either version 2 of the License, or (at your option)
19  #   more details.  #   any later version.
20  #  #
21  #   You should have received a copy of the GNU General Public License along  #   This program is distributed in the hope that it will be useful, but WITHOUT
22  #   with this program; if not, write to the Free Software Foundation, Inc.,  #   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23  #   59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  #   FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
24  #  #   more details.
25  #   For more information visit www.meteorserver.org  #
26  #  #   You should have received a copy of the GNU General Public License along
27  ###############################################################################  #   with this program; if not, write to the Free Software Foundation, Inc.,
28    #   59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29    #
30  ###############################################################################  #   For more information visit www.meteorserver.org
31  # Configuration  #
32  ###############################################################################  ###############################################################################
33            
34          use strict;  
35            ###############################################################################
36          use Meteor::Syslog;  # Configuration
37            ###############################################################################
38          use Meteor::Socket;          
39          use Meteor::Connection;          use strict;
40          use Meteor::Controller;          
41          use Meteor::Subscriber;          use Meteor::Syslog;
42          use Meteor::Channel;          
43          use Meteor::Document;          use Meteor::Socket;
44          use Meteor::Config;          use Meteor::Connection;
45                    use Meteor::Controller;
46          $::CRLF="\r\n";         # Line separator to be used throughout all modules          use Meteor::Subscriber;
47                    use Meteor::Channel;
48          our $CONTROL_QUEUE_SIZE=5;          use Meteor::Document;
49          our $SUBSCRIBER_QUEUE_SIZE=20;          use Meteor::Config;
50                    
51          our $MAIN_LOOP_TIMEOUT=60;          $::CRLF="\r\n";         # Line separator to be used throughout all modules
52          our $AGE_CHECK_INTERVALL=60;          
53                    our $CONTROL_QUEUE_SIZE=5;
54          our $MAX_EXIT_DELAY=120;          our $SUBSCRIBER_QUEUE_SIZE=20;
55            
56  ###############################################################################          our $MAIN_LOOP_TIMEOUT=60;
57  # Main          our $AGE_CHECK_INTERVALL=60;
58  ###############################################################################          
59                    our $MAX_EXIT_DELAY=120;
60          #  
61          # Program name  ###############################################################################
62          #  # Main
63          $::PGM=$0;  ###############################################################################
64          $::PGM=~s/^.*\///;          
65                    #
66          #          # Program name
67          # Handle command line options and config file          #
68          #          $::PGM=$0;
69          Meteor::Config->setCommandLineParameters(@ARGV);          $::PGM=~s/^.*\///;
70                    
71          #          #
72          # Do something about warn and die          # Handle command line options and config file
73          #          #
74          unless($::CONF{'Debug'})          Meteor::Config->setCommandLineParameters(@ARGV);
75          {          
76                  $SIG{'__WARN__'}=\&Meteor::Syslog::myWarn;          #
77                  $SIG{'__DIE__'}=\&Meteor::Syslog::myDie;          # Do something about warn and die
78          }          #
79                    unless($::CONF{'Debug'})
80          &::syslog('info',"$::PGM launched!");          {
81                            $SIG{'__WARN__'}=\&Meteor::Syslog::myWarn;
82          #                  $SIG{'__DIE__'}=\&Meteor::Syslog::myDie;
83          # Daemonize          }
84          #          
85          {          &::syslog('info',"$::PGM launched!");
86                  $0="$::PGM daemon";          
87                            #
88                  unless($::CONF{'Debug'})          # Daemonize
89                  {          #
90                          # close standard file descriptors          {
91                          close(STDIN);                  $0="$::PGM daemon";
92                          close(STDOUT);                  
93                          close(STDERR);                  unless($::CONF{'Debug'})
94                          chdir("/");                  {
95                          umask(0);                          # close standard file descriptors
96                          # fork and exit parent                          close(STDIN);
97                          exit if fork;                          close(STDOUT);
98                          setpgrp(0, $$) if defined $SIG{TTOU};                          close(STDERR);
99                          $SIG{TTOU}='ignore' if defined $SIG{TTOU};                          chdir("/");
100                                                    umask(0);
101                          # Avoid 'stdin reopened for output' warning with newer perls                          # fork and exit parent
102                          open(NULL,'/dev/null');                          exit if fork;
103                          <NULL> if(0);                          setpgrp(0, $$) if defined $SIG{TTOU};
104                                                    $SIG{TTOU}='ignore' if defined $SIG{TTOU};
105                          open(OUT,">/var/run/$::PGM.pid");                          
106                          print OUT "$$\n";                          # Avoid 'stdin reopened for output' warning with newer perls
107                          close(OUT);                          open(NULL,'/dev/null');
108                  }                          <NULL> if(0);
109                  else                          
110                  {                          open(OUT,">/var/run/$::PGM.pid");
111                          print "$::PGM PID: $$\n";                          print OUT "$$\n";
112                  }                          close(OUT);
113          }                  }
114                            else
115          #                  {
116          # Signal handlers                          print "$::PGM PID: $$\n";
117          #                  }
118          $::HUP=$::TERM=$::USR1=$::USR2=0;          }
119          $SIG{'HUP'}=sub{$::HUP=1};          
120          $SIG{'TERM'}=sub{$::TERM=1};          #
121          $SIG{'USR1'}=sub{$::USR1=1};          # Signal handlers
122          $SIG{'USR2'}=sub{$::USR2=1};          #
123                    $::HUP=$::TERM=$::USR1=$::USR2=0;
124          #          $SIG{'HUP'}=sub{$::HUP=1};
125          # Run server          $SIG{'TERM'}=sub{$::TERM=1};
126          #          $SIG{'USR1'}=sub{$::USR1=1};
127          my $con_counter=0;          $SIG{'USR2'}=sub{$::USR2=1};
128          my $con;          
129                    #
130          my $controlServer=Meteor::Socket->newServer(          # Run server
131                  $::CONF{'ControllerPort'},          #
132                  $CONTROL_QUEUE_SIZE,          my $con_counter=0;
133                  $::CONF{'ControllerIP'}          my $con;
134          );          
135          my $controlServerFN=$controlServer->fileno();          my $controlServer=Meteor::Socket->newServer(
136                            $::CONF{'ControllerPort'},
137          my $subscriberServer=Meteor::Socket->newServer(                  $CONTROL_QUEUE_SIZE,
138                  $::CONF{'SubscriberPort'},                  $::CONF{'ControllerIP'}
139                  $SUBSCRIBER_QUEUE_SIZE,          );
140                  $::CONF{'SubscriberIP'}          my $controlServerFN=$controlServer->fileno();
141          );          
142          my $subscriberServerFN=$subscriberServer->fileno();          my $subscriberServer=Meteor::Socket->newServer(
143                            $::CONF{'SubscriberPort'},
144          my $serverVector='';                  $SUBSCRIBER_QUEUE_SIZE,
145          vec($serverVector,$controlServerFN,1)=1;                  $::CONF{'SubscriberIP'}
146          vec($serverVector,$subscriberServerFN,1)=1;          );
147                    my $subscriberServerFN=$subscriberServer->fileno();
148          my $lastAgeCheck=time;          
149                    my $serverVector='';
150          my $nextPing=undef;          vec($serverVector,$controlServerFN,1)=1;
151          if(exists($::CONF{'PingInterval'}) && $::CONF{'PingInterval'}>2)          vec($serverVector,$subscriberServerFN,1)=1;
152          {          
153                  $nextPing=$::CONF{'PingInterval'}+$lastAgeCheck;          my $lastAgeCheck=time;
154          }          
155                    my $nextPing=undef;
156          while(!$::TERM)          if(exists($::CONF{'PingInterval'}) && $::CONF{'PingInterval'}>2)
157          {          {
158                  eval                  $nextPing=$::CONF{'PingInterval'}+$lastAgeCheck;
159                  {          }
160                          while(!$::TERM)          
161                          {          while(!$::TERM)
162                                  my $rVec=$serverVector;          {
163                                  my $wVec='';                  eval
164                                  my $eVec='';                  {
165                                            while(!$::TERM)
166                                  my $rout;                          {
167                                  my $wout;                                  my $rVec=$serverVector;
168                                  my $eout;                                  my $wVec='';
169                                                    my $eVec='';
170                                  Meteor::Connection->addAllHandleBits(\$rVec,\$wVec,\$eVec);                  
171                                                                    my $rout;
172                                  my $timeout=$MAIN_LOOP_TIMEOUT;                                  my $wout;
173                                  if(defined($nextPing))                                  my $eout;
174                                  {                  
175                                          $timeout=$nextPing-time;                                  Meteor::Connection->addAllHandleBits(\$rVec,\$wVec,\$eVec);
176                                  }                                  
177                                                                    my $timeout=$MAIN_LOOP_TIMEOUT;
178                                  my $result=0;                                  if(defined($nextPing))
179                                  if($timeout>0)                                  {
180                                  {                                          $timeout=$nextPing-time;
181                                          $result=&Meteor::Socket::sselect($rout=$rVec,$wout=$wVec,$eout=$eVec,$timeout);                                  }
182                                  }                                  
183                                                                    my $result=0;
184                                  if($result>0)                                  if($timeout>0)
185                                  {                                  {
186                                          if(vec($rout,$controlServerFN,1))                                          $result=&Meteor::Socket::sselect($rout=$rVec,$wout=$wVec,$eout=$eVec,$timeout);
187                                          {                                  }
188                                                  Meteor::Controller->newFromServer($controlServer);                                  
189                                          }                                  if($result>0)
190                                          if(vec($rout,$subscriberServerFN,1))                                  {
191                                          {                                          if(vec($rout,$controlServerFN,1))
192                                                  Meteor::Subscriber->newFromServer($subscriberServer);                                          {
193                                          }                                                  Meteor::Controller->newFromServer($controlServer);
194                                                                                    }
195                                          Meteor::Connection->checkAllHandleBits($rout,$wout,$eout);                                          if(vec($rout,$subscriberServerFN,1))
196                                  }                                          {
197                                  elsif($result<0)                                                  Meteor::Subscriber->newFromServer($subscriberServer);
198                                  {                                          }
199                                          &::syslog('crit',"Select failed: $!");                                          
200                                          sleep(30);                                          Meteor::Connection->checkAllHandleBits($rout,$wout,$eout);
201                                  }                                  }
202                                                                    elsif($result<0)
203                                  if($::HUP)                                  {
204                                  {                                          &::syslog('crit',"Select failed: $!");
205                                          $::HUP=0;                                          sleep(30);
206                                                                            }
207                                          &::syslog('info',"Received SIGHUP, re-reading config and clearing document cache!");                                  
208                                                                            if($::HUP)
209                                          Meteor::Config->readConfig();                                  {
210                                          Meteor::Config->updateConfig();                                          $::HUP=0;
211                                                                                    
212                                          Meteor::Document->clearDocuments()                                          &::syslog('info',"Received SIGHUP, re-reading config and clearing document cache!");
213                                  }                                          
214                                                                            Meteor::Config->readConfig();
215                                  if($::USR1)                                          Meteor::Config->updateConfig();
216                                  {                                          
217                                          $::USR1=0;                                          Meteor::Document->clearDocuments()
218                                                                            }
219                                          &::syslog('info',"Received SIGUSR1, clearing channel buffers!");                                  
220                                                                            if($::USR1)
221                                          Meteor::Channel->clearAllBuffers();                                  {
222                                  }                                          $::USR1=0;
223                                                                            
224                                  if($::USR2)                                          &::syslog('info',"Received SIGUSR1, clearing channel buffers!");
225                                  {                                          
226                                          $::USR2=0;                                          Meteor::Channel->clearAllBuffers();
227                                                                            }
228                                          &::syslog('info',"Received SIGUSR2, clearing document cache!");                                  
229                                                                            if($::USR2)
230                                          Meteor::Document->clearDocuments()                                  {
231                                  }                                          $::USR2=0;
232                                                                            
233                                  my $t=time;                                          &::syslog('info',"Received SIGUSR2, clearing document cache!");
234                                  if($t>$lastAgeCheck+$AGE_CHECK_INTERVALL)                                          
235                                  {                                          Meteor::Document->clearDocuments()
236                                          my $minTimeStap=time-$::CONF{'MaxMessageAge'};                                  }
237                                          Meteor::Channel->trimMessageStoresByTimestamp($minTimeStap);                                  
238                                          $lastAgeCheck=time;                                  my $t=time;
239                                          $t=$lastAgeCheck;                                  if($t>$lastAgeCheck+$AGE_CHECK_INTERVALL)
240                                                                            {
241                                          Meteor::Subscriber->checkPersistentConnectionsForMaxTime();                                          my $minTimeStap=time-$::CONF{'MaxMessageAge'};
242                                  }                                          Meteor::Channel->trimMessageStoresByTimestamp($minTimeStap);
243                                                                            $lastAgeCheck=time;
244                                  if(defined($nextPing) && $nextPing<=$t)                                          $t=$lastAgeCheck;
245                                  {                                          
246                                          $nextPing=undef;                                          Meteor::Subscriber->checkPersistentConnectionsForMaxTime();
247                                                                            }
248                                          Meteor::Subscriber->pingPersistentConnections();                                  
249                                                                            if(defined($nextPing) && $nextPing<=$t)
250                                          if(exists($::CONF{'MaxMessageAge'}) && $::CONF{'MaxMessageAge'}>2)                                  {
251                                          {                                          $nextPing=undef;
252                                                  $nextPing=$::CONF{'PingInterval'}+time;                                          
253                                          }                                          Meteor::Subscriber->pingPersistentConnections();
254                                  }                                          
255                          }                                          if(exists($::CONF{'MaxMessageAge'}) && $::CONF{'MaxMessageAge'}>2)
256                  };                                          {
257                  unless($::TERM)                                                  $nextPing=$::CONF{'PingInterval'}+time;
258                  {                                          }
259                          &::syslog('alert',"$::PGM loop died (will restart in 2 seconds): $@");                                  }
260                          sleep(2);                          }
261                  }                  };
262          }                  unless($::TERM)
263                            {
264          #                          &::syslog('alert',"$::PGM loop died (will restart in 2 seconds): $@");
265          # Proper shutdown                          sleep(2);
266          #                  }
267          if($::TERM)          }
268          {          
269                  &::syslog('info',"Received SIGTERM, begin shutdown!");          #
270                            # Proper shutdown
271                  $subscriberServer->close();          #
272                  $controlServer->close();          if($::TERM)
273                            {
274                  unlink("/var/run/$::PGM.pid") unless($::CONF{'Debug'});                  &::syslog('info',"Received SIGTERM, begin shutdown!");
275                                    
276                  Meteor::Connection->closeAllConnections();                  $subscriberServer->close();
277                                    $controlServer->close();
278                  my $timoutAt=time+$MAX_EXIT_DELAY;                  
279                                    unlink("/var/run/$::PGM.pid") unless($::CONF{'Debug'});
280                  while(Meteor::Connection->connectionCount() && time<$timoutAt)                  
281                  {                  Meteor::Connection->closeAllConnections();
282                          my $rVec='';                  
283                          my $wVec='';                  my $timoutAt=time+$MAX_EXIT_DELAY;
284                          my $eVec='';                  
285                                            while(Meteor::Connection->connectionCount() && time<$timoutAt)
286                          my $rout;                  {
287                          my $wout;                          my $rVec='';
288                          my $eout;                          my $wVec='';
289                                                    my $eVec='';
290                          Meteor::Connection->addAllHandleBits(\$rVec,\$wVec,\$eVec);                          
291                                                    my $rout;
292                          my $result=&Meteor::Socket::sselect($rout=$rVec,$wout=$wVec,$eout=$eVec,$timoutAt-time);                          my $wout;
293                                                    my $eout;
294                          if($result>0)                          
295                          {                          Meteor::Connection->addAllHandleBits(\$rVec,\$wVec,\$eVec);
296                                  Meteor::Connection->checkAllHandleBits($rout,$wout,$eout);                          
297                          }                          my $result=&Meteor::Socket::sselect($rout=$rVec,$wout=$wVec,$eout=$eVec,$timoutAt-time);
298                  }                          
299                                            if($result>0)
300                  if(my $cnt=Meteor::Connection->connectionCount())                          {
301                  {                                  Meteor::Connection->checkAllHandleBits($rout,$wout,$eout);
302                          &::syslog('info',"$cnt client(s) unresponsive, will shutdown anyway");                          }
303                                            }
304                          exit(1);                  
305                  }                  if(my $cnt=Meteor::Connection->connectionCount())
306                                    {
307                  &::syslog('info',"shutdown succeeded");                          &::syslog('info',"$cnt client(s) unresponsive, will shutdown anyway");
308                                            
309                  exit(0);                          exit(1);
310          }                  }
311                            
312          &::syslog('emerg',"$::PGM loop exited");                  &::syslog('info',"shutdown succeeded");
313                    
314  1;                  exit(0);
315            }
316            
317            &::syslog('emerg',"$::PGM loop exited");
318    
319    1;
320  ############################################################################EOF  ############################################################################EOF

Legend:
Removed from v.5  
changed lines
  Added in v.9

  ViewVC Help
Powered by ViewVC 1.1.26