/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (hide annotations)
Mon Nov 20 17:59:30 2006 UTC (12 years, 9 months ago) by andrew.betts
File size: 7095 byte(s)
Initial import
1 andrew.betts 3 #!/usr/bin/perl -w
2     ###############################################################################
3     # Copyright 2006 BITart Gerd Knops, All rights reserved.
4     #
5     # Project : Meteor
6     # File : meteord
7     # Author : Gerd Knops gerti@BITart.com
8     #
9     ###############################################################################
10     #
11     # History:
12     # 060821 Creation of file
13     #
14     ###############################################################################
15     #
16     # Description:
17     # The Meteor daemon
18     #
19     # $Id:$
20     #
21     ###############################################################################
22     #
23     # DISCLAIMER
24     #
25     # BITart and Gerd Knops make no warranties, representations or commitments
26     # with regard to the contents of this software. BITart and Gerd Knops
27     # specifically disclaim any and all warranties, whether express, implied or
28     # statutory, including, but not limited to, any warranty of merchantability
29     # or fitness for a particular purpose, and non-infringement. Under no
30     # circumstances will BITart or Gerd Knops be liable for loss of data,
31     # special, incidental or consequential damages out of the use of this
32     # software, even if those damages were foreseeable, or BITart or Gerd Knops
33     # was informed of their potential.
34     #
35     ###############################################################################
36     # Configuration
37     ###############################################################################
38    
39     use strict;
40    
41     use Meteor::Syslog;
42    
43     use Meteor::Socket;
44     use Meteor::Connection;
45     use Meteor::Controller;
46     use Meteor::Subscriber;
47     use Meteor::Channel;
48     use Meteor::Document;
49     use Meteor::Config;
50    
51     $::CRLF="\r\n"; # Line separator to be used throughout all modules
52    
53     our $CONTROL_QUEUE_SIZE=5;
54     our $SUBSCRIBER_QUEUE_SIZE=20;
55    
56     our $MAIN_LOOP_TIMEOUT=60;
57     our $AGE_CHECK_INTERVALL=60;
58    
59     our $MAX_EXIT_DELAY=120;
60    
61     ###############################################################################
62     # Main
63     ###############################################################################
64    
65     #
66     # Program name
67     #
68     $::PGM=$0;
69     $::PGM=~s/^.*\///;
70    
71     #
72     # Handle command line options and config file
73     #
74     Meteor::Config->setCommandLineParameters(@ARGV);
75    
76     #
77     # Do something about warn and die
78     #
79     unless($::CONF{'Debug'})
80     {
81     $SIG{'__WARN__'}=\&Meteor::Syslog::myWarn;
82     $SIG{'__DIE__'}=\&Meteor::Syslog::myDie;
83     }
84    
85     &::syslog('info',"$::PGM launched!");
86    
87     #
88     # Daemonize
89     #
90     {
91     $0="$::PGM daemon";
92    
93     unless($::CONF{'Debug'})
94     {
95     # close standard file descriptors
96     close(STDIN);
97     close(STDOUT);
98     close(STDERR);
99     chdir("/");
100     umask(0);
101     # fork and exit parent
102     exit if fork;
103     setpgrp(0, $$) if defined $SIG{TTOU};
104     $SIG{TTOU}='ignore' if defined $SIG{TTOU};
105    
106     # Avoid 'stdin reopened for output' warning with newer perls
107     open(NULL,'/dev/null');
108     <NULL> if(0);
109    
110     open(OUT,">/var/run/$::PGM.pid");
111     print OUT "$$\n";
112     close(OUT);
113     }
114     else
115     {
116     print "$::PGM PID: $$\n";
117     }
118     }
119    
120     #
121     # Signal handlers
122     #
123     $::HUP=$::TERM=$::USR1=$::USR2=0;
124     $SIG{'HUP'}=sub{$::HUP=1};
125     $SIG{'TERM'}=sub{$::TERM=1};
126     $SIG{'USR1'}=sub{$::USR1=1};
127     $SIG{'USR2'}=sub{$::USR2=1};
128    
129     #
130     # Run server
131     #
132     my $con_counter=0;
133     my $con;
134    
135     my $controlServer=Meteor::Socket->newServer(
136     $::CONF{'ControllerPort'},
137     $CONTROL_QUEUE_SIZE,
138     $::CONF{'ControllerIP'}
139     );
140     my $controlServerFN=$controlServer->fileno();
141    
142     my $subscriberServer=Meteor::Socket->newServer(
143     $::CONF{'SubscriberPort'},
144     $SUBSCRIBER_QUEUE_SIZE,
145     $::CONF{'SubscriberIP'}
146     );
147     my $subscriberServerFN=$subscriberServer->fileno();
148    
149     my $serverVector='';
150     vec($serverVector,$controlServerFN,1)=1;
151     vec($serverVector,$subscriberServerFN,1)=1;
152    
153     my $lastAgeCheck=time;
154    
155     my $nextPing=undef;
156     if(exists($::CONF{'PingInterval'}) && $::CONF{'PingInterval'}>2)
157     {
158     $nextPing=$::CONF{'PingInterval'}+$lastAgeCheck;
159     }
160    
161     while(!$::TERM)
162     {
163     eval
164     {
165     while(!$::TERM)
166     {
167     my $rVec=$serverVector;
168     my $wVec='';
169     my $eVec='';
170    
171     my $rout;
172     my $wout;
173     my $eout;
174    
175     Meteor::Connection->addAllHandleBits(\$rVec,\$wVec,\$eVec);
176    
177     my $timeout=$MAIN_LOOP_TIMEOUT;
178     if(defined($nextPing))
179     {
180     $timeout=$nextPing-time;
181     }
182    
183     my $result=0;
184     if($timeout>0)
185     {
186     $result=&Meteor::Socket::sselect($rout=$rVec,$wout=$wVec,$eout=$eVec,$timeout);
187     }
188    
189     if($result>0)
190     {
191     if(vec($rout,$controlServerFN,1))
192     {
193     Meteor::Controller->newFromServer($controlServer);
194     }
195     if(vec($rout,$subscriberServerFN,1))
196     {
197     Meteor::Subscriber->newFromServer($subscriberServer);
198     }
199    
200     Meteor::Connection->checkAllHandleBits($rout,$wout,$eout);
201     }
202     elsif($result<0)
203     {
204     &::syslog('crit',"Select failed: $!");
205     sleep(30);
206     }
207    
208     if($::HUP)
209     {
210     $::HUP=0;
211    
212     &::syslog('info',"Received SIGHUP, re-reading config and clearing document cache!");
213    
214     Meteor::Config->readConfig();
215     Meteor::Config->updateConfig();
216    
217     Meteor::Document->clearDocuments()
218     }
219    
220     if($::USR1)
221     {
222     $::USR1=0;
223    
224     &::syslog('info',"Received SIGUSR1, clearing channel buffers!");
225    
226     Meteor::Channel->clearAllBuffers();
227     }
228    
229     if($::USR2)
230     {
231     $::USR2=0;
232    
233     &::syslog('info',"Received SIGUSR2, clearing document cache!");
234    
235     Meteor::Document->clearDocuments()
236     }
237    
238     my $t=time;
239     if($t>$lastAgeCheck+$AGE_CHECK_INTERVALL)
240     {
241     my $minTimeStap=time-$::CONF{'MaxMessageAge'};
242     Meteor::Channel->trimMessageStoresByTimestamp($minTimeStap);
243     $lastAgeCheck=time;
244     $t=$lastAgeCheck;
245    
246     Meteor::Subscriber->checkPersistentConnectionsForMaxTime();
247     }
248    
249     if(defined($nextPing) && $nextPing<=$t)
250     {
251     $nextPing=undef;
252    
253     Meteor::Subscriber->pingPersistentConnections();
254    
255     if(exists($::CONF{'MaxMessageAge'}) && $::CONF{'MaxMessageAge'}>2)
256     {
257     $nextPing=$::CONF{'PingInterval'}+time;
258     }
259     }
260     }
261     };
262     unless($::TERM)
263     {
264     &::syslog('alert',"$::PGM loop died (will restart in 2 seconds): $@");
265     sleep(2);
266     }
267     }
268    
269     #
270     # Proper shutdown
271     #
272     if($::TERM)
273     {
274     &::syslog('info',"Received SIGTERM, begin shutdown!");
275    
276     $subscriberServer->close();
277     $controlServer->close();
278    
279     unlink("/var/run/$::PGM.pid") unless($::CONF{'Debug'});
280    
281     Meteor::Connection->closeAllConnections();
282    
283     my $timoutAt=time+$MAX_EXIT_DELAY;
284    
285     while(Meteor::Connection->connectionCount() && time<$timoutAt)
286     {
287     my $rVec='';
288     my $wVec='';
289     my $eVec='';
290    
291     my $rout;
292     my $wout;
293     my $eout;
294    
295     Meteor::Connection->addAllHandleBits(\$rVec,\$wVec,\$eVec);
296    
297     my $result=&Meteor::Socket::sselect($rout=$rVec,$wout=$wVec,$eout=$eVec,$timoutAt-time);
298    
299     if($result>0)
300     {
301     Meteor::Connection->checkAllHandleBits($rout,$wout,$eout);
302     }
303     }
304    
305     if(my $cnt=Meteor::Connection->connectionCount())
306     {
307     &::syslog('info',"$cnt client(s) unresponsive, will shutdown anyway");
308    
309     exit(1);
310     }
311    
312     &::syslog('info',"shutdown succeeded");
313    
314     exit(0);
315     }
316    
317     &::syslog('emerg',"$::PGM loop exited");
318    
319     1;
320     ############################################################################EOF

  ViewVC Help
Powered by ViewVC 1.1.26