Merge lp:~radix/landscape-client/fix-landscape-client-startup into lp:~landscape/landscape-client/trunk

Proposed by Christopher Armstrong
Status: Merged
Approved by: Christopher Armstrong
Approved revision: 677
Merged at revision: 678
Proposed branch: lp:~radix/landscape-client/fix-landscape-client-startup
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 97 lines (+16/-35)
3 files modified
landscape/amp.py (+0/-26)
landscape/broker/amp.py (+13/-6)
landscape/broker/server.py (+3/-3)
To merge this branch: bzr merge lp:~radix/landscape-client/fix-landscape-client-startup
Reviewer Review Type Date Requested Status
Alberto Donato (community) Approve
Free Ekanayaka (community) Approve
Review via email: mp+164045@code.launchpad.net

Commit message

Get rid of implicit population of the components registry; it's now explicitly created in a function, and used directly when it's needed.

Description of the change

Unfortunately no tests with this one, but it's an almost-pure code refactor.

Basically, the module that happened to populate the global registry of components wasn't being imported any more. I decided to get rid of the global registry entirely as a solution :) now there's just a function that returns the registry (as a dict) when called. now there's no more dependency on import ordering.

To post a comment you must log in.
Revision history for this message
Free Ekanayaka (free.ekanayaka) wrote :

Looks good! +1

[1]

+
+def get_component_registry():
+ return {
+ "broker": RemoteBrokerConnector,
+ "client": RemoteClientConnector,
+ "monitor": RemoteMonitorConnector,
+ "manager": RemoteManagerConnector
+ }

You could use the "name" class attribute of the "component" class attribute, to avoid duplication, e.g.:

return {
    RemoteBrokerConnector.component.name: RemoteBrokerConnector,
    // etc.
}

Later on I believe we could get rid of the ComponentConnector sub-classes too relatively easy (as you did for the ComponentPublisher-based ones), but it'd probably require dropping the RemoteBroker class as pre-requisite. Its two methods could be moved to the Monitor/Manager classes where they are used (just thinking loud).

[2]

+ from landscape.broker.amp import get_component_registry
+ self.connectors_registry = get_component_registry()

I believe one reason for which we had the ComponentRegistry was to avoid circular imports like this. So it'd be great to have a way of avoiding dependency on import ordering while still not introducing circular imports (maybe dropping the ComponentConnector sub-classes will do it, not sure).

review: Approve
Revision history for this message
Alberto Donato (ack) wrote :

+1, looks good!

#1:
+def get_component_registry():
+ return {
+ "broker": RemoteBrokerConnector,
+ "client": RemoteClientConnector,
+ "monitor": RemoteMonitorConnector,
+ "manager": RemoteManagerConnector
+ }

You could write this as

+COMPONENTS = [
+ RemoteBrokerConnector, RemoteClientConnector, RemoteMonitorConnector, RemoteManagerConnector]
+
+def get_component_registry():
+ return dict(
+ (connector_class.component.name, connector_class)
+ for connector_class in COMPONENTS)

#2:
landscape/broker/server.py:305:1: W391 blank line at end of file

review: Approve
677. By Christopher Armstrong

Address comments:
 - don't duplicate name information in get_component_registry
 - lint

Revision history for this message
Christopher Armstrong (radix) wrote :

free [1] fixed

free [2]

I actually almost removed ComponentConnector subclasses, after my branch to remove the ComponentPublisher subclasses. It was a bit trickier than I wanted to get into at the time, mostly because it involved updating watchdog and configuration code, as well as this registry code. Maybe I'll take another look at it before I leave.

