def read(self, count=0, block=True, timeout=None): """Read an item that was processed by one of our threads :note: Triggers task dependency handling needed to provide the necessary input""" # NOTE: we always queue the operation that would give us count items # as tracking the scheduled items or testing the channels size # is in herently unsafe depending on the design of the task network # If we put on tasks onto the queue for every request, we are sure # to always produce enough items, even if the task.min_count actually # provided enough - its better to have some possibly empty task runs # than having and empty queue that blocks. # if the user tries to use us to read from a done task, we will never # compute as all produced items are already in the channel task = self._task_ref() if task is None: return list() # END abort if task was deleted skip_compute = task.is_done() or task.error() ########## prepare ############################## if not skip_compute: self._pool_ref()._prepare_channel_read(task, count) # END prepare pool scheduling ####### read data ######## ########################## # read actual items, tasks were setup to put their output into our channel ( as well ) items = CallbackChannelReader.read(self, count, block, timeout) ########################## return items
def _read(self, count=0, block=True, timeout=None): return CallbackChannelReader.read(self, count, block, timeout)
def __init__(self, channel, task, pool): CallbackChannelReader.__init__(self, channel) self._task_ref = weakref.ref(task) self._pool_ref = weakref.ref(pool)