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