@@ -444,39 +444,40 @@ def arg_to_cache_key(arg: Hashable) -> Hashable:
444444 deferred : "defer.Deferred[Any]" = defer .Deferred ()
445445 deferreds_map [arg ] = deferred
446446 key = arg_to_cache_key (arg )
447- cache .set (key , deferred , callback = invalidate_callback )
447+ cached_defers .append (
448+ cache .set (key , deferred , callback = invalidate_callback )
449+ )
448450
449451 def complete_all (res : Dict [Hashable , Any ]) -> None :
450- # the wrapped function has completed. It returns a
451- # a dict. We can now resolve the observable deferreds in
452- # the cache and update our own result map .
452+ # the wrapped function has completed. It returns a dict.
453+ # We can now update our own result map, and then resolve the
454+ # observable deferreds in the cache .
453455 for e in missing :
454456 val = res .get (e , None )
455- deferreds_map [e ].callback (val )
457+ # make sure we update the results map before running the
458+ # deferreds, because as soon as we run the last deferred, the
459+ # gatherResults() below will complete and return the result
460+ # dict to our caller.
456461 results [e ] = val
462+ deferreds_map [e ].callback (val )
457463
458- def errback (f : Failure ) -> Failure :
459- # the wrapped function has failed. Invalidate any cache
460- # entries we're supposed to be populating, and fail
461- # their deferreds.
462- for e in missing :
463- key = arg_to_cache_key (e )
464- cache .invalidate (key )
465- deferreds_map [e ].errback (f )
466-
467- # return the failure, to propagate to our caller.
468- return f
464+ def errback_all (f : Failure ) -> None :
465+ # the wrapped function has failed. Propagate the failure into
466+ # the cache, which will invalidate the entry, and cause the
467+ # relevant cached_deferreds to fail, which will propagate the
468+ # failure to our caller.
469+ for d1 in deferreds_map .values ():
470+ d1 .errback (f )
469471
470472 args_to_call = dict (arg_dict )
471473 # copy the missing set before sending it to the callee, to guard against
472474 # modification.
473475 args_to_call [self .list_name ] = tuple (missing )
474476
475- cached_defers .append (
476- defer .maybeDeferred (
477- preserve_fn (self .orig ), ** args_to_call
478- ).addCallbacks (complete_all , errback )
479- )
477+ # dispatch the call, and attach the two handlers
478+ defer .maybeDeferred (
479+ preserve_fn (self .orig ), ** args_to_call
480+ ).addCallbacks (complete_all , errback_all )
480481
481482 if cached_defers :
482483 d = defer .gatherResults (cached_defers , consumeErrors = True ).addCallbacks (
0 commit comments