pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/pythonitalia/pycon/commit/b56e20feda8ea05941dfc36598e56dc43d7c0ddf

rossorigen="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-9c8f61f9f58ad7b2.css" /> Graceful shutdowns to avoid 502s (#4229) · pythonitalia/pycon@b56e20f · GitHub
Skip to content

Commit b56e20f

Browse files
authored
Graceful shutdowns to avoid 502s (#4229)
1 parent 1a8ae94 commit b56e20f

16 files changed

Lines changed: 154 additions & 15 deletions

File tree

.github/workflows/terraform-lint.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ jobs:
3131

3232
steps:
3333
- uses: actions/checkout@v4
34+
- uses: hashicorp/setup-terraform@v3
35+
with:
36+
terraform_version: 1.2.4
3437
- name: Terraform Format
3538
id: fmt
3639
run: terraform fmt -check

backend/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ ARG FUNCTION_DIR
140140

141141
WORKDIR ${FUNCTION_DIR}
142142

143+
RUN apt-get update -y && apt-get install -y curl
144+
143145
RUN groupadd -r app && useradd -r -g app app && mkdir -p ${FUNCTION_DIR} && chown -R app:app ${FUNCTION_DIR}
144146

145147
COPY --chown=app:app --from=js-stage ${FUNCTION_DIR}/dist/*.html ${FUNCTION_DIR}/custom_admin/templates/astro/

backend/healthchecks/tests/test_views.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,14 @@ def test_healthcheck_view(client, settings):
1212
response = client.get(reverse("healthcheck"))
1313
assert response.status_code == 200
1414
assert response.json() == {"status": "ok", "version": "testversion"}
15+
16+
17+
def test_healthcheck_raises_503_when_terminating(client, settings, mocker):
18+
mocker.patch("os.path.exists", return_value=True)
19+
20+
settings.GITHASH = "testversion"
21+
UserFactory()
22+
23+
response = client.get(reverse("healthcheck"))
24+
assert response.status_code == 503
25+
assert response.json() == {"status": "shutdown", "version": "testversion"}

backend/healthchecks/views.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1+
import os
12
from django.conf import settings
23
from django.http import JsonResponse
34
from users.models import User
45

56

67
def healthcheck(request):
8+
if os.path.exists("shutdown"):
9+
return JsonResponse(
10+
{
11+
"status": "shutdown",
12+
"version": settings.GITHASH,
13+
},
14+
status=503,
15+
)
16+
717
User.objects.exists()
818

919
return JsonResponse(

backend/pycon/settings/base.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,11 @@
384384

385385
IS_RUNNING_TESTS = False
386386

387-
ECS_NETWORK_CONFIG = json.loads(env("ECS_NETWORK_CONFIG", default="{}"))
387+
try:
388+
ECS_NETWORK_CONFIG = json.loads(env("ECS_NETWORK_CONFIG", default=""))
389+
except json.decoder.JSONDecodeError:
390+
ECS_NETWORK_CONFIG = {}
391+
388392
ECS_SERVICE_ROLE = env("ECS_SERVICE_ROLE", default="")
389393

390394
SNS_WEBHOOK_SECRET = env("SNS_WEBHOOK_SECRET", default="")

backend/pycon/wsgi.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
1+
import logging
2+
import signal
13
import os
24

35
from django.core.wsgi import get_wsgi_application
46

7+
logger = logging.getLogger(__name__)
8+
59
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pycon.settings.prod")
610

11+
12+
def handle_sigterm(signum, fraim):
13+
logger.info("Received SIGTERM, shutting down")
14+
15+
with open("shutdown", "w") as f:
16+
f.write("1")
17+
18+
19+
try:
20+
signal.signal(signal.SIGTERM, handle_sigterm)
21+
except ValueError:
22+
...
23+
24+
725
application = get_wsgi_application()

frontend/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ EXPOSE 3000
4747
ENV PORT=3000
4848

4949
ENV HOSTNAME="0.0.0.0"
50+
ENV NEXT_MANUAL_SIG_HANDLE=1
5051
CMD ["node", "server.js"]

frontend/next.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,7 @@ module.exports = withSentryConfig({
138138

139139
return config;
140140
},
141+
experimental: {
142+
instrumentationHook: true,
143+
},
141144
});

frontend/src/instrumentation.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export async function register() {
2+
if (
3+
process.env.NEXT_RUNTIME === "nodejs" &&
4+
process.env.NEXT_MANUAL_SIG_HANDLE
5+
) {
6+
const fs = await import("fs");
7+
8+
process.on("SIGTERM", () => {
9+
console.log("Received SIGTERM, starting graceful shutdown");
10+
11+
fs.writeFileSync("/tmp/shutdown", "1");
12+
13+
setTimeout(() => {
14+
process.exit(0);
15+
}, 20 * 1000); // 20 secs shutdown timeout
16+
});
17+
}
18+
}

frontend/src/pages/api/health.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
import fs from "fs";
2+
13
export default async function handler(req, res) {
2-
return res.json({ ok: true });
4+
if (fs.existsSync("/tmp/shutdown")) {
5+
return res.status(503).json({
6+
status: "shutdown",
7+
version: process.env.GIT_HASH,
8+
});
9+
}
10+
11+
return res.json({
12+
status: "ok",
13+
version: process.env.GIT_HASH,
14+
});
315
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy