summaryrefslogtreecommitdiffstats
path: root/nova/service.py
diff options
context:
space:
mode:
authorjaypipes@gmail.com <>2010-12-17 11:10:11 -0500
committerjaypipes@gmail.com <>2010-12-17 11:10:11 -0500
commitafae367d63c6d38faa5d9be54725df29c2a5b903 (patch)
treee2282e9bbc6ef6d4c5f339a4fde38127a619f354 /nova/service.py
parentd283922defdda6ede5fa2e09656cd8d411a90096 (diff)
parentcd460a1f661eea7e050891f50a8218fdf24f2c6f (diff)
downloadnova-afae367d63c6d38faa5d9be54725df29c2a5b903.tar.gz
nova-afae367d63c6d38faa5d9be54725df29c2a5b903.tar.xz
nova-afae367d63c6d38faa5d9be54725df29c2a5b903.zip
Merge eventlet and resolve all conflicts
Diffstat (limited to 'nova/service.py')
-rw-r--r--nova/service.py107
1 files changed, 73 insertions, 34 deletions
diff --git a/nova/service.py b/nova/service.py
index 348b1d192..ac30aaceb 100644
--- a/nova/service.py
+++ b/nova/service.py
@@ -17,21 +17,17 @@
# under the License.
"""
-A service is a very thin wrapper around a Manager object. It exposes the
-manager's public methods to other components of the system via rpc. It will
-report state periodically to the database and is responsible for initiating
-any periodic tasts that need to be executed on a given host.
-
-This module contains Service, a generic baseclass for all workers.
+Generic Node baseclass for all workers that run on hosts
"""
import inspect
import logging
import os
+import sys
-from twisted.internet import defer
-from twisted.internet import task
-from twisted.application import service
+from eventlet import event
+from eventlet import greenthread
+from eventlet import greenpool
from nova import context
from nova import db
@@ -50,8 +46,16 @@ flags.DEFINE_integer('periodic_interval', 60,
'seconds between running periodic tasks',
lower_bound=1)
+flags.DEFINE_string('pidfile', None,
+ 'pidfile to use for this service')
+
+
+flags.DEFINE_flag(flags.HelpFlag())
+flags.DEFINE_flag(flags.HelpshortFlag())
+flags.DEFINE_flag(flags.HelpXMLFlag())
+
-class Service(object, service.Service):
+class Service(object):
"""Base class for workers that run on hosts."""
def __init__(self, host, binary, topic, manager, report_interval=None,
@@ -64,8 +68,9 @@ class Service(object, service.Service):
self.periodic_interval = periodic_interval
super(Service, self).__init__(*args, **kwargs)
self.saved_args, self.saved_kwargs = args, kwargs
+ self.timers = []
- def startService(self): # pylint: disable-msg C0103
+ def start(self):
manager_class = utils.import_class(self.manager_class_name)
self.manager = manager_class(host=self.host, *self.saved_args,
**self.saved_kwargs)
@@ -80,26 +85,29 @@ class Service(object, service.Service):
except exception.NotFound:
self._create_service_ref(ctxt)
- conn = rpc.Connection.instance()
+ conn1 = rpc.Connection.instance(new=True)
+ conn2 = rpc.Connection.instance(new=True)
if self.report_interval:
consumer_all = rpc.AdapterConsumer(
- connection=conn,
+ connection=conn1,
topic=self.topic,
proxy=self)
consumer_node = rpc.AdapterConsumer(
- connection=conn,
+ connection=conn2,
topic='%s.%s' % (self.topic, self.host),
proxy=self)
- consumer_all.attach_to_twisted()
- consumer_node.attach_to_twisted()
+ self.timers.append(consumer_all.attach_to_eventlet())
+ self.timers.append(consumer_node.attach_to_eventlet())
- pulse = task.LoopingCall(self.report_state)
+ pulse = utils.LoopingCall(self.report_state)
pulse.start(interval=self.report_interval, now=False)
+ self.timers.append(pulse)
if self.periodic_interval:
- pulse = task.LoopingCall(self.periodic_tasks)
- pulse.start(interval=self.periodic_interval, now=False)
+ periodic = utils.LoopingCall(self.periodic_tasks)
+ periodic.start(interval=self.periodic_interval, now=False)
+ self.timers.append(periodic)
def _create_service_ref(self, context):
service_ref = db.service_create(context,
@@ -143,29 +151,32 @@ class Service(object, service.Service):
report_interval = FLAGS.report_interval
if not periodic_interval:
periodic_interval = FLAGS.periodic_interval
- logging.warn(_("Starting %s node"), topic)
+ logging.warn("Starting %s node", topic)
service_obj = cls(host, binary, topic, manager,
report_interval, periodic_interval)
- # This is the parent service that twistd will be looking for when it
- # parses this file, return it so that we can get it into globals.
- application = service.Application(binary)
- service_obj.setServiceParent(application)
- return application
+ return service_obj
def kill(self):
"""Destroy the service object in the datastore"""
+ self.stop()
try:
db.service_destroy(context.get_admin_context(), self.service_id)
except exception.NotFound:
- logging.warn(_("Service killed that has no database entry"))
+ logging.warn("Service killed that has no database entry")
+
+ def stop(self):
+ for x in self.timers:
+ try:
+ x.stop()
+ except Exception:
+ pass
+ self.timers = []
- @defer.inlineCallbacks
def periodic_tasks(self):
"""Tasks to be run at a periodic interval"""
- yield self.manager.periodic_tasks(context.get_admin_context())
+ self.manager.periodic_tasks(context.get_admin_context())
- @defer.inlineCallbacks
def report_state(self):
"""Update the state of this service in the datastore."""
ctxt = context.get_admin_context()
@@ -173,8 +184,8 @@ class Service(object, service.Service):
try:
service_ref = db.service_get(ctxt, self.service_id)
except exception.NotFound:
- logging.debug(_("The service database object disappeared, "
- "Recreating it."))
+ logging.debug("The service database object disappeared, "
+ "Recreating it.")
self._create_service_ref(ctxt)
service_ref = db.service_get(ctxt, self.service_id)
@@ -185,11 +196,39 @@ class Service(object, service.Service):
# TODO(termie): make this pattern be more elegant.
if getattr(self, "model_disconnected", False):
self.model_disconnected = False
- logging.error(_("Recovered model server connection!"))
+ logging.error("Recovered model server connection!")
# TODO(vish): this should probably only catch connection errors
except Exception: # pylint: disable-msg=W0702
if not getattr(self, "model_disconnected", False):
self.model_disconnected = True
- logging.exception(_("model server went away"))
- yield
+ logging.exception("model server went away")
+
+
+def serve(*services):
+ argv = FLAGS(sys.argv)
+
+ if not services:
+ services = [Service.create()]
+
+ name = '_'.join(x.binary for x in services)
+ logging.debug("Serving %s" % name)
+
+ logging.getLogger('amqplib').setLevel(logging.WARN)
+
+ if FLAGS.verbose:
+ logging.getLogger().setLevel(logging.DEBUG)
+ else:
+ logging.getLogger().setLevel(logging.WARNING)
+
+ logging.debug("Full set of FLAGS:")
+ for flag in FLAGS:
+ logging.debug("%s : %s" % (flag, FLAGS.get(flag, None)))
+
+ for x in services:
+ x.start()
+
+
+def wait():
+ while True:
+ greenthread.sleep(5)