Starts the `IOLoop`, runs the given function, and stops the loop. The function must return either an awaitable object or ``None``. If the function returns an awaitable object, the `IOLoop` will run until the awaitable is resolved (and `run_sync()` will return the awa
(self, func: Callable, timeout: Optional[float] = None)
| 453 | raise NotImplementedError() |
| 454 | |
| 455 | def run_sync(self, func: Callable, timeout: Optional[float] = None) -> Any: |
| 456 | """Starts the `IOLoop`, runs the given function, and stops the loop. |
| 457 | |
| 458 | The function must return either an awaitable object or |
| 459 | ``None``. If the function returns an awaitable object, the |
| 460 | `IOLoop` will run until the awaitable is resolved (and |
| 461 | `run_sync()` will return the awaitable's result). If it raises |
| 462 | an exception, the `IOLoop` will stop and the exception will be |
| 463 | re-raised to the caller. |
| 464 | |
| 465 | The keyword-only argument ``timeout`` may be used to set |
| 466 | a maximum duration for the function. If the timeout expires, |
| 467 | a `asyncio.TimeoutError` is raised. |
| 468 | |
| 469 | This method is useful to allow asynchronous calls in a |
| 470 | ``main()`` function:: |
| 471 | |
| 472 | async def main(): |
| 473 | # do stuff... |
| 474 | |
| 475 | if __name__ == '__main__': |
| 476 | IOLoop.current().run_sync(main) |
| 477 | |
| 478 | .. versionchanged:: 4.3 |
| 479 | Returning a non-``None``, non-awaitable value is now an error. |
| 480 | |
| 481 | .. versionchanged:: 5.0 |
| 482 | If a timeout occurs, the ``func`` coroutine will be cancelled. |
| 483 | |
| 484 | .. versionchanged:: 6.2 |
| 485 | ``tornado.util.TimeoutError`` is now an alias to ``asyncio.TimeoutError``. |
| 486 | """ |
| 487 | future_cell = [None] # type: List[Optional[Future]] |
| 488 | |
| 489 | def run() -> None: |
| 490 | try: |
| 491 | result = func() |
| 492 | if result is not None: |
| 493 | from tornado.gen import convert_yielded |
| 494 | |
| 495 | result = convert_yielded(result) |
| 496 | except Exception: |
| 497 | fut = Future() # type: Future[Any] |
| 498 | future_cell[0] = fut |
| 499 | future_set_exc_info(fut, sys.exc_info()) |
| 500 | else: |
| 501 | if is_future(result): |
| 502 | future_cell[0] = result |
| 503 | else: |
| 504 | fut = Future() |
| 505 | future_cell[0] = fut |
| 506 | fut.set_result(result) |
| 507 | assert future_cell[0] is not None |
| 508 | self.add_future(future_cell[0], lambda future: self.stop()) |
| 509 | |
| 510 | self.add_callback(run) |
| 511 | if timeout is not None: |
| 512 |