~khaeru/+junk/ceabdb

« back to all changes in this revision

Viewing changes to ceabdb/Daemon.py

  • Committer: Paul Kishimoto
  • Date: 2008-07-04 17:45:20 UTC
  • Revision ID: mail@paul.kishimoto.name-20080704174520-eo0mfsyva94u6rdx
 * Added BasicServer, BasicRequestHandler classes for common functionality.
 * Lifted a shutdown() method for BasicServer and subclasses from a Python 2.6 patch.
 * Use logging.getLogger(''), especially in classes that will exist in separate threads but also elsewhere for consistency.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
import signal
8
8
import logging
9
9
 
 
10
from threading import Thread
10
11
from . import Config, server, storage
11
12
 
12
13
class Daemon:
 
14
    servers = []
 
15
    server_threads = []
 
16
 
13
17
    def __init__(self):
14
18
        """Initialize the daemon."""
15
19
        self.__dict__.update(Config.items('Daemon'))
33
37
        # Set up logging in daemon thread
34
38
        logging.basicConfig(level=logging.DEBUG,
35
39
            format='%(asctime)s %(levelname)s %(message)s',
36
 
            filename=d.logfile)
37
 
        logging.notice('Daemon spawned.')
 
40
            filename=self.logfile)
 
41
        self.log = logging.getLogger('')
 
42
        self.log.info('Daemon spawned.')
38
43
        # Main loop
39
44
        while self.__alive:
40
45
            # Reload configuration (e.g. after SIGHUP)
46
51
        else:
47
52
            # SIGTERM received. Shutdown.
48
53
            self.__stop()
49
 
            logging.notice('Shutting down.')
 
54
            logging.info('Shutting down.')
50
55
            # Remove PID file
51
56
            os.remove(self.pidfile)
52
 
        return
53
57
 
54
58
    def __daemonize(self):
55
59
        """Detach a process from the controlling terminal and run it in the
102
106
            fp.close()
103
107
        finally:
104
108
            os.umask(umask_save)
105
 
        return       
106
109
 
107
110
    def __signal_handler(self, signum, frame):
108
111
        """Handle signals.
113
116
 
114
117
        """
115
118
        if signum == signal.SIGTERM:
116
 
            logging.notice('Received SIGTERM.')
 
119
            self.log.info('Received SIGTERM.')
117
120
            # Trigger the main loop 'else' clause in __init__()
118
121
            self.__alive = False
119
122
            return
120
123
        if signum == signal.SIGHUP:
121
 
            logging.notice('Received SIGHUP.')
 
124
            self.log.info('Received SIGHUP.')
122
125
            # Stop Servers and close Stores, but leave _running = True.
123
126
            self.__stop()
124
127
            return
125
 
        logging.notice('Received unhandled signal %d' % signum)
 
128
        self.log.info('Received unhandled signal %d' % signum)
126
129
        signal.pause()
127
 
        return
128
130
 
129
131
    def __start(self):
130
 
        logging.notice('Opening store.')
 
132
        self.log.info('Opening store.')
131
133
        # Initialize a data store in the main thread
132
134
        store_type = Config.get('Storage', 'type')
133
 
        self.store = store_types[store_type]()
 
135
        self.store = storage.types[store_type]()
134
136
        # Start servers, each in their own thread
135
 
        for server_type in server_types:
 
137
        for server_type, server_class in server.types.iteritems():
136
138
            try:
137
 
                if bool(Config.get('Server', server_type['name'])):
138
 
                    s = server_type['class']()
 
139
                if bool(eval(Config.get('Server', server_type))):
 
140
                    self.log.info('Starting %s server.' % server_type)
 
141
                    s = server_class()
139
142
                    self.servers.append(s)
140
 
                    t = threading.thread(s.serve_forever)
 
143
                    t = Thread(target=s.serve_forever)
 
144
                    t.start()
141
145
                    self.server_threads.append(t)
142
146
            except NoOptionError:
143
147
                pass
144
 
        return
145
148
 
146
149
    def __stop(self):
147
 
        logging.notice('Shutting down servers.')
148
 
        for s in self.servers:
149
 
            s.shutdown()
150
 
        for t in self.server_threads:
151
 
            t.join()
152
 
        logging.notice('Closing store.')
153
 
        self.store.close()
154
 
        return
 
150
        try:
 
151
            self.log.info('Shutting down servers.')
 
152
            [s.shutdown() for s in self.servers]
 
153
            self.log.info('Joining threads.')
 
154
            [t.join() for t in self.server_threads]
 
155
            self.log.info('Closing store.')
 
156
            self.store.close()
 
157
        except Exception, e:
 
158
            self.log.error(e)
 
159
 
155
160
 
156
161
def start():
157
162
    d = Daemon()