Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: appengine/findit/crash/flag_manager.py

Issue 2593093003: [Predator] Add flag manager and flag manager test. (Closed)
Patch Set: Fix nits. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Module handling flags while doing stream parsing.
6
7 ``ParsingFlag`` has name, a condition function which returns boolean predicate
wrengr 2016/12/28 23:34:09 "has name" -> "has a name" "returns boolean predi
Sharu Jiang 2016/12/29 18:20:22 Done.
8 and a boolean value. We call a flag with ``True`` value is ``on``, and a flag
wrengr 2016/12/28 23:34:10 "call a..." -> "We say that a flag with the boolea
Sharu Jiang 2016/12/29 18:20:21 Done.
9 with ``False`` value is ``off``.
10 The condition function is used to check whether a flag should be turned ``on``
wrengr 2016/12/28 23:34:09 should use "on" rather than ``on`` (ditto "off" ra
Sharu Jiang 2016/12/29 18:20:22 Done.
11 while it is ``off``.
12
13 ``FlagManager`` is a managing class of all the flags while doing stream parsing.
wrengr 2016/12/28 23:34:09 "managing class of" -> "class for managing"
Sharu Jiang 2016/12/29 18:20:21 Done.
14 In order to get tracked in stream parsing, all flags must be registered in
wrengr 2016/12/28 23:34:10 "to get tracked in" -> "to be tracked during"
Sharu Jiang 2016/12/29 18:20:21 Done.
15 ``FlagManager`` with a certain group (differentiate different namespaces).
16
17 For example:
18
19
20 stacktrace = "blabla\nSUMMARY:\nblabla"
21 flag = ParsingFlag('after_summary_flag', lambda line: 'SUMMARY:' in line,
22 value=False)
23 flag_manager = FlagManager()
24 flag_manager.Register('stacktrace_group', flag)
25
26 for line in stacktrace.splitlines():
27 flag_manager.ConditionallyTurnOnFlags(line)
28
29
30 The ``after_summary_flag`` will be turned on (set the value to True) when
31 parsing the second line, because the initial value of the flag is ``False`` and
32 the condition function returns ``True`` for the second line.
33
34 The flag will stay ``on``, until ``flag.Off()`` is called to set the value to
35 ``False`` explictly.
36 """
37
38 from collections import defaultdict
39
40
41 class ParsingFlag(object):
42 """Represents a flag in stream parsing.
43
44 This object serves like a delegation to manipulate flag of obj,
wrengr 2016/12/28 23:34:10 "obj" -> "object"
Sharu Jiang 2016/12/29 18:20:22 Done.
45 condition will be used to evaluate the flag value.
46 """
47 def __init__(self, name, condition=None, value=False):
48 """
49 Args:
50 name (str): Name of the flag.
51 condition (function): Funtion that takes str line as input and returns
52 boolean value indicating whether the flag should be turned on or not.
53 Note, the condition should only be checked when the flag is off.
wrengr 2016/12/28 23:34:09 The first sentence is ambiguous about the meaning
Sharu Jiang 2016/12/29 18:20:21 Done.
54 value (bool): Initial value of the flag.
55 """
56 self._name = name
57 self._condition = condition
58 self._value = value
59
60 @property
61 def name(self):
62 return self._name
63
64 @property
65 def value(self):
66 return self._value
67
68 def On(self):
wrengr 2016/12/28 23:34:10 I'd call this ``TurnOn`` rather than just ``On``.
Sharu Jiang 2016/12/29 18:20:22 Ok... I just thought that flag is "on" and flag ma
69 self._value = True
70
71 def Off(self):
wrengr 2016/12/28 23:34:09 ditto
Sharu Jiang 2016/12/29 18:20:21 Done.
72 self._value = False
73
74 def __nonzero__(self):
75 return self._value
76
77 __bool__ = __nonzero__
78
79 def ConditionallyTurnOn(self, line):
80 """When the flag is off, turns on it if conditions met."""
81 if not self._value and self._condition and self._condition(line):
wrengr 2016/12/28 23:34:09 is there a reason to check ``bool(self._condition)
Sharu Jiang 2016/12/29 18:20:22 No, but I think the performance should be the same
wrengr 2016/12/29 19:56:25 Performance would be marginally better (since you
Sharu Jiang 2017/01/03 22:13:27 Will address this in another cl
82 self.On()
83
84
85 class FlagManager(object):
86 """A manager to track all the registered flags.
87
88 FlagManager collects and manages flags based on group names. FlagManager takes
89 care of manipulating flags during the stream parsing, including evaluating
90 based on the conditions of flags, and resetting flags.
91
92 Note, flag manager only keeps distinct flags(with distinct flag name), one
wrengr 2016/12/28 23:34:10 ", one" -> ", and one"
Sharu Jiang 2016/12/29 18:20:21 Done.
93 flag cannot be registered with different groups.
wrengr 2016/12/28 23:34:09 "different" -> "multiple"
Sharu Jiang 2016/12/29 18:20:22 Done.
94 """
95
96 def __init__(self):
97 self.flag_groups = defaultdict(list)
98 self.flags = {}
99
100 def ClearFlags(self):
101 """Deletes all the flags."""
102 self.flag_groups = defaultdict(list)
103 self.flags = {}
104
105 def Register(self, group_name, flag):
106 """Registers a flag with a group.
107
108 Flags under the same group should have the same scope.
109 For example, in stacktrace parsing, the scope of a flag like
110 ``after_sumary_line`` is the whole stacktrace, so it should be under
111 ``stacktrace_flags`` group, while the scope of
112 ``callstack_top_frame_has_no_symbol`` is callstack, and it should be
113 under ``callstack_flags`` group.
114 """
115 self.flag_groups[group_name].append(flag)
116 self.flags[flag.name] = flag
117
118 def GetAllFlags(self):
119 """Returns all registered flags."""
120 return self.flags.values()
121
122 def GetGroupFlags(self, group_name):
123 """Returns a certain group of flags."""
124 return self.flag_groups.get(group_name, [])
125
126 def ResetAllFlags(self):
127 """Turns off all registered flags."""
128 for flag in self.GetAllFlags():
129 flag.Off()
130
131 def ResetGroupFlags(self, group_name):
132 """Turns off a certain group of flags."""
133 for flag in self.GetGroupFlags(group_name):
134 flag.Off()
135
136 def ConditionallyTurnOnFlags(self, line):
137 """Turns on flags which are off and the conditions are met by the line."""
138 for flag in self.GetAllFlags():
139 flag.ConditionallyTurnOn(line)
140
141 def Get(self, flag_name):
142 """Gets the instance with flag_name."""
143 return self.flags.get(flag_name)
144
145 def TurnOn(self, flag_name):
146 """Sets the instance with flag_name to True."""
147 flag = self.flags.get(flag_name)
148 if flag is None:
149 return
150
151 flag.On()
152
153 def TurnOff(self, flag_name):
154 """Sets the instance with flag_name to False."""
155 flag = self.flags.get(flag_name)
156 if flag is None:
157 return
158
159 flag.Off()
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/crash/test/flag_manager_test.py » ('j') | appengine/findit/crash/test/flag_manager_test.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698