github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/sawtooth_validator/concurrent/threadpool.py (about)

     1  # Copyright 2017 Intel Corporation
     2  #
     3  # Licensed under the Apache License, Version 2.0 (the "License");
     4  # you may not use this file except in compliance with the License.
     5  # You may obtain a copy of the License at
     6  #
     7  #     http://www.apache.org/licenses/LICENSE-2.0
     8  #
     9  # Unless required by applicable law or agreed to in writing, software
    10  # distributed under the License is distributed on an "AS IS" BASIS,
    11  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  # See the License for the specific language governing permissions and
    13  # limitations under the License.
    14  # ------------------------------------------------------------------------------
    15  
    16  import logging
    17  import os
    18  
    19  from concurrent.futures import ThreadPoolExecutor
    20  
    21  from sawtooth_validator import metrics
    22  
    23  
    24  LOGGER = logging.getLogger(__name__)
    25  COLLECTOR = metrics.get_collector(__name__)
    26  
    27  
    28  class InstrumentedThreadPoolExecutor(ThreadPoolExecutor):
    29      def __init__(self, max_workers=None, name='', trace=None):
    30          if trace is None:
    31              self._trace = 'SAWTOOTH_TRACE_LOGGING' in os.environ
    32          else:
    33              self._trace = trace
    34  
    35          self._name = name
    36          if name == '':
    37              self._name = 'Instrumented'
    38  
    39          LOGGER.debug('Creating thread pool executor %s', self._name)
    40  
    41          super().__init__(max_workers)
    42  
    43          self._workers_in_use = COLLECTOR.counter(
    44              "workers_in_use",
    45              instance=self,
    46              tags={"name": self._name})
    47          # Tracks how long tasks take to run
    48          self._task_run_timer = COLLECTOR.timer(
    49              "task_run_time",
    50              instance=self,
    51              tags={"name": self._name})
    52          # Tracks how long tasks wait in the queue
    53          self._task_time_in_queue_timer = COLLECTOR.timer(
    54              "task_time_in_queue",
    55              instance=self,
    56              tags={"name": self._name})
    57  
    58      def submit(self, fn, *args, **kwargs):
    59          time_in_queue_ctx = self._task_time_in_queue_timer.time()
    60  
    61          try:
    62              task_name = fn.__qualname__
    63          except AttributeError:
    64              task_name = str(fn)
    65  
    66          if self._trace:
    67              task_details = '{}[{},{}]'.format(fn, args, kwargs)
    68          else:
    69              task_details = task_name
    70  
    71          def wrapper():
    72              time_in_queue_ctx.stop()
    73  
    74              self._workers_in_use.inc()
    75  
    76              if self._trace:
    77                  LOGGER.debug(
    78                      '(%s) Executing task %s', self._name, task_details)
    79  
    80              with self._task_run_timer.time():
    81                  return_value = None
    82                  try:
    83                      return_value = fn(*args, **kwargs)
    84                  # pylint: disable=broad-except
    85                  except Exception:
    86                      LOGGER.exception(
    87                          '(%s) Unhandled exception during execution of task %s',
    88                          self._name,
    89                          task_details)
    90  
    91                  self._workers_in_use.dec()
    92  
    93                  if self._trace:
    94                      LOGGER.debug(
    95                          '(%s) Finished task %s', self._name, task_details)
    96  
    97                  return return_value
    98  
    99          return super().submit(wrapper)