Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3eb6f03
Update setup.py
jrbourbeau Nov 19, 2019
00adbbd
Updates Travis CI builds
jrbourbeau Nov 19, 2019
5b39657
Use conda-forge channel + pip install tblib
jrbourbeau Dec 13, 2019
092323e
Set tblib min version on CI
jrbourbeau Dec 16, 2019
7c4a25e
tblib 1.5.0 is on conda-forge now
jrbourbeau Dec 17, 2019
e72e3e6
Skip stacktrace install on 3.8
jrbourbeau Dec 17, 2019
f1fefad
Merge remote-tracking branch 'upstream/master' into py3.8
jrbourbeau Dec 17, 2019
2046d4f
Garbage collect in test_cleanup_repeated_tasks
jrbourbeau Dec 23, 2019
d7faf5c
Merge branch 'master' of github.com:dask/distributed into py3.8
mrocklin Dec 28, 2019
03df3c7
Merge remote-tracking branch 'upstream/master' into py3.8
jrbourbeau Jan 9, 2020
94672a0
Update appveyor to use Python 3.8
jrbourbeau Jan 9, 2020
8837365
Windows event loop policy
jrbourbeau Jan 9, 2020
287bf59
Update base class for AnyThreadEventLoopPolicy
jrbourbeau Jan 13, 2020
246f59a
Bump appveyor to tornado 6
jrbourbeau Jan 14, 2020
25a5ea1
xfail test_silent_startup
jrbourbeau Jan 14, 2020
16049ff
Merge remote-tracking branch 'upstream/master' into py3.8
jrbourbeau Jan 17, 2020
ee470c4
Add Python 3.8 to GH actions windows builds
jrbourbeau Jan 17, 2020
61f5d13
Avoid reconnecting client after shutdown
mrocklin Jan 21, 2020
0fe9d8b
Merge branch 'py3.8' of github.com:jrbourbeau/distributed into py3.8
mrocklin Jan 21, 2020
7501333
Merge remote-tracking branch 'upstream/master' into py3.8
jrbourbeau Jan 21, 2020
df6a562
Test multiple versions of tornado on Windows
jrbourbeau Jan 21, 2020
b6bfa4a
concurrent.futures.CancelledError is no longer an alias for asyncio.C…
jrbourbeau Jan 26, 2020
d3fb8b1
Use concurrent.futures CancelledError throughout
jrbourbeau Jan 26, 2020
18ec512
Add task shield back
jrbourbeau Jan 27, 2020
cdbba87
Merge remote-tracking branch 'upstream/master' into py3.8
jrbourbeau Feb 3, 2020
52c169f
xfail test_cleanup_repeated_tasks
jrbourbeau Feb 3, 2020
7c9619c
xfail test_pickle_functions
jrbourbeau Feb 3, 2020
e4747b8
Update minimum tornado for Python 3.8
jrbourbeau Feb 4, 2020
36d2c44
Updates based on reviewer feedback
jrbourbeau Feb 11, 2020
eee0c84
xfail test_pause_executor
jrbourbeau Feb 11, 2020
576348f
Merge remote-tracking branch 'upstream/master' into py3.8
jrbourbeau Feb 11, 2020
5b90e98
Update logic around BaseEventLoopPolicy
jrbourbeau Feb 11, 2020
48f5d1a
Install tornado from conda-forge
jrbourbeau Feb 13, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .github/workflows/ci-windows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: windows-latest
strategy:
matrix:
python-version: ["3.6", "3.7"]
python-version: ["3.6", "3.7", "3.8"]

steps:
- name: Checkout source
Expand All @@ -22,6 +22,19 @@ jobs:
activate-environment: testenv
auto-activate-base: false

- name: Install tornado
shell: bash -l {0}
run: |
if [[ "${{ matrix.python-version }}" = "3.8" ]]; then
conda install -c conda-forge tornado=6
else
conda install -c conda-forge tornado=5
fi

- name: List packages in environment
shell: bash -l {0}
run: conda list

- name: Install distributed from source
shell: bash -l {0}
run: python -m pip install -q --no-deps -e .
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ env:
matrix:
- PYTHON=3.6 TESTS=true COVERAGE=true PACKAGES="scikit-learn lz4" TORNADO=5 CRICK=true
- PYTHON=3.7 TESTS=true PACKAGES="scikit-learn python-snappy python-blosc" TORNADO=6
- PYTHON=3.8 TESTS=true PACKAGES="scikit-learn python-snappy python-blosc" TORNADO=6

