~markmc/nova/flat-dhcp-without-bridge-iface

« back to all changes in this revision

Viewing changes to nova/service.py

  • Committer: Tarmac
  • Author(s): Vishvananda Ishaya
  • Date: 2011-08-19 00:04:02 UTC
  • mfrom: (1450.4.8 united-launch-strategy)
  • Revision ID: tarmac-20110819000402-dp9hs0eosmunud8x
Makes all of the binary services launch using the same strategy.
 * Removes helper methods from utils for loading flags and logging
 * Changes service.serve to use Launcher
 * Changes service.wait to actually wait for all the services to exit
 * Changes nova-api to explicitly load flags and logging and use service.serve
 * Fixes the annoying IOError when /etc/nova/nova.conf doesn't exist

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
"""Generic Node baseclass for all workers that run on hosts."""
21
21
 
22
22
import inspect
23
 
import multiprocessing
24
23
import os
25
24
 
 
25
import eventlet
26
26
import greenlet
27
27
 
28
 
from eventlet import greenthread
29
 
 
30
28
from nova import context
31
29
from nova import db
32
30
from nova import exception
69
67
        self._services = []
70
68
 
71
69
    @staticmethod
72
 
    def run_service(service):
73
 
        """Start and wait for a service to finish.
74
 
 
75
 
        :param service: Service to run and wait for.
76
 
        :returns: None
77
 
 
78
 
        """
79
 
        service.start()
80
 
        try:
81
 
            service.wait()
82
 
        except KeyboardInterrupt:
83
 
            service.stop()
84
 
 
85
 
    def launch_service(self, service):
86
 
        """Load and start the given service.
87
 
 
88
 
        :param service: The service you would like to start.
89
 
        :returns: None
90
 
 
91
 
        """
92
 
        process = multiprocessing.Process(target=self.run_service,
93
 
                                          args=(service,))
94
 
        process.start()
95
 
        self._services.append(process)
 
70
    def run_server(server):
 
71
        """Start and wait for a server to finish.
 
72
 
 
73
        :param service: Server to run and wait for.
 
74
        :returns: None
 
75
 
 
76
        """
 
77
        server.start()
 
78
        server.wait()
 
79
 
 
80
    def launch_server(self, server):
 
81
        """Load and start the given server.
 
82
 
 
83
        :param server: The server you would like to start.
 
84
        :returns: None
 
85
 
 
86
        """
 
87
        gt = eventlet.spawn(self.run_server, server)
 
88
        self._services.append(gt)
96
89
 
97
90
    def stop(self):
98
91
        """Stop all services which are currently running.
101
94
 
102
95
        """
103
96
        for service in self._services:
104
 
            if service.is_alive():
105
 
                service.terminate()
 
97
            service.kill()
106
98
 
107
99
    def wait(self):
108
100
        """Waits until all services have been stopped, and then returns.
111
103
 
112
104
        """
113
105
        for service in self._services:
114
 
            service.join()
 
106
            try:
 
107
                service.wait()
 
108
            except greenlet.GreenletExit:
 
109
                pass
115
110
 
116
111
 
117
112
class Service(object):
118
 
    """Base class for workers that run on hosts."""
 
113
    """Service object for binaries running on hosts.
 
114
 
 
115
    A service takes a manager and enables rpc by listening to queues based
 
116
    on topic. It also periodically runs tasks on the manager and reports
 
117
    it state to the database services table."""
119
118
 
120
119
    def __init__(self, host, binary, topic, manager, report_interval=None,
121
120
                 periodic_interval=None, *args, **kwargs):
173
172
            finally:
174
173
                consumer_set.close()
175
174
 
176
 
        self.consumer_set_thread = greenthread.spawn(_wait)
 
175
        self.consumer_set_thread = eventlet.spawn(_wait)
177
176
 
178
177
        if self.report_interval:
179
178
            pulse = utils.LoopingCall(self.report_state)
293
292
    """Provides ability to launch API from a 'paste' configuration."""
294
293
 
295
294
    def __init__(self, name, loader=None):
296
 
        """Initialize, but do not start the WSGI service.
 
295
        """Initialize, but do not start the WSGI server.
297
296
 
298
 
        :param name: The name of the WSGI service given to the loader.
 
297
        :param name: The name of the WSGI server given to the loader.
299
298
        :param loader: Loads the WSGI application using the given name.
300
299
        :returns: None
301
300
 
339
338
        self.server.wait()
340
339
 
341
340
 
342
 
def serve(*services):
343
 
    try:
344
 
        if not services:
345
 
            services = [Service.create()]
346
 
    except Exception:
347
 
        logging.exception('in Service.create()')
348
 
        raise
349
 
    finally:
350
 
        # After we've loaded up all our dynamic bits, check
351
 
        # whether we should print help
352
 
        flags.DEFINE_flag(flags.HelpFlag())
353
 
        flags.DEFINE_flag(flags.HelpshortFlag())
354
 
        flags.DEFINE_flag(flags.HelpXMLFlag())
355
 
        FLAGS.ParseNewFlags()
356
 
 
357
 
    name = '_'.join(x.binary for x in services)
358
 
    logging.debug(_('Serving %s'), name)
 
341
# NOTE(vish): the global launcher is to maintain the existing
 
342
#             functionality of calling service.serve +
 
343
#             service.wait
 
344
_launcher = None
 
345
 
 
346
 
 
347
def serve(*servers):
 
348
    global _launcher
 
349
    if not _launcher:
 
350
        _launcher = Launcher()
 
351
    for server in servers:
 
352
        _launcher.launch_server(server)
 
353
 
 
354
 
 
355
def wait():
 
356
    # After we've loaded up all our dynamic bits, check
 
357
    # whether we should print help
 
358
    flags.DEFINE_flag(flags.HelpFlag())
 
359
    flags.DEFINE_flag(flags.HelpshortFlag())
 
360
    flags.DEFINE_flag(flags.HelpXMLFlag())
 
361
    FLAGS.ParseNewFlags()
359
362
    logging.debug(_('Full set of FLAGS:'))
360
363
    for flag in FLAGS:
361
364
        flag_get = FLAGS.get(flag, None)
362
365
        logging.debug('%(flag)s : %(flag_get)s' % locals())
363
 
 
364
 
    for x in services:
365
 
        x.start()
366
 
 
367
 
 
368
 
def wait():
369
 
    while True:
370
 
        greenthread.sleep(5)
 
366
    try:
 
367
        _launcher.wait()
 
368
    except KeyboardInterrupt:
 
369
        _launcher.stop()