Merge lp:~robru/queuebot/fix-rtm-dupes into lp:queuebot

Proposed by Robert Bruce Park
Status: Merged
Merged at revision: 93
Proposed branch: lp:~robru/queuebot/fix-rtm-dupes
Merge into: lp:queuebot
Diff against target: 103 lines (+25/-33)
1 file modified
plugins/landing.py (+25/-33)
To merge this branch: bzr merge lp:~robru/queuebot/fix-rtm-dupes
Reviewer Review Type Date Requested Status
Robert Bruce Park (community) Approve
Stéphane Graber Pending
Ubuntu Package Archive Administrators Pending
Review via email: mp+232335@code.launchpad.net

Commit message

Stop flooding pings when spreadsheet column A isn't unique.

Description of the change

Apologies for the big diff, but I was able to track down the flooding problem. What was happening was that people were copy&pasting their utopic landings as RTM landings, so spreadsheet column A which we were indexing on was no longer unique. And since the utopic/RTM silos rarely had identical statuses, the bot would see one status, see the other status, see they were different, and ping that, always.

I solved that by creating a more unique token by hashing together columns A and H, which is to say I combine the destination release with the landing description to create a more unique key to index off of.

In the process of writing this, I realized that the plugin had a memory leak, because it never cleared old descriptions that it was scanning, so in theory those were just piling up forever. I solved it by creating a new dict each time rather than adding to the same old dict forever.

Additionally, I wrote a few simplifications that make the code easier to read, at least for me. Hopefully none of this is controversial for you.

Thanks!

To post a comment you must log in.
Revision history for this message
Robert Bruce Park (robru) wrote :

I tested this in the staging channel and it looked really good, didn't flood at all. Please merge! ;-)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/landing.py'
2--- plugins/landing.py 2014-07-16 18:32:07 +0000
3+++ plugins/landing.py 2014-08-26 23:10:20 +0000
4@@ -11,6 +11,9 @@
5 "?key=0AuDk72Lpx8U5dFVHQ3FuMDJGLUZCamJfSjYzbWh3Wnc" \
6 "&usp=sharing&output=csv"
7
8+TESTED = "trainguards, {silo_name}: {new_status}"
9+ASSIGN = "trainguards, please assign line {line_num} for {landers}"
10+
11
12 class COL:
13 pass
14@@ -23,13 +26,6 @@
15 try:
16 self.notices = list()
17
18- if self.queue not in self.testing_state:
19- self.testing_state[self.queue] = dict()
20-
21- # In verbose mode, show the current content of the queue
22- if self.verbose and self.queue not in self.landing_state:
23- self.landing_state[self.queue] = set()
24-
25 # Fetch current state
26 opener = urllib2.build_opener(
27 urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
28@@ -47,6 +43,7 @@
29 setattr(COL, re.split('\W', heading.lower())[0], i)
30
31 landing_ready = set()
32+ testing_ready = dict()
33 for line_num, line in enumerate(reader, start=4):
34 # Do some basic validation
35 if len(line) < 17:
36@@ -55,46 +52,41 @@
37 description = line[COL.description]
38 new_status = line[COL.computed]
39 silo_name = line[COL.assigned]
40- landers = line[COL.lander]
41+ landers = ", ".join(line[COL.lander].split())
42 ready = line[COL.ready]
43 request = line[COL.request]
44-
45- old_status = self.testing_state[self.queue].get(description)
46+ target = line[COL.target]
47+ token = hash(target + description)
48+
49+ old_status = self.testing_state.get(token)
50+
51+ testing_ready[token] = new_status
52 if old_status != new_status:
53- self.testing_state[self.queue][description] = new_status
54 if "Testing pass" in new_status:
55- self.notices.append((
56- "%s: trainguards, silo %s: %s"
57- % (self.queue, silo_name, new_status),
58- ("landing",)))
59+ self.notices.append((TESTED.format(**locals()),
60+ (self.queue,)))
61
62 if ready != "Yes" or request:
63 continue
64
65- landing_ready.add(description)
66-
67- if self.queue not in self.landing_state:
68- continue
69-
70- if self.queue in self.landing_state and \
71- description in self.landing_state[self.queue]:
72- continue
73-
74- self.notices.append(("%s: trainguards, new landing "
75- "ready for assignment "
76- "(line %s, lander is %s)"
77- % (self.queue, line_num,
78- ", ".join(landers.split())),
79- ("landing",)))
80-
81- self.landing_state[self.queue] = landing_ready
82+ landing_ready.add(token)
83+
84+ if token in self.landing_state:
85+ continue
86+
87+ self.notices.append((ASSIGN.format(**locals()), (self.queue,)))
88+
89+ self.landing_state.clear()
90+ self.landing_state.update(landing_ready)
91+ self.testing_state.clear()
92+ self.testing_state.update(testing_ready)
93 except:
94 # We don't want the bot to crash when something fails
95 traceback.print_exc()
96
97
98 class Landing():
99- landing_state = dict()
100+ landing_state = set()
101 testing_state = dict()
102 scanner = LandingScanner()
103 name = "landing"

Subscribers

People subscribed via source and target branches