ack [1] fixed
ack [2] fixed

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'landscape/amp.py'
--- landscape/amp.py 2013-05-14 22:57:15 +0000
+++ landscape/amp.py 2013-05-16 16:41:25 +0000
@@ -151,31 +151,5 @@
151 self._connector = None151 self._connector = None
152152
153153
154class ComponentsRegistry(object):
155 """
156 A global registry for looking up Landscape component connectors by name.
157 """
158
159 _by_name = {}
160
161 @classmethod
162 def get(cls, name):
163 """Get the connector class for the given Landscape component.
164
165 @param name: Name of the Landscape component we want to connect to, for
166 instance C{monitor} or C{manager}.
167 """
168 return cls._by_name[name]
169
170 @classmethod
171 def register(cls, connector_class):
172 """Register a connector for a Landscape component.
173
174 @param connector_class: A sub-class of L{ComponentConnector}
175 that can be used to connect to a certain component.
176 """
177 cls._by_name[connector_class.component.name] = connector_class
178
179
180def _get_socket_path(component, config):154def _get_socket_path(component, config):
181 return os.path.join(config.sockets_path, component.name + ".sock")155 return os.path.join(config.sockets_path, component.name + ".sock")
182156
=== modified file 'landscape/broker/amp.py'
--- landscape/broker/amp.py 2013-05-07 22:47:06 +0000
+++ landscape/broker/amp.py 2013-05-16 16:41:25 +0000
@@ -1,8 +1,7 @@
1from twisted.internet.defer import maybeDeferred, execute, succeed1from twisted.internet.defer import maybeDeferred, execute, succeed
22
3from landscape.lib.amp import RemoteObject, MethodCallArgument3from landscape.lib.amp import RemoteObject, MethodCallArgument
4from landscape.amp import (ComponentConnector, ComponentsRegistry,4from landscape.amp import ComponentConnector, get_remote_methods
5 get_remote_methods)
6from landscape.broker.server import BrokerServer5from landscape.broker.server import BrokerServer
7from landscape.broker.client import BrokerClient6from landscape.broker.client import BrokerClient
8from landscape.monitor.monitor import Monitor7from landscape.monitor.monitor import Monitor
@@ -90,7 +89,15 @@
9089
91 component = Manager90 component = Manager
9291
93ComponentsRegistry.register(RemoteBrokerConnector)92
94ComponentsRegistry.register(RemoteClientConnector)93def get_component_registry():
95ComponentsRegistry.register(RemoteMonitorConnector)94 """Get a mapping of component name to connectors, for all components."""
96ComponentsRegistry.register(RemoteManagerConnector)95 all_connectors = [
96 RemoteBrokerConnector,
97 RemoteClientConnector,
98 RemoteMonitorConnector,
99 RemoteManagerConnector
100 ]
101 return dict(
102 (connector.component.name, connector)
103 for connector in all_connectors)
97104
=== modified file 'landscape/broker/server.py'
--- landscape/broker/server.py 2013-05-14 22:57:15 +0000
+++ landscape/broker/server.py 2013-05-16 16:41:25 +0000
@@ -3,9 +3,8 @@
3from twisted.internet.defer import Deferred3from twisted.internet.defer import Deferred
44
5from landscape.lib.twisted_util import gather_results5from landscape.lib.twisted_util import gather_results
6from landscape.amp import ComponentsRegistry6from landscape.amp import remote
7from landscape.manager.manager import FAILED7from landscape.manager.manager import FAILED
8from landscape.amp import remote
98
109
11def event(method):10def event(method):
@@ -38,10 +37,11 @@
38 @param message_store: The broker's L{MessageStore}.37 @param message_store: The broker's L{MessageStore}.
39 """38 """
40 name = "broker"39 name = "broker"
41 connectors_registry = ComponentsRegistry
4240
43 def __init__(self, config, reactor, exchange, registration,41 def __init__(self, config, reactor, exchange, registration,
44 message_store, pinger):42 message_store, pinger):
43 from landscape.broker.amp import get_component_registry
44 self.connectors_registry = get_component_registry()
45 self._config = config45 self._config = config
46 self._reactor = reactor46 self._reactor = reactor
47 self._exchanger = exchange47 self._exchanger = exchange

Subscribers

People subscribed via source and target branches

to all changes: