Merge lp:~free.ekanayaka/landscape-client/clones-fixes into lp:~landscape/landscape-client/trunk

Proposed by Free Ekanayaka
Status: Merged
Approved by: Alberto Donato
Approved revision: 446
Merge reported by: Free Ekanayaka
Merged at revision: not available
Proposed branch: lp:~free.ekanayaka/landscape-client/clones-fixes
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 172 lines (+39/-24)
4 files modified
landscape/reactor.py (+15/-3)
landscape/service.py (+7/-2)
landscape/tests/test_reactor.py (+0/-15)
landscape/watchdog.py (+17/-4)
To merge this branch: bzr merge lp:~free.ekanayaka/landscape-client/clones-fixes
Reviewer Review Type Date Requested Status
Alberto Donato (community) Approve
Geoff Teale (community) Approve
Review via email: mp+91404@code.launchpad.net

Description of the change

This branch:

- makes the watchdog increase the system's nofile limit of open file descriptors when using the --clones option, allowing the child processes to open a possibly high number of unix sockets to communicate with each other (there will be several instances of Broker, Manager and Monitor in each process)

- makes the TwistedReactor.call_in_thread method use Twisted's deferToThread, which will use a threadpool instead of spawning a thread each time, this should be both more efficient and safe (when running clones the number of threads will be kept under control)

- increases the MethodCallProtocol timeout when using --clones, as RPCs between processes can lag a bit in that case

To post a comment you must log in.
Revision history for this message
Geoff Teale (tealeg) wrote :

+1 All good.

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

Great, +1!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'landscape/reactor.py'
2--- landscape/reactor.py 2011-12-02 08:35:25 +0000
3+++ landscape/reactor.py 2012-02-03 10:35:22 +0000
4@@ -1,4 +1,3 @@
5-import thread
6 import time
7 import sys
8 import logging
9@@ -8,6 +7,7 @@
10 from twisted.test.proto_helpers import FakeDatagramTransport
11 from twisted.internet.defer import succeed, fail
12 from twisted.internet.error import DNSLookupError
13+from twisted.internet.threads import deferToThread
14
15 from landscape.log import format_object
16
17@@ -120,8 +120,20 @@
18 @note: Both C{callback} and C{errback} will be executed in the
19 the parent thread.
20 """
21- thread.start_new_thread(self._in_thread,
22- (callback, errback, f, args, kwargs))
23+ def on_success(result):
24+ if callback:
25+ return callback(result)
26+
27+ def on_failure(failure):
28+ exc_info = (failure.type, failure.value, failure.tb)
29+ if errback:
30+ errback(*exc_info)
31+ else:
32+ logging.error(exc_info[1], exc_info=exc_info)
33+
34+ deferred = deferToThread(f, *args, **kwargs)
35+ deferred.addCallback(on_success)
36+ deferred.addErrback(on_failure)
37
38 def _in_thread(self, callback, errback, f, args, kwargs):
39 try:
40
41=== modified file 'landscape/service.py'
42--- landscape/service.py 2011-12-01 13:38:58 +0000
43+++ landscape/service.py 2012-02-03 10:35:22 +0000
44@@ -8,6 +8,7 @@
45 from landscape.log import rotate_logs
46 from landscape.reactor import TwistedReactor
47 from landscape.deployment import get_versioned_persist, init_logging
48+from landscape.amp import ComponentProtocol
49
50
51 class LandscapeService(Service, object):
52@@ -78,6 +79,9 @@
53
54 if configuration.clones > 0:
55
56+ # Increase the timeout of AMP's MethodCalls
57+ ComponentProtocol.timeout = 300
58+
59 # Create clones here because TwistedReactor.__init__ would otherwise
60 # cancel all scheduled delayed calls
61 clones = []
62@@ -93,8 +97,9 @@
63 configuration.is_clone = False
64
65 def start_clones():
66- # Spawn instances over 25-30 minutes.
67- delay = configuration.start_clones_over / configuration.clones
68+ # Spawn instances over the given time window
69+ start_clones_over = float(configuration.start_clones_over)
70+ delay = start_clones_over / configuration.clones
71
72 for i, clone in enumerate(clones):
73
74
75=== modified file 'landscape/tests/test_reactor.py'
76--- landscape/tests/test_reactor.py 2011-07-05 05:09:11 +0000
77+++ landscape/tests/test_reactor.py 2012-02-03 10:35:22 +0000
78@@ -243,9 +243,6 @@
79
80 reactor.call_in_thread(None, None, f, 1, 2, c=3)
81
82- while not called:
83- pass
84-
85 reactor.call_later(0.7, reactor.stop)
86 reactor.run()
87
88@@ -274,9 +271,6 @@
89
90 reactor.call_in_thread(callback, errback, f)
91
92- while not called:
93- pass
94-
95 reactor.call_later(0.7, reactor.stop)
96 reactor.run()
97
98@@ -301,9 +295,6 @@
99
100 reactor.call_in_thread(callback, errback, f)
101
102- while not called:
103- pass
104-
105 reactor.call_later(0.7, reactor.stop)
106 reactor.run()
107
108@@ -329,9 +320,6 @@
109
110 reactor.call_in_thread(callback, None, f)
111
112- while not called:
113- pass
114-
115 reactor.call_later(0.7, reactor.stop)
116 reactor.run()
117
118@@ -355,9 +343,6 @@
119
120 reactor.call_in_thread(None, None, f)
121
122- while not called:
123- pass
124-
125 reactor.call_later(0.7, reactor.stop)
126 reactor.run()
127
128
129=== modified file 'landscape/watchdog.py'
130--- landscape/watchdog.py 2011-12-02 08:35:25 +0000
131+++ landscape/watchdog.py 2012-02-03 10:35:22 +0000
132@@ -13,6 +13,7 @@
133 import time
134
135 from logging import warning, info, error
136+from resource import setrlimit, RLIMIT_NOFILE
137
138 from twisted.internet import reactor
139 from twisted.internet.defer import Deferred, succeed
140@@ -27,6 +28,7 @@
141 from landscape.lib.bootstrap import (BootstrapList, BootstrapFile,
142 BootstrapDirectory)
143 from landscape.log import rotate_logs
144+from landscape.amp import ComponentProtocol
145 from landscape.broker.amp import (
146 RemoteBrokerConnector, RemoteMonitorConnector, RemoteManagerConnector)
147 from landscape.reactor import TwistedReactor
148@@ -490,10 +492,21 @@
149 Service.startService(self)
150 bootstrap_list.bootstrap(data_path=self._config.data_path,
151 log_dir=self._config.log_dir)
152- for i in range(self._config.clones):
153- suffix = "-clone-%d" % i
154- bootstrap_list.bootstrap(data_path=self._config.data_path + suffix,
155- log_dir=self._config.log_dir + suffix)
156+ if self._config.clones > 0:
157+
158+ # Let clones open an appropriate number of fds
159+ setrlimit(RLIMIT_NOFILE, (self._config.clones * 100,
160+ self._config.clones * 200))
161+
162+ # Increase the timeout of AMP's MethodCalls
163+ ComponentProtocol.timeout = 300
164+
165+ # Create clones log and data directories
166+ for i in range(self._config.clones):
167+ suffix = "-clone-%d" % i
168+ bootstrap_list.bootstrap(
169+ data_path=self._config.data_path + suffix,
170+ log_dir=self._config.log_dir + suffix)
171
172 result = self.watchdog.check_running()
173

Subscribers

People subscribed via source and target branches

to all changes: