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

Unified Diff: appengine/findit/crash/flag_manager.py

Issue 2593093003: [Predator] Add flag manager and flag manager test. (Closed)
Patch Set: Fix nits. Created 4 years 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 side-by-side diff with in-line comments
Download patch
Index: appengine/findit/crash/flag_manager.py
diff --git a/appengine/findit/crash/flag_manager.py b/appengine/findit/crash/flag_manager.py
new file mode 100644
index 0000000000000000000000000000000000000000..9a13eb482635d6e5a49efe1c7243e951f7a70d52
--- /dev/null
+++ b/appengine/findit/crash/flag_manager.py
@@ -0,0 +1,159 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Module handling flags while doing stream parsing.
+
+``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.
+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.
+with ``False`` value is ``off``.
+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.
+while it is ``off``.
+
+``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.
+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.
+``FlagManager`` with a certain group (differentiate different namespaces).
+
+For example:
+
+
+stacktrace = "blabla\nSUMMARY:\nblabla"
+flag = ParsingFlag('after_summary_flag', lambda line: 'SUMMARY:' in line,
+ value=False)
+flag_manager = FlagManager()
+flag_manager.Register('stacktrace_group', flag)
+
+for line in stacktrace.splitlines():
+ flag_manager.ConditionallyTurnOnFlags(line)
+
+
+The ``after_summary_flag`` will be turned on (set the value to True) when
+parsing the second line, because the initial value of the flag is ``False`` and
+the condition function returns ``True`` for the second line.
+
+The flag will stay ``on``, until ``flag.Off()`` is called to set the value to
+``False`` explictly.
+"""
+
+from collections import defaultdict
+
+
+class ParsingFlag(object):
+ """Represents a flag in stream parsing.
+
+ 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.
+ condition will be used to evaluate the flag value.
+ """
+ def __init__(self, name, condition=None, value=False):
+ """
+ Args:
+ name (str): Name of the flag.
+ condition (function): Funtion that takes str line as input and returns
+ boolean value indicating whether the flag should be turned on or not.
+ 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.
+ value (bool): Initial value of the flag.
+ """
+ self._name = name
+ self._condition = condition
+ self._value = value
+
+ @property
+ def name(self):
+ return self._name
+
+ @property
+ def value(self):
+ return self._value
+
+ 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
+ self._value = True
+
+ def Off(self):
wrengr 2016/12/28 23:34:09 ditto
Sharu Jiang 2016/12/29 18:20:21 Done.
+ self._value = False
+
+ def __nonzero__(self):
+ return self._value
+
+ __bool__ = __nonzero__
+
+ def ConditionallyTurnOn(self, line):
+ """When the flag is off, turns on it if conditions met."""
+ 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
+ self.On()
+
+
+class FlagManager(object):
+ """A manager to track all the registered flags.
+
+ FlagManager collects and manages flags based on group names. FlagManager takes
+ care of manipulating flags during the stream parsing, including evaluating
+ based on the conditions of flags, and resetting flags.
+
+ 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.
+ 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.
+ """
+
+ def __init__(self):
+ self.flag_groups = defaultdict(list)
+ self.flags = {}
+
+ def ClearFlags(self):
+ """Deletes all the flags."""
+ self.flag_groups = defaultdict(list)
+ self.flags = {}
+
+ def Register(self, group_name, flag):
+ """Registers a flag with a group.
+
+ Flags under the same group should have the same scope.
+ For example, in stacktrace parsing, the scope of a flag like
+ ``after_sumary_line`` is the whole stacktrace, so it should be under
+ ``stacktrace_flags`` group, while the scope of
+ ``callstack_top_frame_has_no_symbol`` is callstack, and it should be
+ under ``callstack_flags`` group.
+ """
+ self.flag_groups[group_name].append(flag)
+ self.flags[flag.name] = flag
+
+ def GetAllFlags(self):
+ """Returns all registered flags."""
+ return self.flags.values()
+
+ def GetGroupFlags(self, group_name):
+ """Returns a certain group of flags."""
+ return self.flag_groups.get(group_name, [])
+
+ def ResetAllFlags(self):
+ """Turns off all registered flags."""
+ for flag in self.GetAllFlags():
+ flag.Off()
+
+ def ResetGroupFlags(self, group_name):
+ """Turns off a certain group of flags."""
+ for flag in self.GetGroupFlags(group_name):
+ flag.Off()
+
+ def ConditionallyTurnOnFlags(self, line):
+ """Turns on flags which are off and the conditions are met by the line."""
+ for flag in self.GetAllFlags():
+ flag.ConditionallyTurnOn(line)
+
+ def Get(self, flag_name):
+ """Gets the instance with flag_name."""
+ return self.flags.get(flag_name)
+
+ def TurnOn(self, flag_name):
+ """Sets the instance with flag_name to True."""
+ flag = self.flags.get(flag_name)
+ if flag is None:
+ return
+
+ flag.On()
+
+ def TurnOff(self, flag_name):
+ """Sets the instance with flag_name to False."""
+ flag = self.flags.get(flag_name)
+ if flag is None:
+ return
+
+ flag.Off()
« 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