Skip to content

Commit b1c40cd

Browse files
committed
stream file directly from bucket; add /version endpoint
this was an attempt to reduce latency by streaming the files directly from google bucket; no performance improvement could be noticed. also add a /version endpoint that outputs just the commit hash of the running server
1 parent eddb78b commit b1c40cd

File tree

5 files changed

+424
-59
lines changed

5 files changed

+424
-59
lines changed

.github/workflows/deploy-prod.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ jobs:
4141
with:
4242
service: "media-server"
4343
image: "vnguyen/openbeta-media-server"
44+
env_vars: |
45+
APP_VERSION=${{ github.sha }}
4446
4547
- name: "Use output"
4648
run: 'curl "${{ steps.deploy.outputs.url }}"'

.github/workflows/deploy-staging.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ jobs:
4343
image: "vnguyen/openbeta-media-server:staging"
4444
env_vars: |
4545
STORAGE_BUCKET=openbeta-staging
46+
APP_VERSION=${{ github.sha }}
4647
4748
- name: "Use output"
4849
run: 'curl "${{ steps.deploy.outputs.url }}"'

app.js

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
1-
const fetch = (...args) =>
2-
import("node-fetch").then(({ default: fetch }) => fetch(...args));
31
const express = require("express");
42
const sharp = require("sharp");
3+
const { Storage, ApiError } = require("@google-cloud/storage");
54

5+
const storage = new Storage();
66
const app = express();
7+
78
const PORT = 8080;
89
const HOST = "0.0.0.0";
910
const BASE_STORAGE_IMAGE_URL = "https://storage.googleapis.com/";
1011
const BUCKET = process.env.STORAGE_BUCKET || "openbeta-prod";
1112

12-
const getImage = (path) =>
13-
fetch(path).then(async (r) => ({
14-
data: await r.arrayBuffer(),
15-
status: r.status,
16-
}));
1713
const getFormat = (webp, avif) => {
1814
return webp ? "webp" : avif ? "avif" : "jpeg";
1915
};
@@ -22,36 +18,44 @@ app.get("/healthy", (req, res) => {
2218
res.send("yep.");
2319
});
2420

21+
app.get("/version", (req, res) => {
22+
res.send(process.env.APP_VERSION);
23+
});
24+
2525
app.get("*", async (req, res) => {
2626
try {
27-
const { searchParams, pathname, href } = new URL(
28-
`${BASE_STORAGE_IMAGE_URL}${BUCKET}${req.url}`,
29-
);
30-
31-
if (!/\.(jpe?g|png|gif|webp)$/i.test(pathname)) {
27+
if (!/\.(jpe?g|png|gif|webp)$/i.test(req.path)) {
3228
return res.status(400).send("Disallowed file extension");
3329
}
3430

3531
const webp = req.headers.accept?.includes("image/webp");
3632
const avif = req.headers.accept?.includes("image/avif");
37-
const quality = Number(searchParams.get("q")) || 90;
38-
const width = Number(searchParams.get("w")) || undefined;
39-
const height = Number(searchParams.get("h")) || undefined;
33+
const quality = Number(req.query.q) || 90;
34+
const width = Number(req.query.w) || undefined;
35+
const height = Number(req.query.h) || undefined;
4036
const format = getFormat(webp, avif);
4137

42-
const { data, status } = await getImage(href);
43-
if (status > 399) {
44-
return res
45-
.status(415)
46-
.send("upstream server did not respond with a valid status code");
47-
}
48-
4938
res
5039
.set("Cache-Control", "public, max-age=15552000")
5140
.set("Vary", "Accept")
5241
.type(`image/${format}`);
5342

54-
sharp(data)
43+
const pipeline = sharp();
44+
45+
storage
46+
.bucket(BUCKET)
47+
.file(req.path.slice(1)) // remove leading slash
48+
.createReadStream()
49+
.on("error", function (e) {
50+
if (e instanceof ApiError) {
51+
if (e.message?.includes("No such object"))
52+
return res.status(404).end();
53+
}
54+
return res.status(500).send(JSON.stringify(e));
55+
})
56+
.pipe(pipeline);
57+
58+
pipeline
5559
.rotate()
5660
.resize({ width, height })
5761
.toFormat(format, { effort: 3, quality, progressive: true })

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
"author": "openbeta.io",
1111
"license": "MIT",
1212
"dependencies": {
13+
"@google-cloud/storage": "^7.5.0",
1314
"express": "^4.18.2",
14-
"node-fetch": "^3.3.2",
1515
"sharp": "^0.32.6"
1616
},
1717
"devDependencies": {

0 commit comments

Comments
 (0)