blob: 0878de110df4e707f23c8226fa3e8af130b69360 [file] [log] [blame]
Benjamin Petersone711caf2008-06-11 16:44:04 +00001#
2# Example where a pool of http servers share a single listening socket
3#
4# On Windows this module depends on the ability to pickle a socket
5# object so that the worker processes can inherit a copy of the server
6# object. (We import `multiprocessing.reduction` to enable this pickling.)
7#
8# Not sure if we should synchronize access to `socket.accept()` method by
9# using a process-shared lock -- does not seem to be necessary.
10#
Benjamin Peterson4469d0c2008-11-30 22:46:23 +000011# Copyright (c) 2006-2008, R Oudkerk
12# All rights reserved.
13#
Benjamin Petersone711caf2008-06-11 16:44:04 +000014
15import os
16import sys
17
18from multiprocessing import Process, current_process, freeze_support
Christian Heimesaae1b702008-11-28 11:23:26 +000019from http.server import HTTPServer
20from http.server import SimpleHTTPRequestHandler
Benjamin Petersone711caf2008-06-11 16:44:04 +000021
22if sys.platform == 'win32':
23 import multiprocessing.reduction # make sockets pickable/inheritable
24
25
26def note(format, *args):
Benjamin Peterson58ea9fe2008-08-19 19:17:39 +000027 sys.stderr.write('[%s]\t%s\n' % (current_process().name, format%args))
Benjamin Petersone711caf2008-06-11 16:44:04 +000028
29
30class RequestHandler(SimpleHTTPRequestHandler):
31 # we override log_message() to show which process is handling the request
32 def log_message(self, format, *args):
33 note(format, *args)
34
35def serve_forever(server):
36 note('starting server')
37 try:
38 server.serve_forever()
39 except KeyboardInterrupt:
40 pass
41
42
43def runpool(address, number_of_processes):
44 # create a single server object -- children will each inherit a copy
45 server = HTTPServer(address, RequestHandler)
46
47 # create child processes to act as workers
48 for i in range(number_of_processes-1):
49 Process(target=serve_forever, args=(server,)).start()
50
51 # main process also acts as a worker
52 serve_forever(server)
53
54
55def test():
56 DIR = os.path.join(os.path.dirname(__file__), '..')
57 ADDRESS = ('localhost', 8000)
58 NUMBER_OF_PROCESSES = 4
59
Christian Heimesaae1b702008-11-28 11:23:26 +000060 print('Serving at http://%s:%d using %d worker processes' % \
61 (ADDRESS[0], ADDRESS[1], NUMBER_OF_PROCESSES))
62 print('To exit press Ctrl-' + ['C', 'Break'][sys.platform=='win32'])
Benjamin Petersone711caf2008-06-11 16:44:04 +000063
64 os.chdir(DIR)
65 runpool(ADDRESS, NUMBER_OF_PROCESSES)
66
67
68if __name__ == '__main__':
69 freeze_support()
70 test()