github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/sdk/python/sawtooth_sdk/messaging/future.py (about)

     1  # Copyright 2016 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  from threading import Condition
    17  from threading import RLock
    18  
    19  from sawtooth_sdk.messaging.exceptions import ValidatorConnectionError
    20  import sawtooth_sdk.protobuf.validator_pb2 as validator_pb2
    21  
    22  
    23  class FutureResult(object):
    24      def __init__(self, message_type, content):
    25          self.message_type = message_type
    26          self.content = content
    27  
    28  
    29  class FutureError(object):
    30      """Used when resolving a future, to
    31      set the FutureResult to an error result.
    32      Specifically this raises ValidatorConnectionError
    33      when accessing attributes, but can be made more general.
    34      """
    35  
    36      @property
    37      def content(self):
    38          raise ValidatorConnectionError()
    39  
    40      @property
    41      def message_type(self):
    42          raise ValidatorConnectionError()
    43  
    44  
    45  class Future(object):
    46      def __init__(self, correlation_id, request_type=None):
    47          self.correlation_id = correlation_id
    48          self._result = None
    49          self._condition = Condition()
    50          self._request_type = request_type
    51  
    52      def done(self):
    53          return self._result is not None
    54  
    55      def result(self, timeout=None):
    56          with self._condition:
    57              if self._result is None:
    58                  if not self._condition.wait(timeout):
    59                      message_type = validator_pb2.Message.MessageType.Name(
    60                          self._request_type) if self._request_type else None
    61                      raise FutureTimeoutError(
    62                          'Future timed out waiting for response to {}'.format(
    63                              message_type))
    64          return self._result
    65  
    66      def set_result(self, result):
    67          with self._condition:
    68              self._result = result
    69              self._condition.notify()
    70  
    71  
    72  class FutureCollectionKeyError(Exception):
    73      pass
    74  
    75  
    76  class FutureTimeoutError(Exception):
    77      pass
    78  
    79  
    80  class FutureCollection(object):
    81      def __init__(self):
    82          self._futures = {}
    83          self._lock = RLock()
    84  
    85      def put(self, future):
    86          with self._lock:
    87              self._futures[future.correlation_id] = future
    88  
    89      def set_result(self, correlation_id, result):
    90          with self._lock:
    91              future = self.get(correlation_id)
    92              future.set_result(result)
    93  
    94      def get(self, correlation_id):
    95          with self._lock:
    96              if correlation_id not in self._futures:
    97                  raise FutureCollectionKeyError(
    98                      "no such correlation id: {}".format(correlation_id))
    99              return self._futures[correlation_id]
   100  
   101      def remove(self, correlation_id):
   102          with self._lock:
   103              if correlation_id not in self._futures:
   104                  raise FutureCollectionKeyError(
   105                      "no such correlation id: {}".format(correlation_id))
   106              del self._futures[correlation_id]
   107  
   108      def future_values(self):
   109          with self._lock:
   110              return self._futures.values()