docs: def execute(self, action, parameters):
          """
          Execute a DynamoDB action with the given parameters. The method will
          retry requests that failed due to OS level errors or when being
          throttled by DynamoDB.
  
          :param str action: DynamoDB action to invoke
          :param dict parameters: parameters to send into the action
          :rtype: tornado.concurrent.Future
  
          This method creates a future that will resolve to the result
          of calling the specified DynamoDB function.  It does it's best
          to unwrap the response from the function to make life a little
          easier for you.  It does this for the ``GetItem`` and ``Query``
          functions currently.
  
          :raises:
              :exc:`~sprockets_dynamodb.exceptions.DynamoDBException`
              :exc:`~sprockets_dynamodb.exceptions.ConfigNotFound`
              :exc:`~sprockets_dynamodb.exceptions.NoCredentialsError`
              :exc:`~sprockets_dynamodb.exceptions.NoProfileError`
              :exc:`~sprockets_dynamodb.exceptions.TimeoutException`
              :exc:`~sprockets_dynamodb.exceptions.RequestException`
              :exc:`~sprockets_dynamodb.exceptions.InternalFailure`
              :exc:`~sprockets_dynamodb.exceptions.LimitExceeded`
              :exc:`~sprockets_dynamodb.exceptions.MissingParameter`
              :exc:`~sprockets_dynamodb.exceptions.OptInRequired`
              :exc:`~sprockets_dynamodb.exceptions.ResourceInUse`
              :exc:`~sprockets_dynamodb.exceptions.RequestExpired`
              :exc:`~sprockets_dynamodb.exceptions.ResourceNotFound`
              :exc:`~sprockets_dynamodb.exceptions.ServiceUnavailable`
              :exc:`~sprockets_dynamodb.exceptions.ThroughputExceeded`
              :exc:`~sprockets_dynamodb.exceptions.ValidationException`
  
          """
          measurements = collections.deque([], self._max_retries)
          for attempt in range(1, self._max_retries + 1):
              try:
                  result = yield self._execute(
                      action, parameters, attempt, measurements)
              except (exceptions.InternalServerError,
                      exceptions.RequestException,
                      exceptions.ThrottlingException,
                      exceptions.ThroughputExceeded,
                      exceptions.ServiceUnavailable) as error:
                  if attempt == self._max_retries:
                      if self._instrumentation_callback:
                          self._instrumentation_callback(measurements)
                      self._on_exception(error)
                  duration = self._sleep_duration(attempt)
                  self.logger.warning('%r on attempt %i, sleeping %.2f seconds',
                                      error, attempt, duration)
                  yield gen.sleep(duration)
              except exceptions.DynamoDBException as error:
                  if self._instrumentation_callback:
                      self._instrumentation_callback(measurements)
                  self._on_exception(error)
              else:
                  if self._instrumentation_callback:
                      self._instrumentation_callback(measurements)
                  self.logger.debug('%s result: %r', action, result)
                  raise gen.Return(_unwrap_result(action, result))