Skip to content

Commit 6e4a5a3

Browse files
committed
-
1 parent 23677eb commit 6e4a5a3

File tree

2 files changed

+41
-11
lines changed

2 files changed

+41
-11
lines changed

source_py3/python_toolbox/future_tools.py

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,34 @@ def filter(self, filter_function, iterable, timeout=None,
1212
as_completed=False):
1313
'''Get a parallelized version of filter(filter_function, iterable).'''
1414

15-
sequence = sequence_tools.ensure_iterable_is_sequence(iterable)
16-
return (
17-
item for (item, keep) in zip(
18-
sequence,
19-
self.map(filter_function, sequence, timeout=timeout,
20-
as_completed=as_completed)
21-
) if keep
22-
)
15+
if timeout is not None:
16+
end_time = timeout + time.time()
17+
18+
def make_future(item):
19+
future = self.submit(filter_function, item)
20+
future._item = item
21+
return future
22+
23+
futures = tuple(map(make_future, iterable))
24+
futures_iterator = concurrent.futures.as_completed(futures) if \
25+
as_completed else futures
26+
27+
# Yield must be hidden in closure so that the futures are submitted
28+
# before the first iterator value is required.
29+
def result_iterator():
30+
try:
31+
for future in futures_iterator:
32+
if timeout is None:
33+
result = future.result()
34+
else:
35+
result = future.result(end_time - time.time())
36+
if result:
37+
yield future._item
38+
finally:
39+
for future in futures:
40+
future.cancel()
41+
return result_iterator()
42+
2343

2444
def map(self, function, *iterables, timeout=None, as_completed=False):
2545
'''Get a parallelized version of map(function, iterable).'''
@@ -35,7 +55,7 @@ def map(self, function, *iterables, timeout=None, as_completed=False):
3555
# before the first iterator value is required.
3656
def result_iterator():
3757
try:
38-
for future in futures:
58+
for future in futures_iterator:
3959
if timeout is None:
4060
yield future.result()
4161
else:

source_py3/test_python_toolbox/test_future_tools/test_future_tools.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def sleep_and_return(seconds):
1414
return seconds
1515

1616

17-
with future_tools.CuteThreadPoolExecutor(5) as executor:
17+
with future_tools.CuteThreadPoolExecutor(10) as executor:
1818
assert isinstance(executor, future_tools.CuteThreadPoolExecutor)
1919
assert tuple(executor.filter(lambda x: (x % 2 == 0), range(10))) == \
2020
tuple(range(0, 10, 2))
@@ -23,7 +23,17 @@ def sleep_and_return(seconds):
2323
list(range(0, 10, 2))
2424
assert tuple(executor.filter(
2525
lambda x: (sleep_and_return(x) % 2 == 0), range(9, -1, -1),
26-
as_completed=True)) == (range(0, 10, 2))
26+
as_completed=True)) == tuple(range(0, 10, 2))
27+
28+
29+
assert tuple(executor.map(lambda x: x % 3, range(10))) == \
30+
(0, 1, 2, 0, 1, 2, 0, 1, 2, 0)
31+
assert sorted(executor.map(lambda x: x % 3, range(10),
32+
timeout=10**5, as_completed=True)) == \
33+
[0, 0, 0, 0, 1, 1, 1, 2, 2, 2]
34+
35+
assert tuple(executor.map(sleep_and_return, range(9, -1, -1),
36+
as_completed=True)) == tuple(range(10))
2737

2838

2939

0 commit comments

Comments
 (0)