本文整理汇总了Python中threading.Condition.wait_for方法的典型用法代码示例。如果您正苦于以下问题:Python Condition.wait_for方法的具体用法?Python Condition.wait_for怎么用?Python Condition.wait_for使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类threading.Condition
的用法示例。
在下文中一共展示了Condition.wait_for方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: __init__
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
class Fork:
def __init__(self):
self.condition = Condition()
self.being_used = False
def use(self, delay):
with self.condition:
self.condition.wait_for(self.can_use)
self.being_used = True
time.sleep(delay)
self.being_used = False
self.condition.notify()
def can_use(self):
return not self.being_used
示例2: ProcessorIteratorCollection
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
class ProcessorIteratorCollection(object):
def __init__(self, processor_iterator_class):
self._processors = {}
self._proc_iter_class = processor_iterator_class
self._condition = Condition()
def __getitem__(self, item):
"""Get a particular ProcessorIterator
:param item (ProcessorType):
:return: (Processor)
"""
with self._condition:
return self._processors[item].next_processor()
def __contains__(self, item):
with self._condition:
return item in self._processors
def __setitem__(self, key, value):
"""Set a ProcessorIterator to a ProcessorType,
if the key is already set, add the processor
to the iterator.
:param key (ProcessorType):
:param value (Processor):
"""
with self._condition:
if key not in self._processors:
proc_iterator = self._proc_iter_class()
proc_iterator.add_processor(value)
self._processors[key] = proc_iterator
else:
self._processors[key].add_processor(value)
self._condition.notify_all()
def __repr__(self):
return ",".join([repr(k) for k in self._processors.keys()])
def wait_to_process(self, item):
with self._condition:
self._condition.wait_for(lambda: item in self)
示例3: __init__
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
class Account:
def __init__(self):
self.condition = Condition()
self.balance = 0
def make_payment(self, amount):
with self.condition:
while not self.can_pay(amount):
self.condition.wait()
self.balance -= amount
self.condition.notify()
def receive_payment(self, amount):
with self.condition:
self.condition.wait_for(self.can_receive)
self.balance += amount
self.condition.notify()
def can_pay(self, amount):
return self.balance > amount
def can_receive(self):
return True
示例4: SC
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
class SC(object):
def __init__(self):
self.events = []
self.event_cond = Condition()
def __call__(self, event):
with self.event_cond:
self.events.append(event)
self.event_cond.notify()
def wait(self, count):
with self.event_cond:
result = self.event_cond.wait_for(lambda: len(self.events) == count, 2)
assert result, "expected %s events, got %s" % (count, len(self.events))
return self.events[:]
示例5: _SendReceiveThread
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
class _SendReceiveThread(Thread):
"""
Internal thread to Stream class that runs the asyncio event loop.
"""
def __init__(self, url, futures):
super(_SendReceiveThread, self).__init__()
self._futures = futures
self._url = url
self._event_loop = None
self._sock = None
self._recv_queue = None
self._send_queue = None
self._context = None
self._condition = Condition()
@asyncio.coroutine
def _receive_message(self):
"""
internal coroutine that receives messages and puts
them on the recv_queue
"""
with self._condition:
self._condition.wait_for(lambda: self._sock is not None)
while True:
msg_bytes = yield from self._sock.recv()
message = validator_pb2.Message()
message.ParseFromString(msg_bytes)
try:
self._futures.set_result(
message.correlation_id,
FutureResult(message_type=message.message_type,
content=message.content))
self._futures.remove(message.correlation_id)
except FutureCollectionKeyError:
# if we are getting an initial message, not a response
self._recv_queue.put_nowait(message)
@asyncio.coroutine
def _send_message(self):
"""
internal coroutine that sends messages from the send_queue
"""
with self._condition:
self._condition.wait_for(lambda: self._send_queue is not None
and self._sock is not None)
while True:
msg = yield from self._send_queue.get()
yield from self._sock.send_multipart([msg.SerializeToString()])
@asyncio.coroutine
def _put_message(self, message):
"""
puts a message on the send_queue. Not to be accessed directly.
:param message: protobuf generated validator_pb2.Message
"""
with self._condition:
self._condition.wait_for(lambda: self._send_queue is not None)
self._send_queue.put_nowait(message)
@asyncio.coroutine
def _get_message(self):
"""
get a message from the recv_queue. Not to be accessed directly.
"""
with self._condition:
self._condition.wait_for(lambda: self._recv_queue is not None)
msg = yield from self._recv_queue.get()
return msg
def put_message(self, message):
"""
:param message: protobuf generated validator_pb2.Message
"""
with self._condition:
self._condition.wait_for(lambda: self._event_loop is not None)
asyncio.run_coroutine_threadsafe(self._put_message(message),
self._event_loop)
def get_message(self):
"""
:return message: protobuf generated validator_pb2.Message
"""
with self._condition:
self._condition.wait_for(lambda: self._event_loop is not None)
return asyncio.run_coroutine_threadsafe(self._get_message(),
self._event_loop).result()
def _exit_tasks(self):
for task in asyncio.Task.all_tasks(self._event_loop):
task.cancel()
def shutdown(self):
self._exit_tasks()
self._event_loop.call_soon_threadsafe(self._event_loop.stop)
self._sock.close()
self._context.destroy()
#.........这里部分代码省略.........
示例6: __init__
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
class ThreadPool:
def __init__(self, n_threads=cpu_count(), local_state={}):
self.threads = [ Thread(target=lambda i=i: self.thread_main(i, deepcopy(local_state)))
for i in range(n_threads) ]
self.queue = []
self.results = []
self.last_req_no = -1
self.last_finished_no = -1
self.done_at_no = -1
self.lock = Lock()
self.thread_cv = Condition(self.lock)
self.iter_cv = Condition(self.lock)
self.exception = None
for thread in self.threads:
thread.start()
def init_thread(self, local_state):
pass
def cleanup_thread(self, local_state):
pass
def execute_task(self, local_state, task):
pass
def thread_main(self, i, local_state):
local_state["thread_no"] = i
self.init_thread(local_state)
try:
while True:
with self.lock:
self.thread_cv.wait_for(lambda: self.queue)
task = self.queue.pop(0)
result = self.execute_task(local_state, task)
with self.lock:
self.results.append(result)
self.last_finished_no += 1
self.iter_cv.notify()
except ExitThread:
pass
except BaseException as e:
with self.lock:
self.exception = e
finally:
self.cleanup_thread(local_state)
def defer(self, task):
with self.lock:
self.done_at_no = -1
self.last_req_no += 1
self.queue.append(task)
self.thread_cv.notify()
def __iter__(self):
with self.lock:
while self.last_finished_no <= self.done_at_no:
self.iter_cv.wait_for(lambda: self.last_finished_no >= self.done_at_no
or self.results or self.exception)
if self.exception:
e = self.exception
self.exception = None
raise e
elif self.results:
yield self.results.pop(0)
else:
break
raise StopIteration()
def done(self):
with self.lock:
self.done_at_no = self.last_req_no
def destroy(self):
for thread in self.threads:
# raise ExitThread in every thread
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(thread.ident),
ctypes.py_object(ExitThread))
with self.lock:
# Wake up all waiting threads to handle exception
self.thread_cv.notify_all()
for thread in self.threads:
thread.join()
if self.exception:
e = self.exception
self.exception = None
raise e
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.destroy()
示例7: NtTestBase
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
class NtTestBase(NetworkTablesInstance):
"""
Object for managing a live pair of NT server/client
"""
_wait_lock = None
_testing_verbose_logging = True
def shutdown(self):
logger.info("shutting down %s", self.__class__.__name__)
NetworkTablesInstance.shutdown(self)
if self._wait_lock is not None:
self._wait_init_listener()
def disconnect(self):
self._api.dispatcher.stop()
def _init_common(self, proto_rev):
# This resets the instance to be independent
self.shutdown()
self._api.dispatcher.setDefaultProtoRev(proto_rev)
self.proto_rev = proto_rev
if self._testing_verbose_logging:
self.enableVerboseLogging()
# self._wait_init()
def _init_server(self, proto_rev, server_port=0):
self._init_common(proto_rev)
self.port = server_port
def _init_client(self, proto_rev):
self._init_common(proto_rev)
def _wait_init(self):
self._wait_lock = Condition()
self._wait = 0
self._wait_init_listener()
def _wait_init_listener(self):
self._api.addEntryListener(
"",
self._wait_cb,
NetworkTablesInstance.NotifyFlags.NEW
| NetworkTablesInstance.NotifyFlags.UPDATE
| NetworkTablesInstance.NotifyFlags.DELETE
| NetworkTablesInstance.NotifyFlags.FLAGS,
)
def _wait_cb(self, *args):
with self._wait_lock:
self._wait += 1
# logger.info('Wait callback, got: %s', args)
self._wait_lock.notify()
@contextmanager
def expect_changes(self, count):
"""Use this on the *other* instance that you're making
changes on, to wait for the changes to propagate to the
other instance"""
if self._wait_lock is None:
self._wait_init()
with self._wait_lock:
self._wait = 0
logger.info("Begin actions")
yield
logger.info("Waiting for %s changes", count)
with self._wait_lock:
result, msg = (
self._wait_lock.wait_for(lambda: self._wait == count, 4),
"Timeout waiting for %s changes (got %s)" % (count, self._wait),
)
logger.info("expect_changes: %s %s", result, msg)
assert result, msg
示例8: ParallelScheduler
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
#.........这里部分代码省略.........
# These transactions have never been scheduled.
for txn_id, txn in self._txns_available.items():
batch = self._batches_by_txn_id[txn_id]
batch_id = batch.header_signature
annotated_batch = self._batches_by_id[batch_id]
if not annotated_batch.preserve:
incomplete_batches.add(batch_id)
# These transactions were in flight.
in_flight = set(self._transactions.keys()).difference(
self._txn_results.keys())
for txn_id in in_flight:
batch = self._batches_by_txn_id[txn_id]
batch_id = batch.header_signature
annotated_batch = self._batches_by_id[batch_id]
if not annotated_batch.preserve:
incomplete_batches.add(batch_id)
# clean up the batches, including partial complete information
for batch_id in incomplete_batches:
annotated_batch = self._batches_by_id[batch_id]
self._batches.remove(annotated_batch.batch)
del self._batches_by_id[batch_id]
for txn in annotated_batch.batch.transactions:
txn_id = txn.header_signature
del self._batches_by_txn_id[txn_id]
if txn_id in self._txn_results:
del self._txn_results[txn_id]
if txn_id in self._txns_available:
del self._txns_available[txn_id]
if txn_id in self._outstanding:
self._outstanding.remove(txn_id)
self._condition.notify_all()
if incomplete_batches:
LOGGER.debug('Removed %s incomplete batches from the schedule',
len(incomplete_batches))
def is_transaction_in_schedule(self, txn_signature):
with self._condition:
return txn_signature in self._batches_by_txn_id
def finalize(self):
with self._condition:
self._final = True
self._condition.notify_all()
def _complete(self):
return self._final and \
len(self._txn_results) == len(self._batches_by_txn_id)
def complete(self, block=True):
with self._condition:
if self._complete():
return True
if block:
return self._condition.wait_for(self._complete)
return False
def __del__(self):
self.cancel()
def __iter__(self):
return SchedulerIterator(self, self._condition)
def count(self):
with self._condition:
return len(self._scheduled)
def get_transaction(self, index):
with self._condition:
return self._scheduled_txn_info[self._scheduled[index]]
def cancel(self):
with self._condition:
if not self._cancelled and not self._final:
contexts = [
tr.context_id for tr in self._txn_results.values()
if tr.context_id
]
self._squash(
self._first_state_hash,
contexts,
persist=False,
clean_up=True)
self._cancelled = True
self._condition.notify_all()
def is_cancelled(self):
with self._condition:
return self._cancelled
示例9: submit_block
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
def submit_block(block):
with context.socket(zmq.PUSH) as sock:
sock.connect(HOST + str(PORT + 1))
sock.send_string(block)
thread = Thread(target=listening_thread)
thread.start()
while True:
if template:
print("Working on template %s" % template["hash"])
task = parse_mining_task(template)
mine(task.block, task.target)
print("Block successfully mined!")
serialized = task.block.serialize()
response = compose_mining_result(serialized)
submit_block(response)
template = None
else:
print("Waiting for work from pool leader.")
with template_received:
template_received.wait_for(lambda: pending_template is not None)
template = pending_template
pending_template = None
示例10: SerialScheduler
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
#.........这里部分代码省略.........
len(incomplete_batches))
def is_transaction_in_schedule(self, txn_signature):
with self._condition:
return txn_signature in self._txn_to_batch
def finalize(self):
with self._condition:
self._final = True
self._condition.notify_all()
def _compute_merkle_root(self, required_state_root):
"""Computes the merkle root of the state changes in the context
corresponding with _last_valid_batch_c_id as applied to
_previous_state_hash.
Args:
required_state_root (str): The merkle root that these txns
should equal.
Returns:
state_hash (str): The merkle root calculated from the previous
state hash and the state changes from the context_id
"""
state_hash = None
if self._previous_valid_batch_c_id is not None:
publishing_or_genesis = self._always_persist or \
required_state_root is None
state_hash = self._squash(
state_root=self._previous_state_hash,
context_ids=[self._previous_valid_batch_c_id],
persist=self._always_persist, clean_up=publishing_or_genesis)
if self._always_persist is True:
return state_hash
if state_hash == required_state_root:
self._squash(state_root=self._previous_state_hash,
context_ids=[self._previous_valid_batch_c_id],
persist=True, clean_up=True)
return state_hash
def _calculate_state_root_if_not_already_done(self):
if not self._already_calculated:
if not self._last_in_batch:
return
last_txn_signature = self._last_in_batch[-1]
batch_id = self._txn_to_batch[last_txn_signature]
required_state_hash = self._required_state_hashes.get(
batch_id)
state_hash = self._compute_merkle_root(required_state_hash)
self._already_calculated = True
for t_id in self._last_in_batch[::-1]:
b_id = self._txn_to_batch[t_id]
if self._batch_statuses[b_id].is_valid:
self._batch_statuses[b_id].state_hash = state_hash
# found the last valid batch, so break out
break
def _calculate_state_root_if_required(self, batch_id):
required_state_hash = self._required_state_hashes.get(
batch_id)
state_hash = None
if required_state_hash is not None:
state_hash = self._compute_merkle_root(required_state_hash)
self._already_calculated = True
return state_hash
def _complete(self):
return self._final and \
len(self._txn_results) == len(self._txn_to_batch)
def complete(self, block):
with self._condition:
if not self._final:
return False
if self._complete():
self._calculate_state_root_if_not_already_done()
return True
if block:
self._condition.wait_for(self._complete)
self._calculate_state_root_if_not_already_done()
return True
return False
def cancel(self):
with self._condition:
if not self._cancelled and not self._final \
and self._previous_context_id:
self._squash(
state_root=self._previous_state_hash,
context_ids=[self._previous_context_id],
persist=False,
clean_up=True)
self._cancelled = True
self._condition.notify_all()
def is_cancelled(self):
with self._condition:
return self._cancelled
示例11: SerialScheduler
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
#.........这里部分代码省略.........
return None
try:
txn = self._txn_queue.get(block=False)
except queue.Empty:
return None
self._in_progress_transaction = txn.header_signature
base_contexts = [] if self._previous_context_id is None \
else [self._previous_context_id]
txn_info = TxnInformation(txn=txn,
state_hash=self._previous_state_hash,
base_context_ids=base_contexts)
self._scheduled_transactions.append(txn_info)
return txn_info
def finalize(self):
with self._condition:
self._final = True
if len(self._batch_statuses) == len(self._last_in_batch):
self._complete = True
self._condition.notify_all()
def _compute_merkle_root(self, required_state_root):
"""Computes the merkle root of the state changes in the context
corresponding with _last_valid_batch_c_id as applied to
_previous_state_hash.
Args:
required_state_root (str): The merkle root that these txns
should equal.
Returns:
state_hash (str): The merkle root calculated from the previous
state hash and the state changes from the context_id
"""
state_hash = None
if self._previous_valid_batch_c_id is not None:
publishing_or_genesis = self._always_persist or \
required_state_root is None
state_hash = self._squash(
state_root=self._previous_state_hash,
context_ids=[self._previous_valid_batch_c_id],
persist=self._always_persist, clean_up=publishing_or_genesis)
if self._always_persist is True:
return state_hash
if state_hash == required_state_root:
self._squash(state_root=self._previous_state_hash,
context_ids=[self._previous_valid_batch_c_id],
persist=True, clean_up=True)
return state_hash
def _calculate_state_root_if_not_already_done(self):
if not self._already_calculated:
if not self._last_in_batch:
return
last_txn_signature = self._last_in_batch[-1]
batch_id = self._txn_to_batch[last_txn_signature]
required_state_hash = self._required_state_hashes.get(
batch_id)
state_hash = self._compute_merkle_root(required_state_hash)
self._already_calculated = True
for t_id in self._last_in_batch[::-1]:
b_id = self._txn_to_batch[t_id]
if self._batch_statuses[b_id].is_valid:
self._batch_statuses[b_id].state_hash = state_hash
# found the last valid batch, so break out
break
def _calculate_state_root_if_required(self, batch_id):
required_state_hash = self._required_state_hashes.get(
batch_id)
state_hash = None
if required_state_hash is not None:
state_hash = self._compute_merkle_root(required_state_hash)
self._already_calculated = True
return state_hash
def complete(self, block):
with self._condition:
if not self._final:
return False
if self._complete:
self._calculate_state_root_if_not_already_done()
return True
if block:
self._condition.wait_for(lambda: self._complete)
self._calculate_state_root_if_not_already_done()
return True
return False
def cancel(self):
with self._condition:
self._cancelled = True
self._condition.notify_all()
def is_cancelled(self):
with self._condition:
return self._cancelled
示例12: TaskExecutor
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
class TaskExecutor(object):
def __init__(self, balancer, index):
self.balancer = balancer
self.index = index
self.task = None
self.proc = None
self.pid = None
self.conn = None
self.state = WorkerState.STARTING
self.key = str(uuid.uuid4())
self.result = AsyncResult()
self.exiting = False
self.thread = gevent.spawn(self.executor)
self.cv = Condition()
self.status_lock = RLock()
def checkin(self, conn):
with self.cv:
self.balancer.logger.debug('Check-in of worker #{0} (key {1})'.format(self.index, self.key))
self.conn = conn
self.state = WorkerState.IDLE
self.cv.notify_all()
def get_status(self):
with self.cv:
self.cv.wait_for(lambda: self.state == WorkerState.EXECUTING)
try:
st = TaskStatus(0)
st.__setstate__(self.conn.call_sync('taskproxy.get_status'))
return st
except RpcException as err:
self.balancer.logger.error(
"Cannot obtain status from task #{0}: {1}".format(self.task.id, str(err))
)
self.terminate()
def put_status(self, status):
with self.cv:
# Try to collect rusage at this point, when process is still alive
try:
kinfo = bsd.kinfo_getproc(self.pid)
self.task.rusage = kinfo.rusage
except LookupError:
pass
if status['status'] == 'ROLLBACK':
self.task.set_state(TaskState.ROLLBACK)
if status['status'] == 'FINISHED':
self.result.set(status['result'])
if status['status'] == 'FAILED':
error = status['error']
cls = TaskException
if error['type'] == 'TaskAbortException':
cls = TaskAbortException
if error['type'] == 'ValidationException':
cls = ValidationException
self.result.set_exception(cls(
code=error['code'],
message=error['message'],
stacktrace=error['stacktrace'],
extra=error.get('extra')
))
def put_warning(self, warning):
self.task.add_warning(warning)
def run(self, task):
with self.cv:
self.cv.wait_for(lambda: self.state == WorkerState.IDLE)
self.result = AsyncResult()
self.task = task
self.task.set_state(TaskState.EXECUTING)
self.state = WorkerState.EXECUTING
self.cv.notify_all()
self.balancer.logger.debug('Actually starting task {0}'.format(task.id))
filename = None
module_name = inspect.getmodule(task.clazz).__name__
for dir in self.balancer.dispatcher.plugin_dirs:
found = False
try:
for root, _, files in os.walk(dir):
file = first_or_default(lambda f: module_name in f, files)
if file:
filename = os.path.join(root, file)
found = True
break
if found:
break
except FileNotFoundError:
continue
try:
#.........这里部分代码省略.........
示例13: Job
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
#.........这里部分代码省略.........
env = BASE_ENV.copy()
env.update(self.environment)
try:
os.execvpe(self.program, self.program_arguments, env)
except:
os._exit(254)
self.logger.debug('Started as PID {0}'.format(pid))
self.pid = pid
self.context.track_pid(self.pid)
self.set_state(JobState.STARTING)
os.waitpid(self.pid, os.WUNTRACED)
os.kill(self.pid, signal.SIGCONT)
def stop(self):
with self.cv:
if self.state == JobState.STOPPED:
return
self.logger.info('Stopping job')
self.set_state(JobState.STOPPING)
if not self.pid:
self.set_state(JobState.STOPPED)
return
try:
os.kill(self.pid, signal.SIGTERM)
except ProcessLookupError:
# Already dead
self.set_state(JobState.STOPPED)
if not self.cv.wait_for(lambda: self.state == JobState.STOPPED, self.exit_timeout):
os.killpg(self.pgid, signal.SIGKILL)
if not self.cv.wait_for(lambda: self.state == JobState.STOPPED, self.exit_timeout):
self.logger.error('Unkillable process {0}'.format(self.pid))
def send_signal(self, signo):
if not self.pid:
return
os.kill(self.pid, signo)
def checkin(self):
with self.cv:
self.logger.info('Service check-in')
if self.supports_checkin:
self.set_state(JobState.RUNNING)
self.context.provide(self.provides)
def push_status(self, status):
with self.cv:
self.status_message = status
self.cv.notify_all()
if self.label == 'org.freenas.dispatcher':
self.context.init_dispatcher()
self.context.emit_event('serviced.job.status', {
'ID': self.id,
'Label': self.label,
'Reason': self.failure_reason,
'Anonymous': self.anonymous,
'Message': self.status_message
示例14: SerialScheduler
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
#.........这里部分代码省略.........
self._last_in_batch = []
self._last_state_hash = first_state_hash
def __iter__(self):
return SchedulerIterator(self, self._condition)
def set_transaction_execution_result(
self, txn_signature, is_valid, context_id):
"""the control flow is that on every valid txn a new state root is
generated. If the txn is invalid the batch status is set,
if the txn is the last txn in the batch, is valid, and no
prior txn failed the batch, the
batch is valid
"""
with self._condition:
if (self._in_progress_transaction is None or
self._in_progress_transaction != txn_signature):
raise ValueError("transaction not in progress: {}",
txn_signature)
self._in_progress_transaction = None
if txn_signature not in self._txn_to_batch:
raise ValueError("transaction not in any batches: {}".format(
txn_signature))
if is_valid:
# txn is valid, get a new state hash
state_hash = self._squash(self._last_state_hash, [context_id])
self._last_state_hash = state_hash
else:
# txn is invalid, preemptively fail the batch
batch_signature = self._txn_to_batch[txn_signature]
self._batch_statuses[batch_signature] = \
BatchExecutionResult(is_valid=is_valid, state_hash=None)
if txn_signature in self._last_in_batch:
batch_signature = self._txn_to_batch[txn_signature]
if batch_signature not in self._batch_statuses:
# because of the else clause above, txn is valid here
self._batch_statuses[batch_signature] = \
BatchExecutionResult(
is_valid=is_valid,
state_hash=self._last_state_hash)
if self._final and self._txn_queue.empty():
self._complete = True
self._condition.notify_all()
def add_batch(self, batch, state_hash=None):
with self._condition:
if self._final:
raise SchedulerError("Scheduler is finalized. Cannnot take"
" new batches")
batch_signature = batch.header_signature
batch_length = len(batch.transactions)
for idx, txn in enumerate(batch.transactions):
if idx == batch_length - 1:
self._last_in_batch.append(txn.header_signature)
self._txn_to_batch[txn.header_signature] = batch_signature
self._txn_queue.put(txn)
def get_batch_execution_result(self, batch_signature):
with self._condition:
return self._batch_statuses.get(batch_signature)
def count(self):
with self._condition:
return len(self._scheduled_transactions)
def get_transaction(self, index):
with self._condition:
return self._scheduled_transactions[index]
def next_transaction(self):
with self._condition:
if self._in_progress_transaction is not None:
return None
try:
txn = self._txn_queue.get(block=False)
except queue.Empty:
return None
self._in_progress_transaction = txn.header_signature
txn_info = TxnInformation(txn, self._last_state_hash)
self._scheduled_transactions.append(txn_info)
return txn_info
def finalize(self):
with self._condition:
self._final = True
self._condition.notify_all()
def complete(self, block):
with self._condition:
if not self._final:
return False
if self._complete:
return True
if block:
self._condition.wait_for(lambda: self._complete)
return True
return False
示例15: _SendReceiveThread
# 需要导入模块: from threading import Condition [as 别名]
# 或者: from threading.Condition import wait_for [as 别名]
class _SendReceiveThread(Thread):
"""
Internal thread to Stream class that runs the asyncio event loop.
"""
def __init__(self, url, futures, ready_event, error_queue):
"""constructor for background thread
:param url (str): the address to connect to the validator on
:param futures (FutureCollection): The Futures associated with
messages sent through Stream.send
:param ready_event (threading.Event): used to notify waiting/asking
classes that the background thread of Stream is ready after
a disconnect event.
"""
super(_SendReceiveThread, self).__init__()
self._futures = futures
self._url = url
self._shutdown = False
self._event_loop = None
self._sock = None
self._monitor_sock = None
self._monitor_fd = None
self._recv_queue = None
self._send_queue = None
self._context = None
self._ready_event = ready_event
self._error_queue = error_queue
self._condition = Condition()
self.identity = _generate_id()[0:16]
@asyncio.coroutine
def _receive_message(self):
"""
internal coroutine that receives messages and puts
them on the recv_queue
"""
while True:
if not self._ready_event.is_set():
break
msg_bytes = yield from self._sock.recv()
message = validator_pb2.Message()
message.ParseFromString(msg_bytes)
try:
self._futures.set_result(
message.correlation_id,
FutureResult(message_type=message.message_type,
content=message.content))
self._futures.remove(message.correlation_id)
except FutureCollectionKeyError:
# if we are getting an initial message, not a response
if not self._ready_event.is_set():
break
self._recv_queue.put_nowait(message)
@asyncio.coroutine
def _send_message(self):
"""
internal coroutine that sends messages from the send_queue
"""
while True:
if not self._ready_event.is_set():
break
msg = yield from self._send_queue.get()
yield from self._sock.send_multipart([msg.SerializeToString()])
@asyncio.coroutine
def _put_message(self, message):
"""
Puts a message on the send_queue. Not to be accessed directly.
:param message: protobuf generated validator_pb2.Message
"""
self._send_queue.put_nowait(message)
@asyncio.coroutine
def _get_message(self):
"""
Gets a message from the recv_queue. Not to be accessed directly.
"""
with self._condition:
self._condition.wait_for(lambda: self._recv_queue is not None)
msg = yield from self._recv_queue.get()
return msg
@asyncio.coroutine
def _monitor_disconnects(self):
"""Monitors the client socket for disconnects
"""
yield from self._monitor_sock.recv_multipart()
self._sock.disable_monitor()
self._monitor_sock.disconnect(self._monitor_fd)
self._monitor_sock.close(linger=0)
self._monitor_sock = None
self._sock.disconnect(self._url)
self._ready_event.clear()
LOGGER.debug("monitor socket received disconnect event")
for future in self._futures.future_values():
future.set_result(FutureError())
for task in asyncio.Task.all_tasks(self._event_loop):
#.........这里部分代码省略.........