-
Notifications
You must be signed in to change notification settings - Fork 2
/
app.py
82 lines (72 loc) · 2.74 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# Source: https://github.com/rstudio/py-shiny/blob/7ba8f90a44ee25f41aa8c258eceeba6807e0017a/examples/load_balance/app.py
from shiny import *
import starlette.responses
app_ui = ui.page_fluid(
ui.markdown(
"""
## Sticky load balancing test - Shiny for Python
The purpose of this app is to determine if HTTP requests made by the client are
correctly routed back to the same Python process where the session resides. It
is only useful for testing deployments that load balance traffic across more
than one Python process.
If this test fails, it means that sticky load balancing is not working, and
certain Shiny functionality (like file upload/download or server-side selectize)
are likely to randomly fail.
"""
),
ui.tags.div(
{"class": "card"},
ui.tags.div(
{"class": "card-body font-monospace"},
ui.tags.div("Attempts: ", ui.tags.span("0", id="count")),
ui.tags.div("Status: ", ui.tags.span(id="status")),
ui.output_ui("out"),
),
),
)
def server(input: Inputs, output: Outputs, session: Session):
@output
@render.ui
def out():
# Register a dynamic route for the client to try to connect to.
# It does nothing, just the 200 status code is all that the client
# will care about.
url = session.dynamic_route(
"test",
lambda req: starlette.responses.PlainTextResponse(
"OK", headers={"Cache-Control": "no-cache"}
),
)
# Send JS code to the client to repeatedly hit the dynamic route.
# It will succeed if and only if we reach the correct Python
# process.
return ui.tags.script(
f"""
const url = "{url}";
const count_el = document.getElementById("count");
const status_el = document.getElementById("status");
let count = 0;
async function check_url() {{
count_el.innerHTML = ++count;
try {{
const resp = await fetch(url);
if (!resp.ok) {{
status_el.innerHTML = "Failure!";
return;
}} else {{
status_el.innerHTML = "In progress";
}}
}} catch(e) {{
status_el.innerHTML = "Failure!";
return;
}}
if (count === 100) {{
status_el.innerHTML = "Test complete";
return;
}}
setTimeout(check_url, 10);
}}
check_url();
"""
)
app = App(app_ui, server)