You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildstream.apache.org by ro...@apache.org on 2020/12/29 13:29:17 UTC

[buildstream] 01/08: _context.py: Added _timed_activity() method

This is an automated email from the ASF dual-hosted git repository.

root pushed a commit to branch early-logging
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit fe65e79c9b36d7ca5fe2d4d3d79cff5b51beeb38
Author: Tristan Van Berkom <tr...@codethink.co.uk>
AuthorDate: Tue Dec 12 18:47:43 2017 -0500

    _context.py: Added _timed_activity() method
    
    A version of the function which can be shared with the frontend too.
---
 buildstream/_context.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/buildstream/_context.py b/buildstream/_context.py
index f975d3d..08ce83a 100644
--- a/buildstream/_context.py
+++ b/buildstream/_context.py
@@ -19,11 +19,15 @@
 #        Tristan Van Berkom <tr...@codethink.co.uk>
 
 import os
+import datetime
 from collections import deque, Mapping
+from contextlib import contextmanager
+from . import _signals
 from . import _site
 from . import _yaml
 from . import utils
-from ._exceptions import LoadError, LoadErrorReason
+from ._exceptions import LoadError, LoadErrorReason, BstError
+from ._message import Message, MessageType
 from ._profile import Topics, profile_start, profile_end
 
 
@@ -303,6 +307,54 @@ class Context():
         self._message_handler(message, context=self)
         return
 
+    # _timed_activity()
+    #
+    # Context manager for performing timed activities and logging those
+    #
+    # Args:
+    #    context (Context): The invocation context object
+    #    activity_name (str): The name of the activity
+    #    detail (str): An optional detailed message, can be multiline output
+    #    silent_nested (bool): If specified, nested messages will be silenced
+    #
+    @contextmanager
+    def _timed_activity(self, activity_name, *, unique_id=None, detail=None, silent_nested=False):
+
+        starttime = datetime.datetime.now()
+        stopped_time = None
+
+        def stop_time():
+            nonlocal stopped_time
+            stopped_time = datetime.datetime.now()
+
+        def resume_time():
+            nonlocal stopped_time
+            nonlocal starttime
+            sleep_time = datetime.datetime.now() - stopped_time
+            starttime += sleep_time
+
+        with _signals.suspendable(stop_time, resume_time):
+            try:
+                # Push activity depth for status messages
+                message = Message(unique_id, MessageType.START, activity_name, detail=detail)
+                self._message(message)
+                self._push_message_depth(silent_nested)
+                yield
+
+            except BstError as e:
+                # Note the failure in status messages and reraise, the scheduler
+                # expects an error when there is an error.
+                elapsed = datetime.datetime.now() - starttime
+                message = Message(unique_id, MessageType.FAIL, activity_name, elapsed=elapsed)
+                self._pop_message_depth()
+                self._message(message)
+                raise
+
+            elapsed = datetime.datetime.now() - starttime
+            message = Message(unique_id, MessageType.SUCCESS, activity_name, elapsed=elapsed)
+            self._pop_message_depth()
+            self._message(message)
+
     # Force the resolved XDG variables into the environment,
     # this is so that they can be used directly to specify
     # preferred locations of things from user configuration