matrix:
fast_finish: true
Expand Down
1 change: 0 additions & 1 deletion continuous_integration/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ dependencies:
- requests
- toolz
- tblib
- tornado=5
- zict
- fsspec
- pip
Expand Down
19 changes: 12 additions & 7 deletions continuous_integration/travis/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ conda create -q -n test-environment python=$PYTHON
source activate test-environment

# Install dependencies
conda install -q \
conda install -c conda-forge -q \
asyncssh \
bokeh \
click \
coverage \
Expand All @@ -48,15 +49,20 @@ conda install -q \
python=$PYTHON \
requests \
scipy \
tblib \
tblib>=1.5.0 \
toolz \
tornado=$TORNADO \
zstandard \
$PACKAGES

# For low-level profiler, install libunwind and stacktrace from conda-forge
# For stacktrace we use --no-deps to avoid upgrade of python
conda install -c defaults -c conda-forge libunwind zstandard asyncssh
conda install --no-deps -c defaults -c numba -c conda-forge stacktrace
# stacktrace is not currently avaiable for Python 3.8.
# Remove the version check block below when it is avaiable.
if [[ $PYTHON != 3.8 ]]; then
# For low-level profiler, install libunwind and stacktrace from conda-forge
# For stacktrace we use --no-deps to avoid upgrade of python
conda install -c defaults -c conda-forge libunwind
conda install --no-deps -c defaults -c numba -c conda-forge stacktrace
fi;

python -m pip install -q "pytest>=4" pytest-repeat pytest-faulthandler pytest-asyncio

Expand All @@ -67,7 +73,6 @@ python -m pip install -q git+https://github.com/dask/s3fs.git --upgrade --no-dep
python -m pip install -q git+https://github.com/dask/zict.git --upgrade --no-deps
python -m pip install -q sortedcollections msgpack --no-deps
python -m pip install -q keras --upgrade --no-deps
python -m pip install -q asyncssh

if [[ $CRICK == true ]]; then
conda install -q cython
Expand Down
2 changes: 1 addition & 1 deletion distributed/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from .queues import Queue
from .scheduler import Scheduler
from .threadpoolexecutor import rejoin
from .utils import sync, TimeoutError
from .utils import sync, TimeoutError, CancelledError
from .variable import Variable
from .worker import Worker, get_worker, get_client, secede, Reschedule
from .worker_client import local_client, worker_client
Expand Down
8 changes: 5 additions & 3 deletions distributed/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import atexit
from collections import defaultdict
from collections.abc import Iterator
from concurrent.futures import ThreadPoolExecutor, CancelledError
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures._base import DoneAndNotDoneFutures
from contextlib import contextmanager
import copy
Expand Down Expand Up @@ -82,6 +82,7 @@
has_keyword,
format_dashboard_link,
TimeoutError,
CancelledError,
)
from . import versions as version_module

Expand Down Expand Up @@ -1248,6 +1249,7 @@ async def _close(self, fast=False):
""" Send close signal and wait until scheduler completes """
if self.status == "closed":
return

self.status = "closing"

for pc in self._periodic_callbacks.values():
Expand All @@ -1273,7 +1275,7 @@ async def _close(self, fast=False):

# Give the scheduler 'stream-closed' message 100ms to come through
# This makes the shutdown slightly smoother and quieter
with ignoring(AttributeError, CancelledError, TimeoutError):
with ignoring(AttributeError, asyncio.CancelledError, TimeoutError):
await asyncio.wait_for(
asyncio.shield(self._handle_scheduler_coroutine), 0.1
)
Expand Down Expand Up @@ -1310,7 +1312,7 @@ async def _close(self, fast=False):
del self.coroutines[:]

if not fast:
with ignoring(TimeoutError):
with ignoring(TimeoutError, asyncio.CancelledError):
await asyncio.wait_for(asyncio.gather(*coroutines), 2)

with ignoring(AttributeError):
Expand Down
8 changes: 2 additions & 6 deletions distributed/comm/ucx.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import ucp

