Skip to content

Commit

Permalink
stream file directly from bucket; add /version endpoint
Browse files Browse the repository at this point in the history
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
  • Loading branch information
enapupe committed Nov 5, 2023
1 parent eddb78b commit b1c40cd
Show file tree
Hide file tree
Showing 5 changed files with 424 additions and 59 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ jobs:
with:
service: "media-server"
image: "vnguyen/openbeta-media-server"
env_vars: |
APP_VERSION=${{ github.sha }}
- name: "Use output"
run: 'curl "${{ steps.deploy.outputs.url }}"'
1 change: 1 addition & 0 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:
image: "vnguyen/openbeta-media-server:staging"
env_vars: |
STORAGE_BUCKET=openbeta-staging
APP_VERSION=${{ github.sha }}
- name: "Use output"
run: 'curl "${{ steps.deploy.outputs.url }}"'
50 changes: 27 additions & 23 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
const fetch = (...args) =>
import("node-fetch").then(({ default: fetch }) => fetch(...args));
const express = require("express");
const sharp = require("sharp");
const { Storage, ApiError } = require("@google-cloud/storage");

const storage = new Storage();
const app = express();

const PORT = 8080;
const HOST = "0.0.0.0";
const BASE_STORAGE_IMAGE_URL = "https://storage.googleapis.com/";
const BUCKET = process.env.STORAGE_BUCKET || "openbeta-prod";

const getImage = (path) =>
fetch(path).then(async (r) => ({
data: await r.arrayBuffer(),
status: r.status,
}));
const getFormat = (webp, avif) => {
return webp ? "webp" : avif ? "avif" : "jpeg";
};
Expand All @@ -22,36 +18,44 @@ app.get("/healthy", (req, res) => {
res.send("yep.");
});

app.get("/version", (req, res) => {
res.send(process.env.APP_VERSION);
});

app.get("*", async (req, res) => {
try {
const { searchParams, pathname, href } = new URL(
`${BASE_STORAGE_IMAGE_URL}${BUCKET}${req.url}`,
);

if (!/\.(jpe?g|png|gif|webp)$/i.test(pathname)) {
if (!/\.(jpe?g|png|gif|webp)$/i.test(req.path)) {
return res.status(400).send("Disallowed file extension");
}

const webp = req.headers.accept?.includes("image/webp");
const avif = req.headers.accept?.includes("image/avif");
const quality = Number(searchParams.get("q")) || 90;
const width = Number(searchParams.get("w")) || undefined;
const height = Number(searchParams.get("h")) || undefined;
const quality = Number(req.query.q) || 90;
const width = Number(req.query.w) || undefined;
const height = Number(req.query.h) || undefined;
const format = getFormat(webp, avif);

const { data, status } = await getImage(href);
if (status > 399) {
return res
.status(415)
.send("upstream server did not respond with a valid status code");
}

res
.set("Cache-Control", "public, max-age=15552000")
.set("Vary", "Accept")
.type(`image/${format}`);

sharp(data)
const pipeline = sharp();

storage
.bucket(BUCKET)
.file(req.path.slice(1)) // remove leading slash
.createReadStream()
.on("error", function (e) {
if (e instanceof ApiError) {
if (e.message?.includes("No such object"))
return res.status(404).end();
}
return res.status(500).send(JSON.stringify(e));
})
.pipe(pipeline);

pipeline
.rotate()
.resize({ width, height })
.toFormat(format, { effort: 3, quality, progressive: true })
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"author": "openbeta.io",
"license": "MIT",
"dependencies": {
"@google-cloud/storage": "^7.5.0",
"express": "^4.18.2",
"node-fetch": "^3.3.2",
"sharp": "^0.32.6"
},
"devDependencies": {
Expand Down
Loading

0 comments on commit b1c40cd

Please sign in to comment.