Skip to content

Commit

Permalink
Releasing/1.8.4 extra (#15952)
Browse files Browse the repository at this point in the history
* [App] Remove `SingleProcessRuntime` (#15933)

* Remove SingleProcessRuntime
* Remove unused queues
* Docs

(cherry picked from commit e250dfe)

* [App] Fix bug when using structures with works (#15911)

* Fix bug when using structures with works
* Add test
* Update CHANGELOG.md

(cherry picked from commit 1283226)

* [App] Wait for full file to be transferred in Path / Payload (#15934)

* Wait for full file to be transferred in Path / Payload
* Fixes

(cherry picked from commit b8c7018)

Co-authored-by: Ethan Harris <ethanwharris@gmail.com>
  • Loading branch information
Borda and ethanwharris committed Dec 8, 2022
1 parent a0d3475 commit e0e75d1
Show file tree
Hide file tree
Showing 34 changed files with 160 additions and 231 deletions.
1 change: 0 additions & 1 deletion docs/source-app/api_reference/runners.rst
Expand Up @@ -18,5 +18,4 @@ ______________
:template: classtemplate.rst

~cloud.CloudRuntime
~singleprocess.SingleProcessRuntime
~multiprocess.MultiProcessRuntime
1 change: 0 additions & 1 deletion docs/source-app/api_references.rst
Expand Up @@ -89,7 +89,6 @@ _______
:template: classtemplate_no_index.rst

~cloud.CloudRuntime
~singleprocess.SingleProcessRuntime
~multiprocess.MultiProcessRuntime

----
Expand Down
3 changes: 0 additions & 3 deletions docs/source-app/testing.rst
Expand Up @@ -120,7 +120,6 @@ We provide ``application_testing`` as a helper funtion to get your application u
os.path.join(_PROJECT_ROOT, "examples/app_v0/app.py"),
"--blocking",
"False",
"--multiprocess",
"--open-ui",
"False",
]
Expand All @@ -129,9 +128,7 @@ First in the list for ``command_line`` is the location of your script. It is an

Next there are a couple of options you can leverage:


* ``blocking`` - Blocking is an app status that says "Do not run until I click run in the UI". For our integration test, since we are not using the UI, we are setting this to "False".
* ``multiprocess/singleprocess`` - This is the runtime your app is expected to run under.
* ``open-ui`` - We set this to false since this is the routine that opens a browser for your local execution.

Once you have your commandline ready, you will then be able to kick off the test and gather results:
Expand Down
8 changes: 4 additions & 4 deletions examples/app_template_streamlit_ui/app.py
@@ -1,8 +1,8 @@
import logging

from lightning_app import LightningApp, LightningFlow
from lightning_app.frontend import StreamlitFrontend
from lightning_app.utilities.state import AppState
from lightning.app import LightningApp, LightningFlow
from lightning.app.frontend import StreamlitFrontend
from lightning.app.utilities.state import AppState

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -45,4 +45,4 @@ def configure_layout(self):
return [{"name": "StreamLitUI", "content": self.streamlit_ui}]


app = LightningApp(HelloWorld(), log_level="debug")
app = LightningApp(HelloWorld())
1 change: 0 additions & 1 deletion pyproject.toml
Expand Up @@ -102,7 +102,6 @@ module = [
"lightning_app.runners.cloud",
"lightning_app.runners.multiprocess",
"lightning_app.runners.runtime",
"lightning_app.runners.singleprocess",
"lightning_app.source_code.copytree",
"lightning_app.source_code.hashing",
"lightning_app.source_code.local",
Expand Down
2 changes: 1 addition & 1 deletion requirements/app/base.txt
Expand Up @@ -7,7 +7,7 @@ fsspec>=2022.5.0, <=2022.7.1
croniter>=1.3.0, <1.4.0 # strict; TODO: for now until we find something more robust.
traitlets>=5.3.0, <=5.4.0
arrow>=1.2.0, <1.2.4
lightning-utilities>=0.3.*, !=0.4.0, <0.5.0
lightning-utilities>=0.3.0, !=0.4.0, <0.5.0
beautifulsoup4>=4.8.0, <4.11.2
inquirer>=2.10.0
psutil<5.9.4
Expand Down
2 changes: 1 addition & 1 deletion requirements/lite/base.txt
Expand Up @@ -2,7 +2,7 @@
# in case you want to preserve/enforce restrictions on the latest compatible version, add "strict" as an in-line comment

numpy>=1.17.2, <1.23.1
torch>=1.9.*, <=1.13.0
torch>=1.9.0, <=1.13.0
fsspec[http]>2021.06.0, <2022.6.0
packaging>=17.0, <=21.3
typing-extensions>=4.0.0, <=4.4.0
Expand Down
4 changes: 4 additions & 0 deletions requirements/lite/examples.txt
@@ -0,0 +1,4 @@
# NOTE: the upper bound for the package version is only set for CI stability, and it is dropped while installing this package
# in case you want to preserve/enforce restrictions on the latest compatible version, add "strict" as an in-line comment

torchvision>=0.10.0, <=0.13.0
2 changes: 1 addition & 1 deletion requirements/pytorch/base.txt
Expand Up @@ -2,7 +2,7 @@
# in case you want to preserve/enforce restrictions on the latest compatible version, add "strict" as an in-line comment

numpy>=1.17.2, <1.23.1
torch>=1.9.*, <=1.13.0
torch>=1.9.0, <=1.13.0
tqdm>=4.57.0, <4.65.0
PyYAML>=5.4, <=6.0
fsspec[http]>2021.06.0, <2022.8.0
Expand Down
2 changes: 1 addition & 1 deletion requirements/pytorch/examples.txt
@@ -1,6 +1,6 @@
# NOTE: the upper bound for the package version is only set for CI stability, and it is dropped while installing this package
# in case you want to preserve/enforce restrictions on the latest compatible version, add "strict" as an in-line comment

torchvision>=0.10.*, <=0.13.0
torchvision>=0.10.0, <=0.14.0
gym[classic_control]>=0.17.0, <0.26.3
ipython[all] <8.6.1
9 changes: 8 additions & 1 deletion src/lightning_app/CHANGELOG.md
Expand Up @@ -12,7 +12,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Added the CLI command `lightning run model` to launch a `LightningLite` accelerated script ([#15506](https://github.com/Lightning-AI/lightning/pull/15506))
- Added the CLI command `lightning delete app` to delete a lightning app on the cloud ([#15783](https://github.com/Lightning-AI/lightning/pull/15783))
- Added a CloudMultiProcessBackend which enables running a child App from within the Flow in the cloud ([#15800](https://github.com/Lightning-AI/lightning/pull/15800))
- Apps without UIs no longer activate the "Open App" button when running in the cloud ([#15875](https://github.com/Lightning-AI/lightning/pull/15875))
- Added `AutoScaler` component ([#15769](https://github.com/Lightning-AI/lightning/pull/15769))
- Added the property `ready` of the LightningFlow to inform when the `Open App` should be visible ([#15921](https://github.com/Lightning-AI/lightning/pull/15921))
- Added private work attributed `_start_method` to customize how to start the works ([#15923](https://github.com/Lightning-AI/lightning/pull/15923))
Expand All @@ -26,6 +25,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Show a message when `BuildConfig(requirements=[...])` is passed but a `requirements.txt` file is already present in the Work ([#15799](https://github.com/Lightning-AI/lightning/pull/15799))
- Show a message when `BuildConfig(dockerfile="...")` is passed but a `Dockerfile` file is already present in the Work ([#15799](https://github.com/Lightning-AI/lightning/pull/15799))
- Dropped name column from cluster list ([#15721](https://github.com/Lightning-AI/lightning/pull/15721))
- Apps without UIs no longer activate the "Open App" button when running in the cloud ([#15875](https://github.com/Lightning-AI/lightning/pull/15875))
- Wait for full file to be transferred in Path / Payload ([#15934](https://github.com/Lightning-AI/lightning/pull/15934))

### Removed

- Removed the `SingleProcessRuntime` ([#15933](https://github.com/Lightning-AI/lightning/pull/15933))

### Fixed

Expand All @@ -37,6 +42,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Fixed the `enable_spawn` method of the `WorkRunExecutor` ([#15812](https://github.com/Lightning-AI/lightning/pull/15812))
- Fixed require/import decorator ([#15849](https://github.com/Lightning-AI/lightning/pull/15849))

- Fixed a bug where using `L.app.structures` would cause multiple apps to be opened and fail with an error in the cloud ([#15911](https://github.com/Lightning-AI/lightning/pull/15911))


## [1.8.3] - 2022-11-22

Expand Down
2 changes: 1 addition & 1 deletion src/lightning_app/components/auto_scaler.py
Expand Up @@ -25,7 +25,6 @@
from lightning_app.utilities.packaging.cloud_compute import CloudCompute

logger = Logger(__name__)
lock = asyncio.Lock()


def _raise_granular_exception(exception: Exception) -> None:
Expand Down Expand Up @@ -209,6 +208,7 @@ async def process_request(self, data: BaseModel):
def run(self):

logger.info(f"servers: {self.servers}")
lock = asyncio.Lock()

self._iter = cycle(self.servers)
self._last_batch_sent = time.time()
Expand Down
4 changes: 1 addition & 3 deletions src/lightning_app/core/app.py
Expand Up @@ -21,7 +21,7 @@
FRONTEND_DIR,
STATE_ACCUMULATE_WAIT,
)
from lightning_app.core.queues import BaseQueue, SingleProcessQueue
from lightning_app.core.queues import BaseQueue
from lightning_app.core.work import LightningWork
from lightning_app.frontend import Frontend
from lightning_app.storage import Drive, Path, Payload
Expand Down Expand Up @@ -549,8 +549,6 @@ def _collect_work_finish_status(self) -> dict:
def _should_snapshot(self) -> bool:
if len(self.works) == 0:
return True
elif isinstance(self.delta_queue, SingleProcessQueue):
return True
elif self._has_updated:
work_finished_status = self._collect_work_finish_status()
if work_finished_status:
Expand Down
4 changes: 4 additions & 0 deletions src/lightning_app/core/constants.py
Expand Up @@ -75,3 +75,7 @@ def get_lightning_cloud_url() -> str:

def enable_multiple_works_in_default_container() -> bool:
return bool(int(os.getenv("ENABLE_MULTIPLE_WORKS_IN_DEFAULT_CONTAINER", "0")))


# Number of seconds to wait between filesystem checks when waiting for files in remote storage
REMOTE_STORAGE_WAIT = 0.5
20 changes: 1 addition & 19 deletions src/lightning_app/core/queues.py
Expand Up @@ -49,7 +49,6 @@


class QueuingSystem(Enum):
SINGLEPROCESS = "singleprocess"
MULTIPROCESS = "multiprocess"
REDIS = "redis"
HTTP = "http"
Expand All @@ -59,10 +58,8 @@ def get_queue(self, queue_name: str) -> "BaseQueue":
return MultiProcessQueue(queue_name, default_timeout=STATE_UPDATE_TIMEOUT)
elif self == QueuingSystem.REDIS:
return RedisQueue(queue_name, default_timeout=REDIS_QUEUES_READ_DEFAULT_TIMEOUT)
elif self == QueuingSystem.HTTP:
return HTTPQueue(queue_name, default_timeout=STATE_UPDATE_TIMEOUT)
else:
return SingleProcessQueue(queue_name, default_timeout=STATE_UPDATE_TIMEOUT)
return HTTPQueue(queue_name, default_timeout=STATE_UPDATE_TIMEOUT)

def get_api_response_queue(self, queue_id: Optional[str] = None) -> "BaseQueue":
queue_name = f"{queue_id}_{API_RESPONSE_QUEUE_CONSTANT}" if queue_id else API_RESPONSE_QUEUE_CONSTANT
Expand Down Expand Up @@ -179,21 +176,6 @@ def is_running(self) -> bool:
return True


class SingleProcessQueue(BaseQueue):
def __init__(self, name: str, default_timeout: float):
self.name = name
self.default_timeout = default_timeout
self.queue = queue.Queue()

def put(self, item):
self.queue.put(item)

def get(self, timeout: int = None):
if timeout == 0:
timeout = self.default_timeout
return self.queue.get(timeout=timeout, block=(timeout is None))


class MultiProcessQueue(BaseQueue):
def __init__(self, name: str, default_timeout: float):
self.name = name
Expand Down
2 changes: 0 additions & 2 deletions src/lightning_app/runners/__init__.py
@@ -1,7 +1,6 @@
from lightning_app.runners.cloud import CloudRuntime
from lightning_app.runners.multiprocess import MultiProcessRuntime
from lightning_app.runners.runtime import dispatch, Runtime
from lightning_app.runners.singleprocess import SingleProcessRuntime
from lightning_app.utilities.app_commands import run_app_commands
from lightning_app.utilities.load_app import load_app_from_file

Expand All @@ -11,6 +10,5 @@
"run_app_commands",
"Runtime",
"MultiProcessRuntime",
"SingleProcessRuntime",
"CloudRuntime",
]
7 changes: 2 additions & 5 deletions src/lightning_app/runners/runtime_type.py
@@ -1,21 +1,18 @@
from enum import Enum
from typing import Type, TYPE_CHECKING

from lightning_app.runners import CloudRuntime, MultiProcessRuntime, SingleProcessRuntime
from lightning_app.runners import CloudRuntime, MultiProcessRuntime

if TYPE_CHECKING:
from lightning_app.runners.runtime import Runtime


class RuntimeType(Enum):
SINGLEPROCESS = "singleprocess"
MULTIPROCESS = "multiprocess"
CLOUD = "cloud"

def get_runtime(self) -> Type["Runtime"]:
if self == RuntimeType.SINGLEPROCESS:
return SingleProcessRuntime
elif self == RuntimeType.MULTIPROCESS:
if self == RuntimeType.MULTIPROCESS:
return MultiProcessRuntime
elif self == RuntimeType.CLOUD:
return CloudRuntime
Expand Down
62 changes: 0 additions & 62 deletions src/lightning_app/runners/singleprocess.py

This file was deleted.

2 changes: 2 additions & 0 deletions src/lightning_app/storage/orchestrator.py
Expand Up @@ -105,6 +105,7 @@ def run_once(self, work_name: str) -> None:
name=request.name,
path=maybe_artifact_path,
hash=request.hash,
size=self.fs.info(maybe_artifact_path)["size"],
destination=request.destination,
)
if isinstance(request, _ExistsRequest):
Expand Down Expand Up @@ -139,6 +140,7 @@ def run_once(self, work_name: str) -> None:
path=request.path,
name=request.name,
hash=request.hash,
size=0,
destination=request.destination,
)
if isinstance(request, _ExistsRequest):
Expand Down
9 changes: 5 additions & 4 deletions src/lightning_app/storage/path.py
Expand Up @@ -10,6 +10,7 @@
from fsspec import AbstractFileSystem
from fsspec.implementations.local import LocalFileSystem

from lightning_app.core.constants import REMOTE_STORAGE_WAIT
from lightning_app.core.queues import BaseQueue
from lightning_app.storage.requests import _ExistsRequest, _ExistsResponse, _GetRequest, _GetResponse
from lightning_app.utilities.app_helpers import Logger
Expand Down Expand Up @@ -199,9 +200,8 @@ def get(self, overwrite: bool = False) -> None:
fs = _filesystem()

# 3. Wait until the file appears in shared storage
while not fs.exists(response.path):
# TODO: Existence check on folder is not enough, files may not be completely transferred yet
sleep(0.5)
while not fs.exists(response.path) or fs.info(response.path)["size"] != response.size:
sleep(REMOTE_STORAGE_WAIT)

if self.exists_local() and self.is_dir():
# Delete the directory, otherwise we can't overwrite it
Expand Down Expand Up @@ -340,10 +340,11 @@ def _handle_get_request(work: "LightningWork", request: _GetRequest) -> _GetResp
destination_path = _shared_storage_path() / request.hash
response = _GetResponse(
source=request.source,
name=request.name,
path=str(destination_path),
hash=request.hash,
size=source_path.stat().st_size,
destination=request.destination,
name=request.name,
)

try:
Expand Down
7 changes: 4 additions & 3 deletions src/lightning_app/storage/payload.py
Expand Up @@ -5,6 +5,7 @@
from time import sleep
from typing import Any, Optional, TYPE_CHECKING, Union

from lightning_app.core.constants import REMOTE_STORAGE_WAIT
from lightning_app.core.queues import BaseQueue
from lightning_app.storage.path import _filesystem, _shared_storage_path, Path
from lightning_app.storage.requests import _ExistsRequest, _ExistsResponse, _GetRequest, _GetResponse
Expand Down Expand Up @@ -159,9 +160,8 @@ def get(self) -> Any:
fs = _filesystem()

# 3. Wait until the file appears in shared storage
while not fs.exists(response.path):
# TODO: Existence check on folder is not enough, files may not be completely transferred yet
sleep(0.5)
while not fs.exists(response.path) or fs.info(response.path)["size"] != response.size:
sleep(REMOTE_STORAGE_WAIT)

# 4. Copy the file from the shared storage to the destination on the local filesystem
local_path = self._path
Expand Down Expand Up @@ -234,6 +234,7 @@ def _handle_get_request(work: "LightningWork", request: _GetRequest) -> _GetResp
try:
payload = getattr(work, request.name)
payload.save(payload.value, source_path)
response.size = source_path.stat().st_size
_copy_files(source_path, destination_path)
_logger.debug(f"All files copied from {request.path} to {response.path}.")
except Exception as e:
Expand Down
1 change: 1 addition & 0 deletions src/lightning_app/storage/requests.py
Expand Up @@ -17,6 +17,7 @@ class _GetResponse:
name: str
path: str
hash: str
size: int = 0
destination: str = ""
exception: Optional[Exception] = None
timedelta: Optional[float] = None
Expand Down

0 comments on commit e0e75d1

Please sign in to comment.