1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
12 def _DefaultErrorHandler(error
):
16 def All(futures
, except_pass
=None, except_pass_log
=False):
17 '''Creates a Future which returns a list of results from each Future in
20 If any Future raises an error other than those in |except_pass| the returned
21 Future will raise as well.
23 If any Future raises an error in |except_pass| then None will be inserted as
24 its result. If |except_pass_log| is True then the exception will be logged.
30 resolved
.append(f
.Get())
31 # "except None" will simply not catch any errors.
34 logging
.error(traceback
.format_exc())
38 return Future(callback
=resolve
)
41 def Race(futures
, except_pass
=None, default
=_no_value
):
42 '''Returns a Future which resolves to the first Future in |futures| that
43 either succeeds or throws an error apart from those in |except_pass|.
45 If all Futures throw errors in |except_pass| then |default| is returned,
46 if specified. If |default| is not specified then one of the passed errors
47 will be re-thrown, for a nice stack trace.
51 for future
in futures
:
52 if first_future
is None:
56 # "except None" will simply not catch any errors.
59 if default
is not _no_value
:
61 # Everything failed and there is no default value, propagate the first
62 # error even though it was caught by |except_pass|.
63 return first_future
.Get()
64 return Future(callback
=resolve
)
68 '''Stores a value, error, or callback to be used later.
70 def __init__(self
, value
=_no_value
, callback
=None, exc_info
=None):
72 self
._callback
= callback
73 self
._exc
_info
= exc_info
74 if (self
._value
is _no_value
and
75 self
._callback
is None and
76 self
._exc
_info
is None):
77 raise ValueError('Must have either a value, error, or callback.')
79 def Then(self
, callback
, error_handler
=_DefaultErrorHandler
):
80 '''Creates and returns a future that runs |callback| on the value of this
81 future, or runs optional |error_handler| if resolving this future results in
84 If |callback| returns a non-Future value then the returned Future will
85 resolve to that value.
87 If |callback| returns a Future then it gets chained to the current Future.
88 This means that the returned Future will resolve to *that* Future's value.
89 This behaviour is transitive.
94 return Future(value=42)
100 return Future(value=x + 1)
102 fortytwo().Then(inc).Get() ==> 43
103 fortytwo().Then(inc_future).Get() ==> 43
104 fortytwo().Then(inc_future).Then(inc_future).Get() ==> 44
110 except Exception as e
:
111 val
= error_handler(e
)
114 return val
.Get() if isinstance(val
, Future
) else val
115 return Future(callback
=then
)
118 '''Gets the stored value, error, or callback contents.
120 if self
._value
is not _no_value
:
122 if self
._exc
_info
is not None:
125 self
._value
= self
._callback
()
128 self
._exc
_info
= sys
.exc_info()
132 exc_info
= self
._exc
_info
133 raise exc_info
[0], exc_info
[1], exc_info
[2]