|
49 | 49 | """ |
50 | 50 | import abc |
51 | 51 | import importlib |
| 52 | +import inspect |
52 | 53 | from typing import Any, Callable, Optional, Protocol, Sequence, Tuple, runtime_checkable |
53 | 54 |
|
54 | 55 | import kafka.errors as Errors |
@@ -207,10 +208,6 @@ def call_soon(self, task: Any) -> Any: |
207 | 208 | deferred-handle box). |
208 | 209 | """ |
209 | 210 |
|
210 | | - @abc.abstractmethod |
211 | | - def call_soon_with_future(self, coro: Any, *args: Any) -> NetBackendFuture: |
212 | | - """Schedule ``coro`` and return a future that resolves with its result.""" |
213 | | - |
214 | 211 | @abc.abstractmethod |
215 | 212 | def call_at(self, when: float, task: Any) -> Any: |
216 | 213 | """Schedule ``task`` to run at absolute monotonic time ``when``.""" |
@@ -334,6 +331,33 @@ def wait_for(self, future: Any, timeout_ms: Optional[float], raise_error: bool=T |
334 | 331 | if raise_error: |
335 | 332 | raise |
336 | 333 |
|
| 334 | + async def _invoke(self, coro, *args): |
| 335 | + """Invoke coro/awaitable/function and fully resolve the result.""" |
| 336 | + if inspect.iscoroutinefunction(coro): |
| 337 | + result = await coro(*args) |
| 338 | + elif hasattr(coro, '__await__'): |
| 339 | + result = await coro |
| 340 | + else: |
| 341 | + result = coro(*args) |
| 342 | + if inspect.iscoroutine(result) or hasattr(result, '__await__'): |
| 343 | + result = await result |
| 344 | + while isinstance(result, NetBackendFuture): |
| 345 | + result = await result |
| 346 | + return result |
| 347 | + |
| 348 | + def call_soon_with_future(self, coro: Any, *args: Any) -> NetBackendFuture: |
| 349 | + """Schedule ``coro`` and return a future that resolves with its result.""" |
| 350 | + if hasattr(coro, '__await__') and args: |
| 351 | + raise ValueError('initiated coroutine does not accept args') |
| 352 | + future = self.create_future() |
| 353 | + async def wrapper(): |
| 354 | + try: |
| 355 | + future.success(await self._invoke(coro, *args)) |
| 356 | + except BaseException as exc: |
| 357 | + future.failure(exc) |
| 358 | + self.call_soon(wrapper) |
| 359 | + return future |
| 360 | + |
337 | 361 |
|
338 | 362 | # --- backend selection ---------------------------------------------------- |
339 | 363 |
|
|
0 commit comments