Beispiel #1
0
    async def with_transaction(
            self,
            callback: Callable[["AsyncClientSession"], Coroutine[Any, Any,
                                                                 Results]],
            *,
            read_concern: Optional[ReadConcern] = None,
            write_concern: Optional[WriteConcern] = None,
            read_preference: Optional[ReadPreferences] = None,
            max_commit_time_ms: Optional[int] = None) -> Results:
        # 99% Of this code from motor's lib

        def _within_time_limit(s: float) -> bool:
            return monotonic_time.time() - s < 120

        def _max_time_expired_error(exc: PyMongoError) -> bool:
            return isinstance(exc, OperationFailure) and exc.code == 50

        start_time = monotonic_time.time()
        while True:
            async with self.start_transaction(
                    read_concern=read_concern,
                    write_concern=write_concern,
                    read_preference=read_preference,
                    max_commit_time_ms=max_commit_time_ms):
                try:
                    ret = await callback(self)
                except Exception as exc:
                    if self.in_transaction:
                        await self.abort_transaction()
                    if (isinstance(exc, PyMongoError) and
                            exc.has_error_label("TransientTransactionError")
                            and _within_time_limit(start_time)):
                        # Retry the entire transaction.
                        continue
                    raise

            if not self.in_transaction:
                # Assume callback intentionally ended the transaction.
                return ret

            while True:
                try:
                    await self.commit_transaction()
                except PyMongoError as exc:
                    if (exc.has_error_label("UnknownTransactionCommitResult")
                            and _within_time_limit(start_time)
                            and not _max_time_expired_error(exc)):
                        # Retry the commit.
                        continue

                    if (exc.has_error_label("TransientTransactionError")
                            and _within_time_limit(start_time)):
                        # Retry the entire transaction.
                        break
                    raise

                # Commit succeeded.
                return ret
Beispiel #2
0
 def sleep(seconds):
     loop = IOLoop.current()
     loop.add_timeout(time.time() + seconds, loop.stop)
     loop.start()
Beispiel #3
0
 def sleep(seconds):
     loop = IOLoop.current()
     loop.add_timeout(time.time() + seconds, loop.stop)
     loop.start()
Beispiel #4
0
 def _within_time_limit(s: float) -> bool:
     return monotonic_time.time() - s < 120