import logging
import concurrent

import dask
import numpy as np
Expand All @@ -17,7 +16,7 @@
from .core import Comm, Connector, Listener, CommClosedError
from .registry import Backend, backends
from .utils import ensure_concrete_host, to_frames, from_frames
from ..utils import ensure_ip, get_ip, get_ipv6, nbytes, log_errors
from ..utils import ensure_ip, get_ip, get_ipv6, nbytes, log_errors, CancelledError

import dask
import numpy as np
Expand Down Expand Up @@ -170,10 +169,7 @@ async def read(self, deserializers=("cuda", "dask", "pickle", "error")):
await self.ep.recv(is_cudas)
sizes = np.empty(nframes[0], dtype=np.uint64)
await self.ep.recv(sizes)
except (
ucp.exceptions.UCXBaseException,
concurrent.futures._base.CancelledError,
):
except (ucp.exceptions.UCXBaseException, CancelledError):
self.abort()
raise CommClosedError("While reading, the connection was closed")
else:
Expand Down
2 changes: 1 addition & 1 deletion distributed/core.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import asyncio
from collections import defaultdict, deque
from concurrent.futures import CancelledError
from functools import partial
from inspect import isawaitable
import logging
Expand Down Expand Up @@ -35,6 +34,7 @@
PeriodicCallback,
parse_timedelta,
has_keyword,
CancelledError,
)
from . import protocol

Expand Down
7 changes: 7 additions & 0 deletions distributed/deploy/tests/test_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
from threading import Lock
import unittest
import weakref
from distutils.version import LooseVersion

from tornado.ioloop import IOLoop
from tornado import gen
import tornado
import pytest

from dask.system import CPU_COUNT
Expand Down Expand Up @@ -451,6 +453,11 @@ async def test_scale_up_and_down():
assert len(cluster.workers) == 1


