def test_register_failure(mocker, SETTINGS, WORKERS):
SETTINGS.GITHUB_SECRET = 'notasecret'
from concurrent.futures import Future
future = Future()
future.set_exception(Exception())
register_webhook = mocker.patch(
'jenkins_epo.main.register_webhook',
CoroutineMock(return_value=[future]),
)
mocker.patch('jenkins_epo.main.WORKERS', WORKERS)
from jenkins_epo.main import register
with pytest.raises(SystemExit):
yield from register()
assert WORKERS.start.mock_calls
assert register_webhook.mock_calls
assert WORKERS.terminate.mock_calls
python类Future()的实例源码
def set_exc_info(self, exc_info):
"""Sets the exception information of a ``Future.``
Preserves tracebacks on Python 2.
.. versionadded:: 4.0
"""
self._exc_info = exc_info
self._log_traceback = True
if not _GC_CYCLE_FINALIZERS:
self._tb_logger = _TracebackLogger(exc_info)
try:
self._set_done()
finally:
# Activate the logger after all callbacks have had a
# chance to call result() or exception().
if self._log_traceback and self._tb_logger is not None:
self._tb_logger.activate()
self._exc_info = exc_info
def set_exc_info(self, exc_info):
"""Sets the exception information of a ``Future.``
Preserves tracebacks on Python 2.
.. versionadded:: 4.0
"""
self._exc_info = exc_info
self._log_traceback = True
if not _GC_CYCLE_FINALIZERS:
self._tb_logger = _TracebackLogger(exc_info)
try:
self._set_done()
finally:
# Activate the logger after all callbacks have had a
# chance to call result() or exception().
if self._log_traceback and self._tb_logger is not None:
self._tb_logger.activate()
self._exc_info = exc_info
def set_exc_info(self, exc_info):
"""Sets the exception information of a ``Future.``
Preserves tracebacks on Python 2.
.. versionadded:: 4.0
"""
self._exc_info = exc_info
self._log_traceback = True
if not _GC_CYCLE_FINALIZERS:
self._tb_logger = _TracebackLogger(exc_info)
try:
self._set_done()
finally:
# Activate the logger after all callbacks have had a
# chance to call result() or exception().
if self._log_traceback and self._tb_logger is not None:
self._tb_logger.activate()
self._exc_info = exc_info
def _wait_for_done(self, timeout):
"""
Will not return until either timeout expires or future becomes "done".
There is one potential deadlock situation here:
The deadlock occurs if we await_result while at the same
time, this future needs to await_result from another future
---> To be safe, don't use await_result() in a Qt slot...
"""
if self.cancelled():
raise CancelledError("Future was cancelled") # pragma: no-cover
if not self.done():
self.timer_timeout = None
if (timeout is not None) and timeout > 0:
self._timer_timeout = MainThreadTimer(timeout*1000)
self._timer_timeout.timeout.connect(self._exit_loop)
self._timer_timeout.start()
self.loop = QtCore.QEventLoop()
self.add_done_callback(self._exit_loop)
self.loop.exec_()
if self._timer_timeout is not None:
if not self._timer_timeout.isActive():
return TimeoutError("Timeout occured") # pragma: no-cover
else:
self._timer_timeout.stop()
def message_send(self, to, msg):
"""
Transmit a text message to a recipient.
:param to:
mobile number (without + or 00) or Jid of the recipient
:type to: str
:param msg:
message text to transmit.
:type msg: str|bytes
:return:
future for async notification
"""
if isinstance(msg, str):
msg = msg.encode("utf-8")
outgoingMessage = TextMessageProtocolEntity(msg, to=self.normalize_jid(to))
self.toLower(outgoingMessage)
# Assume successful transmission
fut = Future()
fut.set_result("Done")
return fut
def async_call(self, f: Callable[..., Any], *a: Any, **kw: Any) -> Any:
''' run a callback function on the main thread and return its
value (blocking). the callback receives 'self' as an argument.
'''
if not shutdown:
msg = 'running {} on main thread blocking'
self.log.debug2(lambda: msg.format(format_funcall(f.__name__, a, kw)))
result_fut = futures.Future() # type: futures.Future
@functools.wraps(f)
def cb() -> None:
result_fut.set_result(f(self, *a, **kw))
self._run_on_main_thread(cb)
result = result_fut.result()
self.log.debug2(lambda: f'async returns {result}')
return result
else:
return f(self, *a, **kw)
def parent_callback(self, parent_fu):
''' Callback from executor future to update the parent.
Args:
- executor_fu (Future): Future returned by the executor along with callback
Returns:
- None
Updates the super() with the result() or exception()
'''
if parent_fu.done() is True:
e = parent_fu._exception
if e:
super().set_exception(e)
else:
super().set_result(parent_fu.result())
return
def launch_task(self, task_id, executable, *args, **kwargs):
''' Handle the actual submission of the task to the executor layer
We should most likely add a callback at this point
Args:
task_id (uuid string) : A uuid string that uniquely identifies the task
executable (callable) : A callable object
args (list of positional args)
kwargs (list of keyword args)
Returns:
Future that tracks the execution of the submitted executable
'''
#logger.debug("Submitting to executor : %s", task_id)
exec_fu = self.executor.submit(executable, *args, **kwargs)
exec_fu.add_done_callback(partial(self.handle_update, task_id))
return exec_fu
def parent_callback(self, executor_fu):
''' Callback from executor future to update the parent.
Args:
- executor_fu (Future): Future returned by the executor along with callback
Returns:
- None
Updates the super() with the result() or exception()
'''
if executor_fu.done() == True:
try :
super().set_result(executor_fu.result())
except Exception as e:
super().set_exception(e)
def __init__ (self, parent, tid=None, stdout=None, stderr=None):
''' Initialize the AppFuture.
Args:
- parent (Future) : The parent future if one exists
A default value of None should be passed in if app is not launched
KWargs:
- tid (Int) : Task id should be any unique identifier. Now Int.
- stdout (str) : Stdout file of the app.
Default: None
- stderr (str) : Stderr file of the app.
Default: None
'''
self._tid = tid
super().__init__()
self.parent = parent
#if self.parent:
# parent.add_done_callback(self.parent_callback)
self._outputs = []
self._stdout = stdout
self._stderr = stderr
concurrent.py 文件源码
项目:My-Web-Server-Framework-With-Python2.7
作者: syjsu
项目源码
文件源码
阅读 27
收藏 0
点赞 0
评论 0
def set_exc_info(self, exc_info):
"""Sets the exception information of a ``Future.``
Preserves tracebacks on Python 2.
.. versionadded:: 4.0
"""
self._exc_info = exc_info
self._log_traceback = True
if not _GC_CYCLE_FINALIZERS:
self._tb_logger = _TracebackLogger(exc_info)
try:
self._set_done()
finally:
# Activate the logger after all callbacks have had a
# chance to call result() or exception().
if self._log_traceback and self._tb_logger is not None:
self._tb_logger.activate()
self._exc_info = exc_info
def ensure_future(coro_or_future, *, loop=None):
"""Wrap a coroutine or an awaitable in a future.
If the argument is a Future, it is returned directly.
"""
if futures.isfuture(coro_or_future):
if loop is not None and loop is not coro_or_future._loop:
raise ValueError('loop argument must agree with Future')
return coro_or_future
elif coroutines.iscoroutine(coro_or_future):
if loop is None:
loop = events.get_event_loop()
task = loop.create_task(coro_or_future)
if task._source_traceback:
del task._source_traceback[-1]
return task
elif compat.PY35 and inspect.isawaitable(coro_or_future):
return ensure_future(_wrap_awaitable(coro_or_future), loop=loop)
else:
raise TypeError('A Future, a coroutine or an awaitable is required')
def run_coroutine_threadsafe(coro, loop):
"""Submit a coroutine object to a given event loop.
Return a concurrent.futures.Future to access the result.
"""
if not coroutines.iscoroutine(coro):
raise TypeError('A coroutine object is required')
future = concurrent.futures.Future()
def callback():
try:
futures._chain_future(ensure_future(coro, loop=loop), future)
except Exception as exc:
if future.set_running_or_notify_cancel():
future.set_exception(exc)
raise
loop.call_soon_threadsafe(callback)
return future
def set_exc_info(self, exc_info):
"""Sets the exception information of a ``Future.``
Preserves tracebacks on Python 2.
.. versionadded:: 4.0
"""
self._exc_info = exc_info
self._log_traceback = True
if not _GC_CYCLE_FINALIZERS:
self._tb_logger = _TracebackLogger(exc_info)
try:
self._set_done()
finally:
# Activate the logger after all callbacks have had a
# chance to call result() or exception().
if self._log_traceback and self._tb_logger is not None:
self._tb_logger.activate()
self._exc_info = exc_info
def set_exc_info(self, exc_info):
"""Sets the exception information of a ``Future.``
Preserves tracebacks on Python 2.
.. versionadded:: 4.0
"""
self._exc_info = exc_info
self._log_traceback = True
if not _GC_CYCLE_FINALIZERS:
self._tb_logger = _TracebackLogger(exc_info)
try:
self._set_done()
finally:
# Activate the logger after all callbacks have had a
# chance to call result() or exception().
if self._log_traceback and self._tb_logger is not None:
self._tb_logger.activate()
self._exc_info = exc_info
def close(self):
from threading import Lock
lock = Lock()
count = [0]
future = Future()
def on_close(_):
with lock:
count[0] += 1
if count[0] == len(self.reporters):
future.set_result(True)
for reporter in self.reporters:
f = reporter.close()
f.add_done_callback(on_close)
return future
def _wakeup(self, future):
try:
future.result()
except Exception as exc:
# This may also be a cancellation.
self._step(exc)
else:
# Don't pass the value of `future.result()` explicitly,
# as `Future.__iter__` and `Future.__await__` don't need it.
# If we call `_step(value, None)` instead of `_step()`,
# Python eval loop would use `.send(value)` method call,
# instead of `__next__()`, which is slower for futures
# that return non-generator iterators from their `__iter__`.
self._step()
self = None # Needed to break cycles when an exception occurs.
# wait() and as_completed() similar to those in PEP 3148.
def ensure_future(coro_or_future, *, loop=None):
"""Wrap a coroutine or an awaitable in a future.
If the argument is a Future, it is returned directly.
"""
if isinstance(coro_or_future, futures.Future):
if loop is not None and loop is not coro_or_future._loop:
raise ValueError('loop argument must agree with Future')
return coro_or_future
elif coroutines.iscoroutine(coro_or_future):
if loop is None:
loop = events.get_event_loop()
task = loop.create_task(coro_or_future)
if task._source_traceback:
del task._source_traceback[-1]
return task
elif compat.PY35 and inspect.isawaitable(coro_or_future):
return ensure_future(_wrap_awaitable(coro_or_future), loop=loop)
else:
raise TypeError('A Future, a coroutine or an awaitable is required')
def run_coroutine_threadsafe(coro, loop):
"""Submit a coroutine object to a given event loop.
Return a concurrent.futures.Future to access the result.
"""
if not coroutines.iscoroutine(coro):
raise TypeError('A coroutine object is required')
future = concurrent.futures.Future()
def callback():
try:
futures._chain_future(ensure_future(coro, loop=loop), future)
except Exception as exc:
if future.set_running_or_notify_cancel():
future.set_exception(exc)
raise
loop.call_soon_threadsafe(callback)
return future
def run_in_executor(self, executor, func, *args):
if (coroutines.iscoroutine(func)
or coroutines.iscoroutinefunction(func)):
raise TypeError("coroutines cannot be used with run_in_executor()")
self._check_closed()
if isinstance(func, events.Handle):
assert not args
assert not isinstance(func, events.TimerHandle)
if func._cancelled:
f = futures.Future(loop=self)
f.set_result(None)
return f
func, args = func._callback, func._args
if executor is None:
executor = self._default_executor
if executor is None:
executor = concurrent.futures.ThreadPoolExecutor(_MAX_WORKERS)
self._default_executor = executor
return futures.wrap_future(executor.submit(func, *args), loop=self)
def _create_connection_transport(self, sock, protocol_factory, ssl,
server_hostname):
protocol = protocol_factory()
waiter = futures.Future(loop=self)
if ssl:
sslcontext = None if isinstance(ssl, bool) else ssl
transport = self._make_ssl_transport(
sock, protocol, sslcontext, waiter,
server_side=False, server_hostname=server_hostname)
else:
transport = self._make_socket_transport(sock, protocol, waiter)
try:
yield from waiter
except:
transport.close()
raise
return transport, protocol
def test_restart(self):
self._new_instance = self.mox.CreateMock(instance.Instance)
self.factory.new_instance(0, expect_ready_request=True).AndReturn(
self._new_instance)
f = futures.Future()
f.set_result(True)
module._THREAD_POOL.submit(self.module._start_instance, self._wsgi_server,
self._new_instance).AndReturn(f)
self._instance.quit(force=True)
port = object()
self.mox.ReplayAll()
self.module.restart()
self.mox.VerifyAll()
self.assertEqual(self.module._handle_request,
self._wsgi_server._app.func)
self.assertEqual({'inst': self._new_instance},
self._wsgi_server._app.keywords)
self.assertFalse(self.module._suspended)
def set_exc_info(self, exc_info):
"""Sets the exception information of a ``Future.``
Preserves tracebacks on Python 2.
.. versionadded:: 4.0
"""
self._exc_info = exc_info
self._log_traceback = True
if not _GC_CYCLE_FINALIZERS:
self._tb_logger = _TracebackLogger(exc_info)
try:
self._set_done()
finally:
# Activate the logger after all callbacks have had a
# chance to call result() or exception().
if self._log_traceback and self._tb_logger is not None:
self._tb_logger.activate()
self._exc_info = exc_info
def schedule(self, f, *args, **kwargs):
"""
Try to acquire connection access lock. Then call protocol method.
Return concurrent Future instance you can wait in the other
thread.
"""
self.wait_open()
# RabbitMQ operations are multiplexed between different AMQP
# method callbacks. Final result of the protocol method call
# will be set inside one of this callbacks. So other thread
# will be able to wait unless this event happens in the
# connection event loop.
future = Future()
with self.lock:
self.process(get_ident(), (f, args, kwargs), future)
return future
def set_exc_info(self, exc_info):
"""Sets the exception information of a ``Future.``
Preserves tracebacks on Python 2.
.. versionadded:: 4.0
"""
self._exc_info = exc_info
self._log_traceback = True
if not _GC_CYCLE_FINALIZERS:
self._tb_logger = _TracebackLogger(exc_info)
try:
self._set_done()
finally:
# Activate the logger after all callbacks have had a
# chance to call result() or exception().
if self._log_traceback and self._tb_logger is not None:
self._tb_logger.activate()
self._exc_info = exc_info
def set_exc_info(self, exc_info):
"""Sets the exception information of a ``Future.``
Preserves tracebacks on Python 2.
.. versionadded:: 4.0
"""
self._exc_info = exc_info
self._log_traceback = True
if not _GC_CYCLE_FINALIZERS:
self._tb_logger = _TracebackLogger(exc_info)
try:
self._set_done()
finally:
# Activate the logger after all callbacks have had a
# chance to call result() or exception().
if self._log_traceback and self._tb_logger is not None:
self._tb_logger.activate()
self._exc_info = exc_info
def _coro_runner(self):
while True:
# Wait for a hand-off
await disable_cancellation(_future_wait(self._request))
self._coro = self._request.result()
self._request = Future()
# If no coroutine, we're shutting down
if not self._coro:
break
# Run the the coroutine
try:
self._result_value = await self._coro
self._result_exc = None
except BaseException as e:
self._result_value = None
self._result_exc = e
# Hand it back to the thread
self._done_evt.set()
await self._terminate_evt.set()
def set_exc_info(self, exc_info):
"""Sets the exception information of a ``Future.``
Preserves tracebacks on Python 2.
.. versionadded:: 4.0
"""
self._exc_info = exc_info
self._log_traceback = True
if not _GC_CYCLE_FINALIZERS:
self._tb_logger = _TracebackLogger(exc_info)
try:
self._set_done()
finally:
# Activate the logger after all callbacks have had a
# chance to call result() or exception().
if self._log_traceback and self._tb_logger is not None:
self._tb_logger.activate()
self._exc_info = exc_info
def run_in_executor(self, executor, callback, *args):
if coroutines.iscoroutinefunction(callback):
raise TypeError("Coroutines cannot be used with run_in_executor()")
if isinstance(callback, events.Handle):
assert not args
assert not isinstance(callback, events.TimerHandle)
if callback._cancelled:
f = futures.Future(loop=self)
f.set_result(None)
return f
callback, args = callback._callback, callback._args
if executor is None:
executor = self._default_executor
if executor is None:
executor = concurrent.futures.ThreadPoolExecutor(_MAX_WORKERS)
self._default_executor = executor
return futures.wrap_future(executor.submit(callback, *args), loop=self)