mirror of
https://github.com/gradio-app/gradio.git
synced 2024-11-21 01:01:05 +08:00
Pass Error status in /dev/reload stream (#8106)
* get error message * Support multiple clients * add changeset * add changeset * add changeset * Display in UI * console.error the python traceback * lint --------- Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
parent
68dcae512c
commit
d0a759f3df
6
.changeset/slow-bats-sniff.md
Normal file
6
.changeset/slow-bats-sniff.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"@gradio/app": patch
|
||||
"gradio": patch
|
||||
---
|
||||
|
||||
feat:Pass Error status in /dev/reload stream
|
@ -137,15 +137,12 @@ def start_server(
|
||||
)
|
||||
reloader = None
|
||||
if GRADIO_WATCH_DIRS:
|
||||
change_event = threading.Event()
|
||||
app.change_event = change_event
|
||||
reloader = SourceFileReloader(
|
||||
app=app,
|
||||
watch_dirs=GRADIO_WATCH_DIRS,
|
||||
watch_module_name=GRADIO_WATCH_MODULE_NAME,
|
||||
demo_name=GRADIO_WATCH_DEMO_NAME,
|
||||
stop_event=threading.Event(),
|
||||
change_event=change_event,
|
||||
demo_file=GRADIO_WATCH_DEMO_PATH,
|
||||
)
|
||||
server = Server(config=config, reloader=reloader)
|
||||
|
@ -19,7 +19,6 @@ import mimetypes
|
||||
import os
|
||||
import posixpath
|
||||
import secrets
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
@ -31,6 +30,7 @@ from typing import (
|
||||
Callable,
|
||||
Dict,
|
||||
List,
|
||||
Literal,
|
||||
Optional,
|
||||
Type,
|
||||
Union,
|
||||
@ -173,7 +173,9 @@ class App(FastAPI):
|
||||
self.queue_token = secrets.token_urlsafe(32)
|
||||
self.startup_events_triggered = False
|
||||
self.uploaded_file_dir = get_upload_folder()
|
||||
self.change_event: None | threading.Event = None
|
||||
self.change_count: int = 0
|
||||
self.change_type: Literal["reload", "error"] | None = None
|
||||
self.reload_error_message: str | None = None
|
||||
self._asyncio_tasks: list[asyncio.Task] = []
|
||||
self.auth_dependency = auth_dependency
|
||||
self.api_info = None
|
||||
@ -284,14 +286,20 @@ class App(FastAPI):
|
||||
heartbeat_rate = 15
|
||||
check_rate = 0.05
|
||||
last_heartbeat = time.perf_counter()
|
||||
current_count = app.change_count
|
||||
|
||||
while True:
|
||||
if await request.is_disconnected():
|
||||
return
|
||||
|
||||
if app.change_event and app.change_event.is_set():
|
||||
app.change_event.clear()
|
||||
yield """event: reload\ndata: {}\n\n"""
|
||||
if app.change_count != current_count:
|
||||
current_count = app.change_count
|
||||
msg = (
|
||||
json.dumps(f"{app.reload_error_message}")
|
||||
if app.change_type == "error"
|
||||
else "{}"
|
||||
)
|
||||
yield f"""event: {app.change_type}\ndata: {msg}\n\n"""
|
||||
|
||||
await asyncio.sleep(check_rate)
|
||||
if time.perf_counter() - last_heartbeat > heartbeat_rate:
|
||||
|
@ -38,6 +38,7 @@ from typing import (
|
||||
Generic,
|
||||
Iterable,
|
||||
Iterator,
|
||||
Literal,
|
||||
Optional,
|
||||
TypeVar,
|
||||
)
|
||||
@ -123,7 +124,6 @@ class SourceFileReloader(BaseReloader):
|
||||
watch_module_name: str,
|
||||
demo_file: str,
|
||||
stop_event: threading.Event,
|
||||
change_event: threading.Event,
|
||||
demo_name: str = "demo",
|
||||
) -> None:
|
||||
super().__init__()
|
||||
@ -131,7 +131,6 @@ class SourceFileReloader(BaseReloader):
|
||||
self.watch_dirs = watch_dirs
|
||||
self.watch_module_name = watch_module_name
|
||||
self.stop_event = stop_event
|
||||
self.change_event = change_event
|
||||
self.demo_name = demo_name
|
||||
self.demo_file = Path(demo_file)
|
||||
|
||||
@ -145,8 +144,9 @@ class SourceFileReloader(BaseReloader):
|
||||
def stop(self) -> None:
|
||||
self.stop_event.set()
|
||||
|
||||
def alert_change(self):
|
||||
self.change_event.set()
|
||||
def alert_change(self, change_type: Literal["reload", "error"] = "reload"):
|
||||
self.app.change_type = change_type
|
||||
self.app.change_count += 1
|
||||
|
||||
def swap_blocks(self, demo: Blocks):
|
||||
old_blocks = self.running_app.blocks
|
||||
@ -154,7 +154,7 @@ class SourceFileReloader(BaseReloader):
|
||||
if old_blocks:
|
||||
reassign_keys(old_blocks, demo)
|
||||
demo.config = demo.get_config_file()
|
||||
self.alert_change()
|
||||
self.alert_change("reload")
|
||||
|
||||
|
||||
NO_RELOAD = True
|
||||
@ -281,6 +281,8 @@ def watchfn(reloader: SourceFileReloader):
|
||||
)
|
||||
traceback.print_exc()
|
||||
mtimes = {}
|
||||
reloader.alert_change("error")
|
||||
reloader.app.reload_error_message = traceback.format_exc()
|
||||
continue
|
||||
demo = getattr(module, reloader.demo_name)
|
||||
reloader.swap_blocks(demo)
|
||||
|
@ -154,6 +154,13 @@
|
||||
};
|
||||
}
|
||||
|
||||
export function add_new_message(
|
||||
message: string,
|
||||
type: ToastMessage["type"]
|
||||
): void {
|
||||
messages = [new_message(message, -1, type), ...messages];
|
||||
}
|
||||
|
||||
let _error_id = -1;
|
||||
|
||||
let user_left_page = false;
|
||||
|
@ -302,6 +302,11 @@
|
||||
const { host } = new URL(api_url);
|
||||
let url = new URL(`http://${host}/dev/reload`);
|
||||
eventSource = new EventSource(url);
|
||||
eventSource.addEventListener("error", async (e) => {
|
||||
new_message_fn("Error reloading app", "error");
|
||||
// @ts-ignore
|
||||
console.error(JSON.parse(e.data));
|
||||
});
|
||||
eventSource.addEventListener("reload", async (event) => {
|
||||
app.close();
|
||||
app = await Client.connect(api_url, {
|
||||
@ -372,6 +377,8 @@
|
||||
}
|
||||
};
|
||||
|
||||
let new_message_fn: (message: string, type: string) => void;
|
||||
|
||||
onMount(async () => {
|
||||
intersecting.register(_id, wrapper);
|
||||
});
|
||||
@ -449,6 +456,7 @@
|
||||
{autoscroll}
|
||||
bind:ready
|
||||
bind:render_complete
|
||||
bind:add_new_message={new_message_fn}
|
||||
show_footer={!is_embed}
|
||||
{app_mode}
|
||||
{version}
|
||||
|
Loading…
Reference in New Issue
Block a user