Merge lp:~facundo/ubuntuone-client/fix-queue-limit-decision into lp:ubuntuone-client

Proposed by Facundo Batista
Status: Merged
Approved by: Facundo Batista
Approved revision: 1227
Merged at revision: 1226
Proposed branch: lp:~facundo/ubuntuone-client/fix-queue-limit-decision
Merge into: lp:ubuntuone-client
Diff against target: 148 lines (+114/-2)
2 files modified
tests/syncdaemon/test_action_queue.py (+111/-0)
ubuntuone/syncdaemon/action_queue.py (+3/-2)
To merge this branch: bzr merge lp:~facundo/ubuntuone-client/fix-queue-limit-decision
Reviewer Review Type Date Requested Status
Roman Yepishev (community) code Approve
Guillermo Gonzalez Approve
Review via email: mp+102729@code.launchpad.net

Commit message

Use the correct comparison to decide in which queue (LP: #978903).

Description of the change

Use the correct comparison to decide in which queue.

Test included.

To post a comment you must log in.
Revision history for this message
Guillermo Gonzalez (verterok) wrote :

+1

review: Approve
Revision history for this message
Roman Yepishev (rye) wrote :

Does not look like it has fixed for me, continuing the test.

Revision history for this message
Roman Yepishev (rye) wrote :

Does not look like it has completely fixed the issue.
My log at chinstrap.canonical.com:~roman.yepishev/syncdaemon.log

review: Needs Fixing (fieldtest)
Revision history for this message
Roman Yepishev (rye) wrote :

21:25 < facundobatista> rye, we may have other bug
21
:25 < facundobatista> rye, the one addressed by the branch is fixed
21:26 < facundobatista> rye, I'm confirming it in your logs
21:27 < rye> facundobatista: ok, then i will change to approved
21:27 < rye> since it definitely does not make it worse

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'tests/syncdaemon/test_action_queue.py'
--- tests/syncdaemon/test_action_queue.py 2012-04-10 18:11:54 +0000
+++ tests/syncdaemon/test_action_queue.py 2012-04-19 17:46:24 +0000
@@ -31,6 +31,7 @@
31from __future__ import with_statement31from __future__ import with_statement
3232
33import base6433import base64
34import collections
34import inspect35import inspect
35import logging36import logging
36import operator37import operator
@@ -120,6 +121,26 @@
120 return self.check(logger.NOTE, *msgs)121 return self.check(logger.NOTE, *msgs)
121122
122123
124class FakeOffloadQueue(object):
125 """Fake replacemente for offload_queue."""
126 def __init__(self):
127 self.queue = collections.deque()
128
129 def push(self, item):
130 """Push it."""
131 self.queue.append(item)
132
133 def pop(self):
134 """Pop it."""
135 return self.queue.popleft()
136
137 def __len__(self):
138 return len(self.queue)
139
140 def __getitem__(self, idx):
141 return self.queue[idx]
142
143
123class FakeMagicHash(object):144class FakeMagicHash(object):
124 """Fake magic hash."""145 """Fake magic hash."""
125 _magic_hash = '666'146 _magic_hash = '666'
@@ -5859,3 +5880,93 @@
5859 self.assertEqual(called[0], ((FakeCommand, 'arg0'), {'bar': 'baz'}))5880 self.assertEqual(called[0], ((FakeCommand, 'arg0'), {'bar': 'baz'}))
5860 self.assertEqual(called[1], ((FakeCommand, 'arg1'), {'foo': 'bar'}))5881 self.assertEqual(called[1], ((FakeCommand, 'arg1'), {'foo': 'bar'}))
5861 self.assertEqual(called[2], ((FakeCommand, 'arg2'), {}))5882 self.assertEqual(called[2], ((FakeCommand, 'arg2'), {}))
5883
5884 def test_execute_pushing_popping(self):
5885 """Exercise the limits when pushing/popping to disk."""
5886 aq = self.action_queue
5887 aq.memory_pool_limit = 2
5888
5889 def _fake_execute(_, cmd):
5890 """Don't really execute, but store and return deferred.
5891
5892 It also handles the queue.
5893 """
5894 d = defer.Deferred()
5895 commands.append((cmd, d))
5896 aq.queue.append(cmd)
5897
5898 def remove(_):
5899 aq.queue.remove(cmd)
5900 commands.remove((cmd, d))
5901
5902 d.addCallback(remove)
5903 return d
5904
5905 commands = []
5906 self.patch(aq, '_really_execute', _fake_execute)
5907 aq.disk_queue = FakeOffloadQueue()
5908 aq.queue = []
5909 aq.commands[FakeCommand.__name__] = FakeCommand
5910
5911 # send two commands, they should be executed right away
5912 aq.execute(FakeCommand, 1)
5913 aq.execute(FakeCommand, 2)
5914 self.assertEqual(commands[0][0], 1)
5915 self.assertEqual(commands[1][0], 2)
5916
5917 # send a third and fourth commands, they should be offloaded
5918 aq.execute(FakeCommand, 3)
5919 aq.execute(FakeCommand, 4)
5920 self.assertEqual(len(commands), 2)
5921 self.assertEqual(len(aq.disk_queue), 2)
5922 self.assertEqual(aq.disk_queue[0], ('FakeCommand', (3,), {}))
5923 self.assertEqual(aq.disk_queue[1], ('FakeCommand', (4,), {}))
5924
5925 # finish command 1, it should pop and execute command 3
5926 commands[0][1].callback(True)
5927 self.assertEqual(len(commands), 2)
5928 self.assertEqual(commands[0][0], 2)
5929 self.assertEqual(commands[1][0], 3)
5930 self.assertEqual(len(aq.disk_queue), 1)
5931 self.assertEqual(aq.disk_queue[0], ('FakeCommand', (4,), {}))
5932
5933 # other command should go offload
5934 aq.execute(FakeCommand, 5)
5935 self.assertEqual(len(commands), 2)
5936 self.assertEqual(len(aq.disk_queue), 2)
5937 self.assertEqual(aq.disk_queue[0], ('FakeCommand', (4,), {}))
5938 self.assertEqual(aq.disk_queue[1], ('FakeCommand', (5,), {}))
5939
5940 # finish commands 2 and 3... 4 and 5 should go in
5941 commands[0][1].callback(True)
5942 commands[0][1].callback(True)
5943 self.assertEqual(len(commands), 2)
5944 self.assertEqual(commands[0][0], 4)
5945 self.assertEqual(commands[1][0], 5)
5946 self.assertEqual(len(aq.disk_queue), 0)
5947
5948 # even in the edge, another command should be offloaded
5949 aq.execute(FakeCommand, 6)
5950 self.assertEqual(len(commands), 2)
5951 self.assertEqual(len(aq.disk_queue), 1)
5952 self.assertEqual(aq.disk_queue[0], ('FakeCommand', (6,), {}))
5953
5954 # finish 4 and 5, we should only have 6 left
5955 commands[0][1].callback(True)
5956 commands[0][1].callback(True)
5957 self.assertEqual(len(commands), 1)
5958 self.assertEqual(commands[0][0], 6)
5959 self.assertEqual(len(aq.disk_queue), 0)
5960
5961 # one below the limit, next op should be executed right away
5962 aq.execute(FakeCommand, 7)
5963 self.assertEqual(len(commands), 2)
5964 self.assertEqual(commands[0][0], 6)
5965 self.assertEqual(commands[1][0], 7)
5966 self.assertEqual(len(aq.disk_queue), 0)
5967
5968 # finish 6 and 7, all clean
5969 commands[0][1].callback(True)
5970 commands[0][1].callback(True)
5971 self.assertEqual(len(commands), 0)
5972 self.assertEqual(len(aq.disk_queue), 0)
58625973
=== modified file 'ubuntuone/syncdaemon/action_queue.py'
--- ubuntuone/syncdaemon/action_queue.py 2012-04-09 20:08:42 +0000
+++ ubuntuone/syncdaemon/action_queue.py 2012-04-19 17:46:24 +0000
@@ -1095,8 +1095,9 @@
1095 @defer.inlineCallbacks1095 @defer.inlineCallbacks
1096 def execute(self, command_class, *args, **kwargs):1096 def execute(self, command_class, *args, **kwargs):
1097 """Execute a command only if there's room in memory to handle it."""1097 """Execute a command only if there's room in memory to handle it."""
1098 if len(self.queue) > self.memory_pool_limit:1098 if len(self.queue) >= self.memory_pool_limit:
1099 # not enough room in memory, store it in the offloaded queue1099 # already in the limit, can't go further as we don't have
1100 # more room in memory, store it in the offloaded queue
1100 logger.debug('offload push: %s %s %s', command_class.__name__, args, kwargs)1101 logger.debug('offload push: %s %s %s', command_class.__name__, args, kwargs)
1101 self.disk_queue.push((command_class.__name__, args, kwargs))1102 self.disk_queue.push((command_class.__name__, args, kwargs))
1102 return1103 return

Subscribers

People subscribed via source and target branches