4
from landscape.lib.amp import (
5
MethodCallProtocol, MethodCallFactory, RemoteObjectConnector)
8
class ComponentProtocol(MethodCallProtocol):
9
"""Communication protocol between the various Landscape components.
11
It can be used both as server-side protocol for exposing the methods of a
12
certain Landscape component, or as client-side protocol for connecting to
13
another Landscape component we want to call the methods of.
15
methods = ["ping", "exit"]
19
class ComponentProtocolFactory(MethodCallFactory):
21
protocol = ComponentProtocol
25
class RemoteComponentConnector(RemoteObjectConnector):
26
"""Utility superclass for creating connections with a Landscape component.
28
@cvar component: The class of the component to connect to, it is expected
29
to define a C{name} class attribute, which will be used to find out
30
the socket to use. It must be defined by sub-classes.
33
factory = ComponentProtocolFactory
35
def __init__(self, reactor, config, *args, **kwargs):
37
@param reactor: A L{TwistedReactor} object.
38
@param config: A L{LandscapeConfiguration}.
39
@param args: Positional arguments for protocol factory constructor.
40
@param kwargs: Keyword arguments for protocol factory constructor.
42
@see: L{MethodCallClientFactory}.
44
self._twisted_reactor = reactor
45
socket = os.path.join(config.sockets_path,
46
self.component.name + ".sock")
47
super(RemoteComponentConnector, self).__init__(
48
self._twisted_reactor._reactor, socket, *args, **kwargs)
50
def connect(self, max_retries=None, factor=None, quiet=False):
51
"""Connect to the remote Landscape component.
53
If the connection is lost after having been established, and then
54
it is established again by the reconnect mechanism, an event will
57
@param max_retries: If given, the connector will keep trying to connect
58
up to that number of times, if the first connection attempt fails.
59
@param factor: Optionally a float indicating by which factor the
60
delay between subsequent retries should increase. Smaller values
61
result in a faster reconnection attempts pace.
62
@param quiet: A boolean indicating whether to log errors.
65
def fire_reconnect(remote):
66
self._twisted_reactor.fire("%s-reconnect" %
69
def connected(remote):
70
self._factory.add_notifier(fire_reconnect)
73
def log_error(failure):
74
logging.error("Error while connecting to %s", self.component.name)
77
result = super(RemoteComponentConnector, self).connect(
78
max_retries=max_retries, factor=factor)
80
result.addErrback(log_error)
81
result.addCallback(connected)
85
class RemoteComponentsRegistry(object):
87
A global registry for looking up Landscape component connectors by name.
94
"""Get the connector class for the given Landscape component.
96
@param name: Name of the Landscape component we want to connect to, for
97
instance C{monitor} or C{manager}.
99
return cls._by_name[name]
102
def register(cls, connector_class):
103
"""Register a connector for a Landscape component.
105
@param connector_class: A sub-class of L{RemoteComponentConnector}
106
that can be used to connect to a certain component.
108
cls._by_name[connector_class.component.name] = connector_class