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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26