perf: 优化缓存下载

This commit is contained in:
2024-10-11 22:10:30 +08:00
parent 79287d7de9
commit 973b76a5f0
6 changed files with 75 additions and 47 deletions

View File

@@ -9,9 +9,9 @@ import { pipeline } from 'stream';
import { promisify } from 'util';
const pipelineAsync = promisify(pipeline);
const { resources, api } = useConfig<{ resources: string; api: { host: string; testHost: string } }>();
const { resources, api } = useConfig<{ resources: string; api: { host: string; path: string } }>();
const fileStore = useFileStore('upload');
const status: { [key: string]: boolean } = {};
const demoData = {
user: 'root',
key: 'codeflow',
@@ -40,6 +40,7 @@ type UserAppOptions = {
user: string;
app: string;
};
export class UserApp {
user: string;
app: string;
@@ -82,10 +83,8 @@ export class UserApp {
}
// 获取域名对应的用户和应用
const isDev = process.env.NODE_ENV === 'development';
const fetchTestUrl = 'http://' + api.testHost + '/api/router';
const fetchUrl = 'http://' + api.host + '/api/router';
const fetchRes = await fetch(isDev ? fetchTestUrl : fetchUrl, {
const fetchUrl = 'http://' + api.host + api.path;
const fetchRes = await fetch(fetchUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -114,14 +113,26 @@ export class UserApp {
redis.set(key, data.user + ':' + data.app, 'EX', 60 * 60 * 24 * 7); // 24小时
return data;
}
async setLoaded() {
const app = this.app;
const user = this.user;
const key = 'user:app:' + app + ':' + user;
if (status[key]) {
status[key] = false;
}
}
async setCacheData() {
const app = this.app;
const user = this.user;
const key = 'user:app:' + app + ':' + user;
const isDev = process.env.NODE_ENV === 'development';
const fetchTestUrl = 'http://' + api.testHost + '/api/router';
const fetchUrl = 'http://' + api.host + '/api/router';
const fetchRes = await fetch(isDev ? fetchTestUrl : fetchUrl, {
const fetchUrl = 'http://' + api.host + api.path;
if (status[key]) {
return {
loading: true,
};
}
status[key] = true;
const fetchRes = await fetch(fetchUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -137,7 +148,8 @@ export class UserApp {
}).then((res) => res.json());
if (fetchRes?.code !== 200) {
console.log('fetchRes is error', fetchRes);
return false;
this.setLoaded();
return { code: 500, message: 'fetchRes is error' };
}
const fetchData = fetchRes.data;
if (!fetchData.type) {
@@ -147,12 +159,17 @@ export class UserApp {
}
if (fetchData.status !== 'running') {
console.error('fetchData status is not running', fetchData.user, fetchData.key);
return null;
this.setLoaded();
return {
code: 500,
message: 'fetchData status is not running',
};
}
const value = await downloadUserAppFiles(user, app, fetchData);
if (value.data.files.length === 0) {
console.error('root files length is zero', user, app);
return false;
this.setLoaded();
return { code: 404 };
}
let valueIndexHtml = value.data.files.find((file) => file.name === 'index.html');
if (!valueIndexHtml) {
@@ -172,8 +189,9 @@ export class UserApp {
data[file.name] = file.path;
});
await redis.hset('user:app:set:' + app + ':' + user, data);
this.setLoaded();
return true;
return { code: 200, data: valueIndexHtml.path };
}
async getAllCacheData() {
const app = this.app;

View File

@@ -7,6 +7,7 @@ import fs from 'fs';
import { useConfig } from '@abearxiong/use-config';
import { redis } from './redis/redis.ts';
import { getContentType } from './get-content-type.ts';
import { sleep } from '@/utils/sleep.ts';
const { api, domain, allowedOrigins } = useConfig<{
api: {
host: string;
@@ -128,30 +129,38 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
let isExist = await userApp.getExist();
if (!isExist) {
try {
const hasApp = await userApp.setCacheData();
if (!hasApp) {
const { code, loading, data } = await userApp.setCacheData();
if (loading) {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write('Loading App\n');
res.end();
return;
}
if (code !== 200) {
res.writeHead(404, { 'Content-Type': 'text/html' });
res.write('Not Found App\n');
res.end();
return;
}
await sleep(1000);
isExist = data; // 设置缓存后再次获取
if (!isExist) {
res.writeHead(404, { 'Content-Type': 'text/html' });
res.write('Not Found App Index Page\n');
res.end();
return;
}
} catch (error) {
console.error('setCacheData error', error);
res.writeHead(500, { 'Content-Type': 'text/html' });
res.write('Server Error\n');
res.end();
return;
}
isExist = await userApp.getExist();
if (!isExist) {
res.writeHead(404, { 'Content-Type': 'text/html' });
res.write('Not Found App Index Page\n');
res.end();
userApp.setLoaded();
return;
}
}
const indexFile = isExist;
const indexFile = isExist; // 已经必定存在了
let appFileUrl: string;
if (domainApp) {
appFileUrl = (url + '').replace(`/`, '');

1
src/utils/sleep.ts Normal file
View File

@@ -0,0 +1 @@
export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));