Skip to content

Commit

Permalink
Upload sqlite backups without creating
Browse files Browse the repository at this point in the history
intermediate file
  • Loading branch information
haishanh committed Aug 4, 2024
1 parent 33c4d0d commit 5ec7207
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 62 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"type": "module",
"dependencies": {
"@aws-sdk/client-s3": "3.623.0",
"@aws-sdk/lib-storage": "3.623.0",
"@node-rs/argon2": "1.8.3",
"@node-rs/crc32": "1.10.3",
"better-sqlite3": "11.1.2",
Expand Down
85 changes: 47 additions & 38 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 10 additions & 11 deletions src/lib/components/base/Button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,6 @@
--fg: var(--color-text);
--bg: var(--bg-btn);
--shadow: 0 0 0 3px rgba(66, 153, 225, 0.6);
@media (prefers-color-scheme: dark) {
--bo-lightness: 30%;
--bo-lightness-hover: 70%;
--bg-hover: hsl(0deg 0% 19%);
}
@media (prefers-color-scheme: light) {
--bo-lightness: 80%;
--bo-lightness-hover: 15%;
--bg-hover: hsl(0deg 0% 90%);
}
position: relative;
appearance: none;
outline: none;
Expand All @@ -57,6 +46,16 @@
border: 1px solid var(--color-btn-bo);
border-radius: 100px;
border-color: hsl(0deg 0% var(--bo-lightness));
@media (prefers-color-scheme: dark) {
--bo-lightness: 30%;
--bo-lightness-hover: 70%;
--bg-hover: hsl(0deg 0% 19%);
}
@media (prefers-color-scheme: light) {
--bo-lightness: 80%;
--bo-lightness-hover: 15%;
--bg-hover: hsl(0deg 0% 90%);
}
&:hover {
border-color: hsl(0deg 0% var(--bo-lightness-hover));
background-color: var(--bg-hover);
Expand Down
6 changes: 3 additions & 3 deletions src/lib/components/base/Modal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,15 @@
max-height: 100%;
display: flex;
flex-direction: column;
background-color: var(--bg-card);
border: 1px solid var(--bo);
border-radius: 10px;
@media (prefers-color-scheme: dark) {
--bo: hsl(0deg 0% 29%);
}
@media (prefers-color-scheme: light) {
--bo: transparent;
}
background-color: var(--bg-card);
border: 1px solid var(--bo);
border-radius: 10px;
}
.action {
position: absolute;
Expand Down
34 changes: 27 additions & 7 deletions src/lib/server/services/admin.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { createReadStream } from 'node:fs';
import * as fs from 'node:fs/promises';
import * as path from 'node:path';

import { Upload } from '@aws-sdk/lib-storage';
import type { Database } from 'better-sqlite3';
import { format } from 'date-fns';
import * as tar from 'tar/create';

import { Duplex } from 'node:stream';
import { BACKUP_S3_BUCKET, BACKUP_S3_PREFIX, DATA_DIR } from '$lib/env';
import * as bookmarkDb from '$lib/server/db/bookmark.db';
import * as groupDb from '$lib/server/db/group.db';
Expand Down Expand Up @@ -56,15 +55,36 @@ export class AdminService {
const tarballFilepath = filepath + '.tar.gz';
try {
const result = await this.db.backup(filepath);
await tar.create({ gzip: true, file: tarballFilepath }, [filepath]);
const tarReadStream = tar.create({ gzip: true }, [filepath]);
const dup = Duplex.from(tarReadStream);
const prefix = BACKUP_S3_PREFIX.replace(/\/$/, '');
const Key = `${prefix}/${yearmonth}/${path.basename(tarballFilepath)}`;
const Body = createReadStream(tarballFilepath);
await this.s3Srv.putObject({ Key, Body });
const parallelUploads3 = new Upload({
client: this.s3Srv.s3,
params: { Bucket: this.s3Srv.bucket, Key, Body: dup },
tags: [],
// additional optional fields show default values below:

// (optional) concurrency configuration
queueSize: 4,

// (optional) size of each part, in bytes, at least 5MB
partSize: 1024 * 1024 * 5,

// (optional) when true, do not automatically call AbortMultipartUpload when
// a multipart upload fails to complete. You should then manually handle
// the leftover parts.
leavePartsOnError: false,
});

parallelUploads3.on('httpUploadProgress', (progress) => {
logger.info(progress, 'httpUploadProgress');
});
await parallelUploads3.done();

return { ...result, key: Key };
} finally {
fs.unlink(filepath).catch(noop);
fs.unlink(tarballFilepath).catch(noop);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib/server/services/s3.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { PutObjectCommand, type PutObjectCommandInput, S3Client } from '@aws-sdk/client-s3';

export class S3Service {
private s3: S3Client;
private bucket: string;
public readonly s3: S3Client;
public readonly bucket: string;

constructor(opts: {
s3Endpoint: string;
Expand Down
2 changes: 1 addition & 1 deletion src/routes/_play/Color/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@
background-color: hsl(35.48deg 94.9% 61.57% / 30%);
}
.chip.yellow {
background-color: hsl(49.65deg 100% 50% / 81%);
@media (prefers-color-scheme: light) {
color: hsl(55.76deg 78.17% 26.98%);
}
@media (prefers-color-scheme: dark) {
color: hsl(55.76deg 78.01% 84.18%);
}
background-color: hsl(49.65deg 100% 50% / 81%);
}
@media (prefers-color-scheme: light) {
Expand Down

0 comments on commit 5ec7207

Please sign in to comment.