Merge lp:~facundo/ubuntuone-client/aq-memory-improvements into lp:ubuntuone-client
- aq-memory-improvements
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | dobey |
Approved revision: | 640 |
Merged at revision: | 649 |
Proposed branch: | lp:~facundo/ubuntuone-client/aq-memory-improvements |
Merge into: | lp:ubuntuone-client |
Diff against target: |
354 lines (+136/-85) 3 files modified
tests/syncdaemon/test_action_queue.py (+98/-29) ubuntuone/syncdaemon/action_queue.py (+27/-47) ubuntuone/syncdaemon/logger.py (+11/-9) |
To merge this branch: | bzr merge lp:~facundo/ubuntuone-client/aq-memory-improvements |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Guillermo Gonzalez | Approve | ||
John O'Brien (community) | Approve | ||
Review via email: mp+33269@code.launchpad.net |
Commit message
Stop storing wrapped functions in every queued command.
Description of the change
Stop storing wrapped functions in every queued command.
For this, I heavily refactored the demark method. Tests included.
Also, fixed mklog to log correctly (and a little speedup).
Guillermo Gonzalez (verterok) wrote : | # |
looks good!
dobey (dobey) wrote : | # |
The attempt to merge lp:~facundo/ubuntuone-client/aq-memory-improvements into lp:ubuntuone-client failed.Below is the output from the failed tests.
/usr/bin/
checking for autoconf >= 2.53...
testing autoconf2.50... not found.
testing autoconf... found 2.67
checking for automake >= 1.10...
testing automake-1.11... found 1.11.1
checking for libtool >= 1.5...
testing libtoolize... found 2.2.6b
checking for intltool >= 0.30...
testing intltoolize... found 0.41.1
checking for pkg-config >= 0.14.0...
testing pkg-config... found 0.25
Checking for required M4 macros...
Checking for forbidden M4 macros...
Processing ./configure.ac
Running libtoolize...
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in AC_CONFIG_
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
Running intltoolize...
Running aclocal-1.11...
Running autoconf...
Running autoheader...
Running automake-1.11...
Running ./configure --with-
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking for library containing strerror... none required
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking dependency style of gcc... (cached) gcc3
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for ar... ar
check...
dobey (dobey) wrote : | # |
This should fix the dbus-docs failing problem during make dist:
=== modified file 'Makefile.am'
--- Makefile.am 2010-07-15 22:03:27 +0000
+++ Makefile.am 2010-08-23 14:35:33 +0000
@@ -76,7 +76,7 @@ test-coverage: logging.conf $(clientdefs
check: lint test Makefile
-docs: Makefile
+docs: $(clientdefs_DATA) Makefile
$(mkdir_p) docs
if test "x$(builddir)" != "x$(srcdir)" -a -f "$(srcdir)
$(LN_S) "$(top_
Preview Diff
1 | === modified file 'tests/syncdaemon/test_action_queue.py' |
2 | --- tests/syncdaemon/test_action_queue.py 2010-08-17 14:23:31 +0000 |
3 | +++ tests/syncdaemon/test_action_queue.py 2010-08-20 22:22:40 +0000 |
4 | @@ -55,6 +55,7 @@ |
5 | DeltaList, |
6 | ) |
7 | from ubuntuone.syncdaemon.event_queue import EventQueue, EVENTS |
8 | +from ubuntuone.syncdaemon.marker import MDMarker |
9 | |
10 | |
11 | PATH = u'~/Documents/pdfs/moño/' |
12 | @@ -1058,6 +1059,7 @@ |
13 | def setUp(self): |
14 | """Set up.""" |
15 | res = super(ActionQueueCommandTestCase, self).setUp() |
16 | + self.handler.setLevel(logging.DEBUG) |
17 | |
18 | class MyCommand(ActionQueueCommand): |
19 | logged_attrs = ('a', 'b', 'c', 'd') |
20 | @@ -1067,6 +1069,7 @@ |
21 | |
22 | request_queue = RequestQueue(name='fu', action_queue=self.action_queue) |
23 | self.cmd = MyCommand(request_queue) |
24 | + self.cmd.start_unqueued() # just for it to create its logger |
25 | |
26 | return res |
27 | |
28 | @@ -1075,35 +1078,101 @@ |
29 | d = self.cmd.to_dict() |
30 | self.assertEqual(d, dict(a=3, b='foo', c=u'año', d=None)) |
31 | |
32 | - def test_unwrap_no_results(self): |
33 | - """Test unwrap with no results.""" |
34 | - r = self.cmd.unwrap([]) |
35 | - self.assertEqual(r, []) |
36 | - |
37 | - def test_unwrap_one_result_ok(self): |
38 | - """Test unwrap with one result ok.""" |
39 | - r = self.cmd.unwrap([(True, 'foo')]) |
40 | - self.assertEqual(r, ['foo']) |
41 | - |
42 | - def test_unwrap_result_None(self): |
43 | - """Test unwrap with None a valid result.""" |
44 | - r = self.cmd.unwrap([None]) |
45 | - self.assertEqual(r, []) |
46 | - |
47 | - def test_unwrap_result_failed(self): |
48 | - """Test unwrap with a not ok result.""" |
49 | - r = self.cmd.unwrap([(False, 'failure')]) |
50 | - self.assertEqual(r, 'failure') |
51 | - |
52 | - def test_unwrap_mixed_results_ok(self): |
53 | - """Test unwrap with different results no failure.""" |
54 | - r = self.cmd.unwrap([(True, 'foo'), None, (True, 'bar')]) |
55 | - self.assertEqual(r, ['foo', 'bar']) |
56 | - |
57 | - def test_unwrap_mixed_results_failure(self): |
58 | - """Test unwrap with different results one failure.""" |
59 | - r = self.cmd.unwrap([(True, 'foo'), (False, 'fail'), (True, 'bar')]) |
60 | - self.assertEqual(r, 'fail') |
61 | + @defer.inlineCallbacks |
62 | + def test_demark_not_marker(self): |
63 | + """Test demark with not a marker.""" |
64 | + result = yield self.cmd.demark('not a marker') |
65 | + self.assertEqual(result, ['not a marker']) |
66 | + |
67 | + @defer.inlineCallbacks |
68 | + def test_demark_with_marker_future(self): |
69 | + """Test demark with a marker not ready. |
70 | + |
71 | + Here, on purpose, set up everything and trigger later. |
72 | + """ |
73 | + marker = MDMarker('foo') |
74 | + d = self.cmd.demark(marker) |
75 | + |
76 | + self.action_queue.uuid_map.set(marker, 'node_id') |
77 | + result = yield d |
78 | + self.assertEqual(result, ['node_id']) |
79 | + self.assertTrue(self.handler.check_debug( |
80 | + "waiting for the real value of 'foo'")) |
81 | + |
82 | + @defer.inlineCallbacks |
83 | + def test_demark_with_marker_ready(self): |
84 | + """Test demark with a marker that had data.""" |
85 | + marker = MDMarker('foo') |
86 | + self.action_queue.uuid_map.set(marker, 'node_id') |
87 | + result = yield self.cmd.demark(marker) |
88 | + self.assertEqual(result, ['node_id']) |
89 | + self.assertTrue(self.handler.check_debug( |
90 | + "waiting for the real value of 'foo'")) |
91 | + |
92 | + @defer.inlineCallbacks |
93 | + def test_demark_mixed_markers(self): |
94 | + """Test demark with both a marker and not.""" |
95 | + # call demark with both |
96 | + marker = MDMarker('foo') |
97 | + self.action_queue.uuid_map.set(marker, 'node_id') |
98 | + result = yield self.cmd.demark('notamarker', marker) |
99 | + |
100 | + # check |
101 | + self.assertEqual(result, ['notamarker', 'node_id']) |
102 | + self.assertTrue(self.handler.check_debug( |
103 | + "waiting for the real value of 'foo'")) |
104 | + self.assertFalse(self.handler.check_debug( |
105 | + "waiting for the real value of 'notamarker'")) |
106 | + |
107 | + @defer.inlineCallbacks |
108 | + def test_demark_marker_ready_got_ok(self): |
109 | + """Test demark getting a marker triggered ok now.""" |
110 | + marker = MDMarker('foo') |
111 | + self.action_queue.uuid_map.set(marker, 'node_id') |
112 | + result = yield self.cmd.demark(marker) |
113 | + self.assertEqual(result, ['node_id']) |
114 | + self.assertTrue(self.handler.check_debug("got 'foo'")) |
115 | + |
116 | + @defer.inlineCallbacks |
117 | + def test_demark_marker_future_got_ok(self): |
118 | + """Test demark getting a marker triggered ok later.""" |
119 | + # don't have the info now |
120 | + marker = MDMarker('foo') |
121 | + d = self.cmd.demark(marker) |
122 | + self.assertFalse(self.handler.check_debug("got 'foo'")) |
123 | + |
124 | + # set and check |
125 | + self.action_queue.uuid_map.set(marker, 'node_id') |
126 | + result = yield d |
127 | + self.assertEqual(result, ['node_id']) |
128 | + self.assertTrue(self.handler.check_debug("got 'foo'")) |
129 | + |
130 | + @defer.inlineCallbacks |
131 | + def test_demark_marker_ready_got_failure(self): |
132 | + """Test demark getting a marker triggered with failure now.""" |
133 | + marker = MDMarker('foo') |
134 | + self.action_queue.uuid_map.err(marker, Failure(Exception('bad'))) |
135 | + try: |
136 | + yield self.cmd.demark(marker) |
137 | + except Exception, e: |
138 | + self.assertEqual(str(e), 'bad') |
139 | + self.assertTrue(self.handler.check_error("failed 'foo'")) |
140 | + |
141 | + @defer.inlineCallbacks |
142 | + def test_demark_marker_future_got_failure(self): |
143 | + """Test demark getting a marker triggered with failure later.""" |
144 | + # don't have the info now |
145 | + marker = MDMarker('foo') |
146 | + d = self.cmd.demark(marker) |
147 | + self.assertFalse(self.handler.check_error("failed 'foo'")) |
148 | + |
149 | + # set the marker and check |
150 | + self.action_queue.uuid_map.err(marker, Failure(Exception('bad'))) |
151 | + try: |
152 | + yield d |
153 | + except Exception, e: |
154 | + self.assertEqual(str(e), 'bad') |
155 | + self.assertTrue(self.handler.check_error("failed 'foo'")) |
156 | |
157 | |
158 | class CreateUDFTestCase(ConnectedBaseTestCase): |
159 | |
160 | === modified file 'ubuntuone/syncdaemon/action_queue.py' |
161 | --- ubuntuone/syncdaemon/action_queue.py 2010-08-17 14:23:31 +0000 |
162 | +++ ubuntuone/syncdaemon/action_queue.py 2010-08-20 22:22:40 +0000 |
163 | @@ -254,7 +254,7 @@ |
164 | try: |
165 | if upload.cancelled: |
166 | raise UploadCompressionCancelled("Cancelled") |
167 | - upload.log.debug('compressing', filename) |
168 | + upload.log.debug('compressing: %r', filename) |
169 | # we need to compress the file completely to figure out its |
170 | # compressed size. So streaming is out :( |
171 | if upload.tempfile_factory is None: |
172 | @@ -519,8 +519,7 @@ |
173 | self.map = {} |
174 | |
175 | def get(self, key): |
176 | - """ |
177 | - Get the value for the given key. |
178 | + """Get the value for the given key. |
179 | |
180 | This always returns a deferred; when we already know the value |
181 | we return a `succeed`, and if we don't know the value because |
182 | @@ -537,9 +536,9 @@ |
183 | return d |
184 | |
185 | def set(self, key, value): |
186 | - """ |
187 | - We've got the value for a key! Write it down in the map, and |
188 | - fire the waiting deferreds. |
189 | + """We've got the value for a key! |
190 | + |
191 | + Write it down in the map, and fire the waiting deferreds. |
192 | """ |
193 | if key not in self.map: |
194 | self.map[key] = value |
195 | @@ -550,18 +549,18 @@ |
196 | raise KeyError("key is taken -- dunno what to do") |
197 | |
198 | def err(self, key, failure): |
199 | - """ |
200 | - Something went terribly wrong in the process of getting a |
201 | - value. Break the news to the waiting deferreds. |
202 | + """Something went terribly wrong in the process of getting a value. |
203 | + |
204 | + Break the news to the waiting deferreds. |
205 | """ |
206 | self.failed[key] = failure.getErrorMessage() |
207 | for d in self.waiting.pop(key, ()): |
208 | d.errback(failure) |
209 | |
210 | def resolve_maybe(self, key): |
211 | - """ |
212 | - Return either the mapping of key (if key has been resolved), |
213 | - or key itself (if not). |
214 | + """Return either the mapping of key, or key itself. |
215 | + |
216 | + The former if key has been resolved, the later if not. |
217 | """ |
218 | return self.map.get(key, key) |
219 | |
220 | @@ -1238,43 +1237,24 @@ |
221 | def check_conditions(self): |
222 | """Check conditions on which the command may be waiting.""" |
223 | |
224 | + @defer.inlineCallbacks |
225 | def demark(self, *maybe_markers): |
226 | """Arrange to have maybe_markers realized.""" |
227 | - l = [] |
228 | + results = [] |
229 | for marker in maybe_markers: |
230 | if IMarker.providedBy(marker): |
231 | - self.log.debug('waiting until we know the real value of %r', |
232 | - marker) |
233 | - d = self.action_queue.uuid_map.get(marker) |
234 | - d.addCallbacks(passit(lambda _: |
235 | - self.log.debug('got %r', marker)), |
236 | - passit(lambda f: |
237 | - self.log.error('failed %r', marker))) |
238 | + self.log.debug("waiting for the real value of '%s'", marker) |
239 | + try: |
240 | + result = yield self.action_queue.uuid_map.get(marker) |
241 | + except: |
242 | + self.log.error("failed '%s'", marker) |
243 | + raise |
244 | + else: |
245 | + self.log.debug("got '%s'", marker) |
246 | + results.append(result) |
247 | else: |
248 | - d = defer.succeed(marker) |
249 | - l.append(d) |
250 | - dl = defer.DeferredList(l, fireOnOneErrback=True, consumeErrors=True) |
251 | - dl.addCallbacks(self.unwrap, lambda f: f.value.subFailure) |
252 | - |
253 | - return dl |
254 | - |
255 | - @staticmethod |
256 | - def unwrap(results): |
257 | - """Unpack the values from the result of a DeferredList. |
258 | - |
259 | - If there's a failure, return it instead. |
260 | - """ |
261 | - values = [] |
262 | - for result in results: |
263 | - # result can be none if one of the callbacks failed |
264 | - # before the others were ready |
265 | - if result is not None: |
266 | - is_ok, value = result |
267 | - if not is_ok: |
268 | - # a failure! |
269 | - return value |
270 | - values.append(value) |
271 | - return values |
272 | + results.append(marker) |
273 | + defer.returnValue(results) |
274 | |
275 | def end_callback(self, arg): |
276 | """It worked!""" |
277 | @@ -1288,9 +1268,9 @@ |
278 | """It failed!""" |
279 | error_message = failure.getErrorMessage() |
280 | if failure.check(*self.suppressed_error_messages): |
281 | - self.log.warn('failure', error_message) |
282 | + self.log.warn('failure: %s', error_message) |
283 | else: |
284 | - self.log.error('failure', error_message) |
285 | + self.log.error('failure: %s', error_message) |
286 | self.log.debug('traceback follows:\n\n' + failure.getTraceback()) |
287 | was_running = self.running |
288 | self.cleanup() |
289 | @@ -1984,7 +1964,7 @@ |
290 | cmd.volume_id == self.volume_id: |
291 | # other GetDeltaFromScratch for same volume! skip self |
292 | m = "GetDeltaFromScratch already queued, not queueing self" |
293 | - self.log.debug(m, cmd) |
294 | + self.log.debug(m) |
295 | return |
296 | |
297 | # no similar command |
298 | |
299 | === modified file 'ubuntuone/syncdaemon/logger.py' |
300 | --- ubuntuone/syncdaemon/logger.py 2010-07-27 17:15:58 +0000 |
301 | +++ ubuntuone/syncdaemon/logger.py 2010-08-20 22:22:40 +0000 |
302 | @@ -23,7 +23,6 @@ |
303 | import os |
304 | import zlib |
305 | |
306 | -from itertools import imap |
307 | from ubuntuone.logger import ( |
308 | LOGFOLDER, |
309 | _DEBUG_LOG_LEVEL, |
310 | @@ -65,33 +64,36 @@ |
311 | self.zipped_desc = zlib.compress(desc, 9) |
312 | self.logger = _logger |
313 | |
314 | - @property |
315 | - def desc(self): |
316 | - return zlib.decompress(self.zipped_desc) |
317 | - |
318 | def _log(self, logger_func, *args): |
319 | - """ |
320 | - Generalized form of the different logging functions. |
321 | - """ |
322 | - logger_func(self.desc + " ".join(imap(str, args))) |
323 | + """Generalized form of the different logging methods.""" |
324 | + desc = zlib.decompress(self.zipped_desc) |
325 | + text = desc + args[0] |
326 | + logger_func(text, *args[1:]) |
327 | + |
328 | def debug(self, *args): |
329 | """Log at level DEBUG""" |
330 | self._log(self.logger.debug, *args) |
331 | + |
332 | def info(self, *args): |
333 | """Log at level INFO""" |
334 | self._log(self.logger.info, *args) |
335 | + |
336 | def warn(self, *args): |
337 | """Log at level WARN""" |
338 | self._log(self.logger.warn, *args) |
339 | + |
340 | def error(self, *args): |
341 | """Log at level ERROR""" |
342 | self._log(self.logger.error, *args) |
343 | + |
344 | def exception(self, *args): |
345 | """Log an exception""" |
346 | self._log(self.logger.exception, *args) |
347 | + |
348 | def note(self, *args): |
349 | """Log at NOTE level (high-priority info) """ |
350 | self._log(self.logger.high, *args) |
351 | + |
352 | def trace(self, *args): |
353 | """Log at level TRACE""" |
354 | self._log(self.logger.trace, *args) |
looks good, and all tests pass.... InlineCallbacks FTW!