@pytest.mark.xfail(
sys.version_info >= (3, 8) and LooseVersion(tornado.version) < "6.0.3",
reason="Known issue with Python 3.8 and Tornado < 6.0.3. See https://github.com/tornadoweb/tornado/pull/2683.",
strict=True,
)
def test_silent_startup():
code = """if 1:
from time import sleep
Expand Down
6 changes: 6 additions & 0 deletions distributed/protocol/tests/test_pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import gc
from operator import add
import weakref
import sys

import pytest

Expand All @@ -23,6 +24,11 @@ def test_pickle_numpy():
assert (loads(dumps(x)) == x).all()


@pytest.mark.xfail(
sys.version_info[:2] == (3, 8),
reason="Sporadic failure on Python 3.8",
strict=False,
)
def test_pickle_functions():
def make_closure():
value = 1
Expand Down
2 changes: 1 addition & 1 deletion distributed/tests/test_as_completed.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from concurrent.futures import CancelledError
from collections.abc import Iterator
from operator import add
import queue
Expand All @@ -9,6 +8,7 @@
from tornado import gen

from distributed.client import _as_completed, as_completed, _first_completed
from distributed.utils import CancelledError
from distributed.utils_test import gen_cluster, inc, throws
from distributed.utils_test import client, cluster_fixture, loop # noqa: F401

Expand Down
2 changes: 1 addition & 1 deletion distributed/tests/test_client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import asyncio
from collections import deque
from concurrent.futures import CancelledError
import gc
import logging
from operator import add
Expand Down Expand Up @@ -38,6 +37,7 @@
profile,
performance_report,
TimeoutError,
CancelledError,
)
from distributed.comm import CommClosedError
from distributed.client import (
Expand Down
2 changes: 1 addition & 1 deletion distributed/tests/test_client_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import time

from concurrent.futures import (
CancelledError,
TimeoutError,
Future,
wait,
Expand All @@ -15,6 +14,7 @@
from toolz import take

from distributed import Client
from distributed.utils import CancelledError
from distributed.utils_test import (
slowinc,
slowadd,
Expand Down
3 changes: 1 addition & 2 deletions distributed/tests/test_failed_workers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from concurrent.futures import CancelledError
import os
import random
from time import sleep
Expand All @@ -12,7 +11,7 @@
from distributed.comm import CommClosedError
from distributed.client import wait
from distributed.metrics import time
from distributed.utils import sync, ignoring
from distributed.utils import sync, ignoring, CancelledError
from distributed.utils_test import (
gen_cluster,
cluster,
Expand Down
5 changes: 5 additions & 0 deletions distributed/tests/test_steal.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,11 @@ def long(delay):
) <= 1


@pytest.mark.xfail(
sys.version_info[:2] == (3, 8),
reason="Sporadic failure on Python 3.8",
strict=False,
)
@gen_cluster(client=True, nthreads=[("127.0.0.1", 5)] * 2)
def test_cleanup_repeated_tasks(c, s, a, b):
class Foo:
Expand Down
3 changes: 1 addition & 2 deletions distributed/tests/test_stress.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from concurrent.futures import CancelledError
from operator import add
import random
import sys
Expand All @@ -12,7 +11,7 @@
from distributed import Client, wait, Nanny
from distributed.config import config
from distributed.metrics import time
from distributed.utils import All, ignoring
from distributed.utils import All, ignoring, CancelledError
from distributed.utils_test import (
gen_cluster,
cluster,
Expand Down
5 changes: 5 additions & 0 deletions distributed/tests/test_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,11 @@ def f(n):


@pytest.mark.slow
@pytest.mark.xfail(
sys.version_info[:2] == (3, 8),
reason="Sporadic failure on Python 3.8",
strict=False,
)
@gen_cluster(
nthreads=[("127.0.0.1", 2)],
client=True,
Expand Down
26 changes: 21 additions & 5 deletions distributed/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import atexit
import click
from collections import deque, OrderedDict, UserDict
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import ThreadPoolExecutor, CancelledError # noqa: F401
from contextlib import contextmanager
import functools
from hashlib import md5
Expand Down Expand Up @@ -1212,11 +1212,27 @@ def reset_logger_locks():
is_kernel_and_no_running_loop = True

if not is_kernel_and_no_running_loop:
import tornado.platform.asyncio

asyncio.set_event_loop_policy(
tornado.platform.asyncio.AnyThreadEventLoopPolicy()
)
# TODO: Use tornado's AnyThreadEventLoopPolicy, instead of class below,
# once tornado > 6.0.3 is available.
if WINDOWS and hasattr(asyncio, "WindowsSelectorEventLoopPolicy"):
# WindowsProactorEventLoopPolicy is not compatible with tornado 6
# fallback to the pre-3.8 default of Selector
# https://github.com/tornadoweb/tornado/issues/2608

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I understand, tornado decided not to do this for users by default. Did Jupyter decided whether or not to do it?

Is appropriate for Dask to me making this decision?

@jrbourbeau jrbourbeau Feb 10, 2020

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tornado decided not to set the event loop policy to asyncio.WindowsSelectorEventLoopPolicy() by default and instead recommends projects do that themselves. Jupyter and several other projects have done this (e.g. jupyter/notebook#5047).

Our situation is a little different because we want to set the event loop policy to tornado's AnyThreadEventLoopPolicy to let us create loops inside of any thread. Tornado has decided to set the base class for AnyThreadEventLoopPolicy to asyncio.WindowsSelectorEventLoopPolicy on Windows (tornadoweb/tornado@d2af6a6), but there hasn't been a release with the those changes yet so we're doing that ourselves here. I'll add a note that we can remove this once the next tornado release is out.

BaseEventLoopPolicy = asyncio.WindowsSelectorEventLoopPolicy
else:
BaseEventLoopPolicy = asyncio.DefaultEventLoopPolicy

class AnyThreadEventLoopPolicy(BaseEventLoopPolicy):
def get_event_loop(self):
try:
return super().get_event_loop()
except (RuntimeError, AssertionError):
loop = self.new_event_loop()
self.set_event_loop(loop)
return loop

asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())


@functools.lru_cache(1000)
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ psutil >= 5.0
sortedcontainers !=2.0.0, !=2.0.1
tblib >= 1.6.0
toolz >= 0.7.4
tornado >= 5
tornado >= 5;python_version<'3.8'
tornado >= 6.0.3;python_version>='3.8'
zict >= 0.1.3
pyyaml
setuptools
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"Programming Language :: Python",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Topic :: Scientific/Engineering",
"Topic :: System :: Distributed Computing",
],
Expand Down