Mercurial > p > roundup > code
comparison roundup/scripts/roundup_server.py @ 2848:e8cb25c30ac9
added multiprocess mode "debug" - run single process...
...and don't cache tracker instances or compiled templates;
preload all trackers unless in "debug" mode (thanks donfu)
| author | Alexander Smishlajev <a1s@users.sourceforge.net> |
|---|---|
| date | Tue, 02 Nov 2004 09:07:08 +0000 |
| parents | 46ad912ddd2b |
| children | 37e6ebd5ba29 |
comparison
equal
deleted
inserted
replaced
| 2847:fddbbeb581bc | 2848:e8cb25c30ac9 |
|---|---|
| 15 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 15 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
| 16 # | 16 # |
| 17 | 17 |
| 18 """Command-line script that runs a server over roundup.cgi.client. | 18 """Command-line script that runs a server over roundup.cgi.client. |
| 19 | 19 |
| 20 $Id: roundup_server.py,v 1.71 2004-10-30 08:43:06 a1s Exp $ | 20 $Id: roundup_server.py,v 1.72 2004-11-02 09:07:08 a1s Exp $ |
| 21 """ | 21 """ |
| 22 __docformat__ = 'restructuredtext' | 22 __docformat__ = 'restructuredtext' |
| 23 | 23 |
| 24 import errno, cgi, getopt, os, socket, sys, traceback, urllib | 24 import errno, cgi, getopt, os, socket, sys, traceback, urllib |
| 25 import ConfigParser, BaseHTTPServer, SocketServer, StringIO | 25 import ConfigParser, BaseHTTPServer, SocketServer, StringIO |
| 50 '''.strip())) | 50 '''.strip())) |
| 51 | 51 |
| 52 DEFAULT_PORT = 8080 | 52 DEFAULT_PORT = 8080 |
| 53 | 53 |
| 54 # See what types of multiprocess server are available | 54 # See what types of multiprocess server are available |
| 55 MULTIPROCESS_TYPES = ["none"] | 55 # Note: the order is important. Preferred multiprocess type |
| 56 # is the last element of this list. | |
| 57 # "debug" means "none" + no tracker/template cache | |
| 58 MULTIPROCESS_TYPES = ["debug", "none"] | |
| 56 try: | 59 try: |
| 57 import thread | 60 import thread |
| 58 except ImportError: | 61 except ImportError: |
| 59 pass | 62 pass |
| 60 else: | 63 else: |
| 63 MULTIPROCESS_TYPES.append("fork") | 66 MULTIPROCESS_TYPES.append("fork") |
| 64 DEFAULT_MULTIPROCESS = MULTIPROCESS_TYPES[-1] | 67 DEFAULT_MULTIPROCESS = MULTIPROCESS_TYPES[-1] |
| 65 | 68 |
| 66 class RoundupRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 69 class RoundupRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
| 67 TRACKER_HOMES = {} | 70 TRACKER_HOMES = {} |
| 71 TRACKERS = None | |
| 68 LOG_IPADDRESS = 1 | 72 LOG_IPADDRESS = 1 |
| 73 | |
| 74 def get_tracker(self, name): | |
| 75 """Return a tracker instance for given tracker name""" | |
| 76 # Note: try/except KeyError works faster that has_key() check | |
| 77 # if the key is usually found in the dictionary | |
| 78 # | |
| 79 # Return cached tracker instance if we have a tracker cache | |
| 80 if self.TRACKERS: | |
| 81 try: | |
| 82 return self.TRACKERS[name] | |
| 83 except KeyError: | |
| 84 pass | |
| 85 # No cached tracker. Look for home path. | |
| 86 try: | |
| 87 tracker_home = self.TRACKER_HOMES[name] | |
| 88 except KeyError: | |
| 89 raise client.NotFound | |
| 90 # open the instance | |
| 91 tracker = roundup.instance.open(tracker_home) | |
| 92 # and cache it if we have a tracker cache | |
| 93 if self.TRACKERS: | |
| 94 self.TRACKERS[name] = tracker | |
| 95 return tracker | |
| 69 | 96 |
| 70 def run_cgi(self): | 97 def run_cgi(self): |
| 71 """ Execute the CGI command. Wrap an innner call in an error | 98 """ Execute the CGI command. Wrap an innner call in an error |
| 72 handler so all errors can be caught. | 99 handler so all errors can be caught. |
| 73 """ | 100 """ |
| 156 self.send_header('Location', url) | 183 self.send_header('Location', url) |
| 157 self.end_headers() | 184 self.end_headers() |
| 158 self.wfile.write('Moved Permanently') | 185 self.wfile.write('Moved Permanently') |
| 159 return | 186 return |
| 160 | 187 |
| 161 if self.TRACKER_HOMES.has_key(tracker_name): | |
| 162 tracker_home = self.TRACKER_HOMES[tracker_name] | |
| 163 tracker = roundup.instance.open(tracker_home) | |
| 164 else: | |
| 165 raise client.NotFound | |
| 166 | |
| 167 # figure out what the rest of the path is | 188 # figure out what the rest of the path is |
| 168 if len(l_path) > 2: | 189 if len(l_path) > 2: |
| 169 rest = '/'.join(l_path[2:]) | 190 rest = '/'.join(l_path[2:]) |
| 170 else: | 191 else: |
| 171 rest = '/' | 192 rest = '/' |
| 191 env['SCRIPT_NAME'] = '' | 212 env['SCRIPT_NAME'] = '' |
| 192 env['SERVER_NAME'] = self.server.server_name | 213 env['SERVER_NAME'] = self.server.server_name |
| 193 env['SERVER_PORT'] = str(self.server.server_port) | 214 env['SERVER_PORT'] = str(self.server.server_port) |
| 194 env['HTTP_HOST'] = self.headers['host'] | 215 env['HTTP_HOST'] = self.headers['host'] |
| 195 | 216 |
| 196 # do the roundup thang | 217 # do the roundup thing |
| 218 tracker = self.get_tracker(tracker_name) | |
| 197 tracker.Client(tracker, self, env).main() | 219 tracker.Client(tracker, self, env).main() |
| 198 | 220 |
| 199 def address_string(self): | 221 def address_string(self): |
| 200 if self.LOG_IPADDRESS: | 222 if self.LOG_IPADDRESS: |
| 201 return self.client_address[0] | 223 return self.client_address[0] |
| 374 if self["LOGFILE"]: | 396 if self["LOGFILE"]: |
| 375 # appending, unbuffered | 397 # appending, unbuffered |
| 376 sys.stdout = sys.stderr = open(self["LOGFILE"], 'a', 0) | 398 sys.stdout = sys.stderr = open(self["LOGFILE"], 'a', 0) |
| 377 # we don't want the cgi module interpreting the command-line args ;) | 399 # we don't want the cgi module interpreting the command-line args ;) |
| 378 sys.argv = sys.argv[:1] | 400 sys.argv = sys.argv[:1] |
| 401 # preload all trackers unless we are in "debug" mode | |
| 402 tracker_homes = self.trackers() | |
| 403 if self["MULTIPROCESS"] == "debug": | |
| 404 trackers = None | |
| 405 else: | |
| 406 trackers = dict([(name, roundup.instance.open(home)) | |
| 407 for (name, home) in tracker_homes]) | |
| 379 # build customized request handler class | 408 # build customized request handler class |
| 380 class RequestHandler(RoundupRequestHandler): | 409 class RequestHandler(RoundupRequestHandler): |
| 381 LOG_IPADDRESS = not self["LOG_HOSTNAMES"] | 410 LOG_IPADDRESS = not self["LOG_HOSTNAMES"] |
| 382 TRACKER_HOMES = dict(self.trackers()) | 411 TRACKER_HOMES = dict(tracker_homes) |
| 412 TRACKERS = trackers | |
| 383 # obtain request server class | 413 # obtain request server class |
| 384 if self["MULTIPROCESS"] not in MULTIPROCESS_TYPES: | 414 if self["MULTIPROCESS"] not in MULTIPROCESS_TYPES: |
| 385 print _("Multiprocess mode \"%s\" is not available, " | 415 print _("Multiprocess mode \"%s\" is not available, " |
| 386 "switching to single-process") % self["MULTIPROCESS"] | 416 "switching to single-process") % self["MULTIPROCESS"] |
| 387 self["MULTIPROCESS"] = "none" | 417 self["MULTIPROCESS"] = "none" |
