Skip to content

Commit 27648df

Browse files
committed
A little bit of code cleanup and commenting
1 parent d9eda2a commit 27648df

File tree

2 files changed

+37
-38
lines changed

2 files changed

+37
-38
lines changed

src/server.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {GoogleAuth} from 'google-auth-library';
33
import * as fsPath from 'path';
44
import express = require('express');
55
import httpProxy = require('http-proxy');
6-
import {Manifest} from './manifest';
76

87
const URL = 'https://storage.googleapis.com';
98
const datastore = new Datastore();
@@ -12,9 +11,6 @@ const auth = new GoogleAuth({
1211
});
1312

1413
const server = httpProxy.createProxyServer();
15-
interface ManifestCache {
16-
[requestSha: string]: string;
17-
}
1814

1915
const getManifest = async (siteId: string, branchOrRef: string) => {
2016
const keys = [
@@ -70,7 +66,6 @@ const parseHostname = (hostname: string) => {
7066
};
7167

7268
export function createApp(siteId: string, branchOrRef: string) {
73-
// const startupManifest = await getManifest(branchOrRef);
7469
console.log(`Starting server for site: ${siteId} @ ${branchOrRef}`);
7570

7671
const app = express();
@@ -141,7 +136,8 @@ export function createApp(siteId: string, branchOrRef: string) {
141136
delete proxyRes.headers['x-guploader-uploadid'];
142137
// This cannot be "private, max-age=0" as this kills perf.
143138
// This also can't be a very small value, as it kills perf. 0036 seems to work correctly.
144-
proxyRes.headers['cache-control'] = 'public, max-age=0036'; // The padded 0036 keeps the content length the same per upload.ts.
139+
// The padded "0036" keeps the Content-Length identical with `3600`.
140+
proxyRes.headers['cache-control'] = 'public, max-age=0036';
145141
proxyRes.headers['x-fileset-blob'] = blobKey;
146142
proxyRes.headers['x-fileset-ref'] = manifest.ref;
147143
proxyRes.headers['x-fileset-site'] = siteId;

src/upload.ts

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
1-
import * as cliProgress from 'cli-progress';
2-
import {asyncify, mapLimit} from 'async';
3-
import {Manifest, ManifestFile} from './manifest';
41
import _colors = require('colors');
5-
6-
import {Storage} from '@google-cloud/storage';
2+
import {asyncify, mapLimit} from 'async';
73
import {Datastore} from '@google-cloud/datastore';
84
import {entity} from '@google-cloud/datastore/build/src/entity';
5+
import {Manifest, ManifestFile} from './manifest';
6+
import {Storage} from '@google-cloud/storage';
7+
import * as cliProgress from 'cli-progress';
98

109
const datastore = new Datastore();
11-
1210
const DEFAULT_BUCKET = `${process.env.GCLOUD_PROJECT}.appspot.com`;
13-
1411
const NUM_CONCURRENT_UPLOADS = 64;
1512

1613
function getBlobPath(siteId: string, hash: string) {
@@ -68,62 +65,67 @@ export async function uploadManifest(
6865
const filesToUpload = force
6966
? manifest.files
7067
: await findUploadedFiles(manifest, storageBucket);
71-
const numFiles = filesToUpload.length;
68+
const numTotalFiles = filesToUpload.length;
7269
console.log(
7370
`Found new ${filesToUpload.length} files out of ${manifest.files.length} total...`
7471
);
7572

76-
if (numFiles > 0) {
77-
let totalTransferred = 0;
78-
let numProcessed = 0;
73+
if (numTotalFiles <= 0) {
74+
finalize(manifest, ttl);
75+
} else {
76+
let bytesTransferred = 0;
77+
let numProcessedFiles = 0;
7978
const startTime = Math.floor(Date.now() / 1000);
80-
bar.start(numFiles, numProcessed, {
79+
bar.start(numTotalFiles, numProcessedFiles, {
8180
speed: 0,
8281
});
82+
// @ts-ignore
83+
bar.on('stop', () => {
84+
finalize(manifest, ttl);
85+
});
8386

8487
mapLimit(
8588
filesToUpload,
8689
NUM_CONCURRENT_UPLOADS,
8790
asyncify(async (manifestFile: ManifestFile) => {
88-
const remotePath = getBlobPath(manifest.site, manifestFile.hash);
89-
90-
// NOTE: This was causing stale responses, even when rewritten by the client-server: 'public, max-age=31536000',
91+
// NOTE: After testing, it seems we need a public Cache-Control with a
92+
// minimum max age of ~3600 seconds (1 hour) for the "high performance"
93+
// mode to kick in. Our best guess is that when this Cache-Control
94+
// setting is used, responses are cached internally within GCP yielding
95+
// much higher performance. That said, we don't want end users to
96+
// receive potentially stale content, so the proxy response rewrites
97+
// this header to 36 seconds (from 3600).
98+
// The following docs indicate that Cache-Control doesn't apply for
99+
// private blobs, however we've observed differences in performance per
100+
// the above.
91101
// https://cloud.google.com/storage/docs/gsutil/addlhelp/WorkingWithObjectMetadata#cache-control
92-
// NOTE: In order for GCS to respond extremely fast, it requires a longer cache expiry time.
93-
// TODO: See if we can remove this from the proxy response without killing perf.
94102
const metadata = {
95103
cacheControl: 'public, max-age=3600',
96104
contentType: manifestFile.mimetype,
97105
metadata: {
98106
path: manifestFile.cleanPath,
99107
},
100108
};
101-
102109
// TODO: Veryify this correctly handles errors and retry attempts.
110+
const remotePath = getBlobPath(manifest.site, manifestFile.hash);
103111
const resp = await storageBucket.upload(manifestFile.path, {
104112
// NOTE: `gzip: true` must *not* be set here. Doing so interferes
105113
// with the proxied GCS response. Despite not setting `gzip: true`,
106114
// the response remains gzipped from the proxy server.
107115
destination: remotePath,
108116
metadata: metadata,
109117
});
110-
totalTransferred += parseInt(resp[1].size);
118+
bytesTransferred += parseInt(resp[1].size);
111119
const elapsed = Math.floor(Date.now() / 1000) - startTime;
112-
bar.update((numProcessed += 1), {
113-
speed: (totalTransferred / elapsed / (1024 * 1024)).toFixed(2),
120+
const speed = (bytesTransferred / elapsed / (1024 * 1024)).toFixed(2);
121+
bar.update((numProcessedFiles += 1), {
122+
speed: speed,
114123
});
115-
if (numProcessed === numFiles) {
124+
if (numProcessedFiles === numTotalFiles) {
116125
bar.stop();
117126
}
118127
})
119128
);
120-
121-
// @ts-ignore
122-
bar.on('stop', () => {
123-
finalize(manifest, ttl);
124-
});
125-
} else {
126-
finalize(manifest, ttl);
127129
}
128130
}
129131

@@ -140,7 +142,7 @@ async function finalize(manifest: Manifest, ttl?: Date) {
140142
const manifestPaths = manifest.toJSON();
141143
const now = new Date();
142144

143-
// Create shortSha mapping for staging.
145+
// Create shortSha mapping, so a shortSha can be used to lookup filesets.
144146
const key = datastore.key([
145147
'Fileset2Manifest',
146148
`${manifest.site}:ref:${manifest.shortSha}`,
@@ -152,7 +154,8 @@ async function finalize(manifest: Manifest, ttl?: Date) {
152154
paths: manifestPaths,
153155
});
154156

155-
// Create branch mapping for staging.
157+
// Create branch mapping, so a branch name can be used to lookup filesets.
158+
// TODO: Use clean branch name to avoid non-URL-safe branch names.
156159
if (manifest.branch) {
157160
const branchKey = datastore.key([
158161
'Fileset2Manifest',
@@ -172,10 +175,10 @@ async function finalize(manifest: Manifest, ttl?: Date) {
172175
// const routerKey = datastore.key(['Fileset2Router', manifest.site]);
173176
// const router = await datastore.get(routerKey);
174177
// const entity = router && router[0];
175-
176178
console.log(
177179
`Finalized upload for site: ${manifest.site} -> ${manifest.branch} @ ${manifest.shortSha}`
178180
);
181+
// TODO: Allow customizing the staging URL using `fileset.yaml` configuration.
179182
console.log(
180183
`Staged: https://${manifest.site}-${manifest.shortSha}-dot-fileset2-dot-${process.env.GCLOUD_PROJECT}.appspot.com`
181184
);

0 commit comments

Comments
 (0)