/[meteor]/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 /trunk/meteord

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations)
Thu Dec 14 16:29:42 2006 UTC (12 years, 8 months ago) by knops.gerd
Original Path: googlecode.com/svn/trunk/meteord
File size: 7285 byte(s)
• Change CRLF line endings back to LF only

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 # Main program should call Meteor::Config::setCommandLineParameters(@ARGV),.
10 # Afterwards anybody can access $::CONF{<parameterName>}, where
11 # <parameterName> is any valid parameter (except 'Help') listed in the
12 # @DEFAULTS array below.
13 #
14 ###############################################################################
15 #
16 # This program is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by the Free
18 # Software Foundation; either version 2 of the License, or (at your option)
19 # any later version.
20 #
21 # This program is distributed in the hope that it will be useful, but WITHOUT
22 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
24 # more details.
25 #
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 #
32 ###############################################################################
33
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