On Sun, Oct 14, 2012 at 10:27 AM, Terry Reedy tjreedy@udel.edu wrote:
On 10/14/2012 10:36 AM, Guido van Rossum wrote:
So, can par() be as simple as
def par(*args): results = [] for task in args: result = yield from task results.append(result) return results
???
Or does it need to interact with the scheduler to ensure fairness? (Not having built one of these, my intuition for how the primitives fit together is still lacking, so excuse me for asking naive questions.)
Of course there's the question of what to do when one of the tasks raises an error -- I haven't quite figured that out in NDB either, it runs all the tasks to completion but the caller only sees the first exception. I briefly considered having an "multi-exception" but it felt too weird -- though I'm not married to that decision.
One answer is to append the exception object to results and let the requesting code sort out what to do.
def par(*args): results = [] for task in args: try:
result = yield from task results.append(result) except Exception as exc: results.append(exc)
return results
But then the caller would have to sort through the results and check for exceptions. I want the caller to be able to use try/except as well.
So far the best I've come up with is to recommend that if you care about distinguishing multiple exceptions, use separate yields surrounded by separate try/except blocks. Note that the tasks can still run concurrently, just create all the futures before doing the first yield.