Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
162825c
Implement abstract Cluster and RPyC connection
vnlitvinov Jul 9, 2020
820997a
Implement cluster spawning based on Ray autoscaler
vnlitvinov Jul 9, 2020
ca81417
Make cloud API import spawner and RPyC on demand only
vnlitvinov Jul 9, 2020
c9d8b27
Clean up modin.experimental.cloud package API
vnlitvinov Jul 9, 2020
7e7e38f
Simplify RayCluster.__run_thread, add verbose error printing
vnlitvinov Jul 10, 2020
aa8cb02
Specify user-defined AWS credentials file
vnlitvinov Jul 10, 2020
28ca2e3
Unify ssh socks proxy support, add MSYS support
vnlitvinov Jul 10, 2020
7a13a69
Make connection to a cluster more long-lived
vnlitvinov Jul 10, 2020
60b8fc8
Fix a few issues
vnlitvinov Jul 13, 2020
5dd2acc
Fix nodes setup
vnlitvinov Jul 13, 2020
9618fc0
Fix getting rpyc connection
vnlitvinov Jul 13, 2020
83d5be0
Use proper timeout waiting
vnlitvinov Jul 13, 2020
f4cd466
Do not steal user std handles for rpyc
vnlitvinov Jul 13, 2020
ff555cc
Make RPyC connection be created when first activated
vnlitvinov Jul 13, 2020
92ece1d
Fix running under WSL
vnlitvinov Jul 13, 2020
46e66f0
Add example script
vnlitvinov Jul 13, 2020
4ec6fe8
Pin RPyC version
vnlitvinov Jul 13, 2020
c63b48e
Catch connection timeout when getting path to rpyc_connect
vnlitvinov Jul 13, 2020
4ed8e48
Remove debug statements
vnlitvinov Jul 13, 2020
e424d08
Return spawning cluster in the background
vnlitvinov Jul 13, 2020
052e3df
Establish RPyC connection more reliably - add retries
vnlitvinov Jul 13, 2020
a1b58d3
Set huge sync request timeout for long Modin operations
vnlitvinov Jul 13, 2020
8fe723f
Rename some entities for improved readability
vnlitvinov Jul 13, 2020
061d77b
Allow connection to be activated much later than created
vnlitvinov Jul 13, 2020
6404bfe
Reworked public API
vnlitvinov Jul 16, 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
35 changes: 35 additions & 0 deletions examples/cluster/experimental_cloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Licensed to Modin Development Team under one or more contributor license agreements.
# See the NOTICE file distributed with this work for additional information regarding
# copyright ownership. The Modin Development Team licenses this file to you under the
# Apache License, Version 2.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.

"""
This is a very basic sample script for running things remotely.
It requires `aws_credentials` file to be present in current working directory.

On credentials file format see https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-where
"""

import logging

import modin.pandas as pd
from modin.experimental.cloud import cluster

# set up verbose logging so Ray autoscaler would print a lot of things
# and we'll see that stuff is alive and kicking
logging.basicConfig(format="%(asctime)s %(message)s")
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

example_cluster = cluster.create("aws", "aws_credentials")
with example_cluster:
remote_df = pd.DataFrame([1, 2, 3, 4])
print(len(remote_df)) # len() is executed remotely
33 changes: 33 additions & 0 deletions modin/experimental/cloud/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Licensed to Modin Development Team under one or more contributor license agreements.
# See the NOTICE file distributed with this work for additional information regarding
# copyright ownership. The Modin Development Team licenses this file to you under the
# Apache License, Version 2.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.

from .base import ClusterError, CannotSpawnCluster, CannotDestroyCluster
from .cluster import Provider, create as create_cluster
from .connection import Connection


def get_connection():
"""
Returns an RPyC connection object to execute Python code remotely on the active cluster.
"""
return Connection.get()


__all__ = [
"ClusterError",
"CannotSpawnCluster",
"CannotDestroyCluster",
"Provider",
"create_cluster",
"get_connection",
]
71 changes: 71 additions & 0 deletions modin/experimental/cloud/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Licensed to Modin Development Team under one or more contributor license agreements.
# See the NOTICE file distributed with this work for additional information regarding
# copyright ownership. The Modin Development Team licenses this file to you under the
# Apache License, Version 2.0 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific language
# governing permissions and limitations under the License.

from typing import NamedTuple
import os
import sys


class ClusterError(Exception):
"""
Generic cluster operating exception
"""

def __init__(self, *args, cause: BaseException = None, traceback: str = None, **kw):
self.cause = cause
self.traceback = traceback
super().__init__(*args, **kw)


class CannotSpawnCluster(ClusterError):
"""
Raised when cluster cannot be spawned in the cloud
"""


class CannotDestroyCluster(ClusterError):
"""
Raised when cluster cannot be destroyed in the cloud
"""


class ConnectionDetails(NamedTuple):
user_name: str = "modin"
key_file: str = None
address: str = None
port: int = 22


_EXT = (".exe", ".com", ".cmd", ".bat", "") if sys.platform == "win32" else ("",)


def _which(prog):
for entry in os.environ["PATH"].split(os.pathsep):
for ext in _EXT:
path = os.path.join(entry, prog + ext)
if os.access(path, os.X_OK):
return path
return None


def _get_ssh_proxy_command():
socks_proxy = os.environ.get("MODIN_SOCKS_PROXY", None)
if socks_proxy is None:
return None
if _which("nc"):
return f"nc -x {socks_proxy} %h %p"
elif _which("connect"):
return f"connect -S {socks_proxy} %h %p"
raise ClusterError(
"SSH through proxy required but no supported proxying tools found"
)
Loading