Cache the individual atom schedulers at compile time
These do not need to be re-fetched/re-examined each time. Change-Id: Ie48100caa12575c725530911ad3d1dc9046e9d26
This commit is contained in:
parent
2fa4af7a24
commit
08c0bbc3e3
@ -52,18 +52,25 @@ class Runtime(object):
|
|||||||
progress=0.0),
|
progress=0.0),
|
||||||
'retry': self.retry_action.change_state,
|
'retry': self.retry_action.change_state,
|
||||||
}
|
}
|
||||||
|
schedulers = {
|
||||||
|
'retry': self.retry_scheduler,
|
||||||
|
'task': self.task_scheduler,
|
||||||
|
}
|
||||||
for atom in self.analyzer.iterate_all_nodes():
|
for atom in self.analyzer.iterate_all_nodes():
|
||||||
metadata = {}
|
metadata = {}
|
||||||
walker = sc.ScopeWalker(self.compilation, atom, names_only=True)
|
walker = sc.ScopeWalker(self.compilation, atom, names_only=True)
|
||||||
if isinstance(atom, task.BaseTask):
|
if isinstance(atom, task.BaseTask):
|
||||||
check_transition_handler = st.check_task_transition
|
check_transition_handler = st.check_task_transition
|
||||||
change_state_handler = change_state_handlers['task']
|
change_state_handler = change_state_handlers['task']
|
||||||
|
scheduler = schedulers['task']
|
||||||
else:
|
else:
|
||||||
check_transition_handler = st.check_retry_transition
|
check_transition_handler = st.check_retry_transition
|
||||||
change_state_handler = change_state_handlers['retry']
|
change_state_handler = change_state_handlers['retry']
|
||||||
|
scheduler = schedulers['retry']
|
||||||
metadata['scope_walker'] = walker
|
metadata['scope_walker'] = walker
|
||||||
metadata['check_transition_handler'] = check_transition_handler
|
metadata['check_transition_handler'] = check_transition_handler
|
||||||
metadata['change_state_handler'] = change_state_handler
|
metadata['change_state_handler'] = change_state_handler
|
||||||
|
metadata['scheduler'] = scheduler
|
||||||
self._atom_cache[atom.name] = metadata
|
self._atom_cache[atom.name] = metadata
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -90,6 +97,14 @@ class Runtime(object):
|
|||||||
def scheduler(self):
|
def scheduler(self):
|
||||||
return sched.Scheduler(self)
|
return sched.Scheduler(self)
|
||||||
|
|
||||||
|
@misc.cachedproperty
|
||||||
|
def task_scheduler(self):
|
||||||
|
return sched.TaskScheduler(self)
|
||||||
|
|
||||||
|
@misc.cachedproperty
|
||||||
|
def retry_scheduler(self):
|
||||||
|
return sched.RetryScheduler(self)
|
||||||
|
|
||||||
@misc.cachedproperty
|
@misc.cachedproperty
|
||||||
def retry_action(self):
|
def retry_action(self):
|
||||||
return ra.RetryAction(self._storage,
|
return ra.RetryAction(self._storage,
|
||||||
@ -110,6 +125,14 @@ class Runtime(object):
|
|||||||
check_transition_handler = metadata['check_transition_handler']
|
check_transition_handler = metadata['check_transition_handler']
|
||||||
return check_transition_handler(current_state, target_state)
|
return check_transition_handler(current_state, target_state)
|
||||||
|
|
||||||
|
def fetch_scheduler(self, atom):
|
||||||
|
"""Fetches the cached specific scheduler for the given atom."""
|
||||||
|
# This does not check if the name exists (since this is only used
|
||||||
|
# internally to the engine, and is not exposed to atoms that will
|
||||||
|
# not exist and therefore doesn't need to handle that case).
|
||||||
|
metadata = self._atom_cache[atom.name]
|
||||||
|
return metadata['scheduler']
|
||||||
|
|
||||||
def fetch_scopes_for(self, atom_name):
|
def fetch_scopes_for(self, atom_name):
|
||||||
"""Fetches a walker of the visible scopes for the given atom."""
|
"""Fetches a walker of the visible scopes for the given atom."""
|
||||||
try:
|
try:
|
||||||
|
@ -17,22 +17,18 @@
|
|||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
from taskflow import exceptions as excp
|
from taskflow import exceptions as excp
|
||||||
from taskflow import retry as retry_atom
|
|
||||||
from taskflow import states as st
|
from taskflow import states as st
|
||||||
from taskflow import task as task_atom
|
|
||||||
from taskflow.types import failure
|
from taskflow.types import failure
|
||||||
|
|
||||||
|
|
||||||
class _RetryScheduler(object):
|
class RetryScheduler(object):
|
||||||
|
"""Schedules retry atoms."""
|
||||||
|
|
||||||
def __init__(self, runtime):
|
def __init__(self, runtime):
|
||||||
self._runtime = weakref.proxy(runtime)
|
self._runtime = weakref.proxy(runtime)
|
||||||
self._retry_action = runtime.retry_action
|
self._retry_action = runtime.retry_action
|
||||||
self._storage = runtime.storage
|
self._storage = runtime.storage
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def handles(atom):
|
|
||||||
return isinstance(atom, retry_atom.Retry)
|
|
||||||
|
|
||||||
def schedule(self, retry):
|
def schedule(self, retry):
|
||||||
"""Schedules the given retry atom for *future* completion.
|
"""Schedules the given retry atom for *future* completion.
|
||||||
|
|
||||||
@ -53,15 +49,13 @@ class _RetryScheduler(object):
|
|||||||
" intention: %s" % intention)
|
" intention: %s" % intention)
|
||||||
|
|
||||||
|
|
||||||
class _TaskScheduler(object):
|
class TaskScheduler(object):
|
||||||
|
"""Schedules task atoms."""
|
||||||
|
|
||||||
def __init__(self, runtime):
|
def __init__(self, runtime):
|
||||||
self._storage = runtime.storage
|
self._storage = runtime.storage
|
||||||
self._task_action = runtime.task_action
|
self._task_action = runtime.task_action
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def handles(atom):
|
|
||||||
return isinstance(atom, task_atom.BaseTask)
|
|
||||||
|
|
||||||
def schedule(self, task):
|
def schedule(self, task):
|
||||||
"""Schedules the given task atom for *future* completion.
|
"""Schedules the given task atom for *future* completion.
|
||||||
|
|
||||||
@ -79,39 +73,28 @@ class _TaskScheduler(object):
|
|||||||
|
|
||||||
|
|
||||||
class Scheduler(object):
|
class Scheduler(object):
|
||||||
"""Schedules atoms using actions to schedule."""
|
"""Safely schedules atoms using a runtime ``fetch_scheduler`` routine."""
|
||||||
|
|
||||||
def __init__(self, runtime):
|
def __init__(self, runtime):
|
||||||
self._schedulers = [
|
self._fetch_scheduler = runtime.fetch_scheduler
|
||||||
_RetryScheduler(runtime),
|
|
||||||
_TaskScheduler(runtime),
|
|
||||||
]
|
|
||||||
|
|
||||||
def _schedule_node(self, node):
|
def schedule(self, atoms):
|
||||||
"""Schedule a single node for execution."""
|
"""Schedules the provided atoms for *future* completion.
|
||||||
for sched in self._schedulers:
|
|
||||||
if sched.handles(node):
|
|
||||||
return sched.schedule(node)
|
|
||||||
else:
|
|
||||||
raise TypeError("Unknown how to schedule '%s' (%s)"
|
|
||||||
% (node, type(node)))
|
|
||||||
|
|
||||||
def schedule(self, nodes):
|
This method should schedule a future for each atom provided and return
|
||||||
"""Schedules the provided nodes for *future* completion.
|
|
||||||
|
|
||||||
This method should schedule a future for each node provided and return
|
|
||||||
a set of those futures to be waited on (or used for other similar
|
a set of those futures to be waited on (or used for other similar
|
||||||
purposes). It should also return any failure objects that represented
|
purposes). It should also return any failure objects that represented
|
||||||
scheduling failures that may have occurred during this scheduling
|
scheduling failures that may have occurred during this scheduling
|
||||||
process.
|
process.
|
||||||
"""
|
"""
|
||||||
futures = set()
|
futures = set()
|
||||||
for node in nodes:
|
for atom in atoms:
|
||||||
|
scheduler = self._fetch_scheduler(atom)
|
||||||
try:
|
try:
|
||||||
futures.add(self._schedule_node(node))
|
futures.add(scheduler.schedule(atom))
|
||||||
except Exception:
|
except Exception:
|
||||||
# Immediately stop scheduling future work so that we can
|
# Immediately stop scheduling future work so that we can
|
||||||
# exit execution early (rather than later) if a single task
|
# exit execution early (rather than later) if a single atom
|
||||||
# fails to schedule correctly.
|
# fails to schedule correctly.
|
||||||
return (futures, [failure.Failure()])
|
return (futures, [failure.Failure()])
|
||||||
return (futures, [])
|
return (futures, [])
|
||||||
|
Loading…
Reference in New Issue
Block a user