~free.ekanayaka/landscape-client/lucid-1.5.4-0ubuntu0.10.04.0

« back to all changes in this revision

Viewing changes to landscape/amp.py

  • Committer: Bazaar Package Importer
  • Author(s): Free Ekanayaka
  • Date: 2010-06-28 18:07:18 UTC
  • mfrom: (1.2.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100628180718-vytyqgbtkiirv5sb
Tags: 1.5.2.1-0ubuntu0.10.04.0
Filter duplicate network interfaces in get_active_interfaces (LP: #597000)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import os
 
2
import logging
 
3
 
 
4
from landscape.lib.amp import (
 
5
    MethodCallProtocol, MethodCallFactory, RemoteObjectConnector)
 
6
 
 
7
 
 
8
class ComponentProtocol(MethodCallProtocol):
 
9
    """Communication protocol between the various Landscape components.
 
10
 
 
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.
 
14
    """
 
15
    methods = ["ping", "exit"]
 
16
    timeout = 60
 
17
 
 
18
 
 
19
class ComponentProtocolFactory(MethodCallFactory):
 
20
 
 
21
    protocol = ComponentProtocol
 
22
    initialDelay = 0.05
 
23
 
 
24
 
 
25
class RemoteComponentConnector(RemoteObjectConnector):
 
26
    """Utility superclass for creating connections with a Landscape component.
 
27
 
 
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.
 
31
    """
 
32
 
 
33
    factory = ComponentProtocolFactory
 
34
 
 
35
    def __init__(self, reactor, config, *args, **kwargs):
 
36
        """
 
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.
 
41
 
 
42
        @see: L{MethodCallClientFactory}.
 
43
        """
 
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)
 
49
 
 
50
    def connect(self, max_retries=None, factor=None, quiet=False):
 
51
        """Connect to the remote Landscape component.
 
52
 
 
53
        If the connection is lost after having been established, and then
 
54
        it is established again by the reconnect mechanism, an event will
 
55
        be fired.
 
56
 
 
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.
 
63
        """
 
64
 
 
65
        def fire_reconnect(remote):
 
66
            self._twisted_reactor.fire("%s-reconnect" %
 
67
                                       self.component.name)
 
68
 
 
69
        def connected(remote):
 
70
            self._factory.add_notifier(fire_reconnect)
 
71
            return remote
 
72
 
 
73
        def log_error(failure):
 
74
            logging.error("Error while connecting to %s", self.component.name)
 
75
            return failure
 
76
 
 
77
        result = super(RemoteComponentConnector, self).connect(
 
78
            max_retries=max_retries, factor=factor)
 
79
        if not quiet:
 
80
            result.addErrback(log_error)
 
81
        result.addCallback(connected)
 
82
        return result
 
83
 
 
84
 
 
85
class RemoteComponentsRegistry(object):
 
86
    """
 
87
    A global registry for looking up Landscape component connectors by name.
 
88
    """
 
89
 
 
90
    _by_name = {}
 
91
 
 
92
    @classmethod
 
93
    def get(cls, name):
 
94
        """Get the connector class for the given Landscape component.
 
95
 
 
96
        @param name: Name of the Landscape component we want to connect to, for
 
97
           instance C{monitor} or C{manager}.
 
98
        """
 
99
        return cls._by_name[name]
 
100
 
 
101
    @classmethod
 
102
    def register(cls, connector_class):
 
103
        """Register a connector for a Landscape component.
 
104
 
 
105
        @param connector_class: A sub-class of L{RemoteComponentConnector}
 
106
            that can be used to connect to a certain component.
 
107
        """
 
108
        cls._by_name[connector_class.component.name] = connector_class