Fix database closed multiple times.

utt part support Ctrl + C
This commit is contained in:
2023-05-23 10:50:56 +08:00
parent 144797f246
commit 5c9712a02c
6 changed files with 69 additions and 12 deletions

View File

@@ -35,9 +35,10 @@ export type EHTTextFile = {
data: EHTData[];
};
async function fetch_eht_file() {
async function fetch_eht_file(signal?: AbortSignal) {
const re = await fetch(
"https://github.com/EhTagTranslation/DatabaseReleases/raw/master/db.text.json",
{ signal },
);
if (re.status != 200) throw Error("fetch failed");
return re.text();
@@ -45,10 +46,11 @@ async function fetch_eht_file() {
export async function load_eht_file(
location: string | undefined = undefined,
signal?: AbortSignal,
): Promise<EHTTextFile> {
const s = location === undefined
? await fetch_eht_file()
: await Deno.readTextFile(location);
? await fetch_eht_file(signal)
: await Deno.readTextFile(location, { signal });
return JSON.parse(s);
}

22
main.ts
View File

@@ -6,6 +6,7 @@ import { ParsedUrl, parseUrl, UrlType } from "./url.ts";
import { sure_dir } from "./utils.ts";
import { EhDb } from "./db.ts";
import { load_eht_file, update_database_tag } from "./eh_translation.ts";
import { get_abort_signal } from "./signal_handler.ts";
function show_help() {
console.log("Usage: main.ts [options]");
@@ -69,7 +70,7 @@ async function download() {
}
await manager.run();
} finally {
manager.close();
if (!manager.aborted) manager.close();
}
}
async function run() {
@@ -77,7 +78,7 @@ async function run() {
try {
await manager.run();
} finally {
manager.close();
if (!manager.aborted) manager.close();
}
}
function optimize() {
@@ -87,11 +88,18 @@ function optimize() {
}
async function update_tag_translation() {
const db = new EhDb(settings.db_path || settings.base);
const f = await load_eht_file(
args._.length > 1 ? args._[1].toString() : undefined,
);
update_database_tag(db, f);
db.close();
const signal = get_abort_signal();
try {
const f = await load_eht_file(
args._.length > 1 ? args._[1].toString() : undefined,
signal,
);
update_database_tag(db, f);
} catch (e) {
if (!signal.aborted) throw e;
} finally {
db.close();
}
}
async function main() {
await sure_dir(settings.base);

View File

@@ -28,3 +28,17 @@ export function add_exit_handler(m: TaskManager) {
});
}
}
export function get_abort_signal(callback?: () => void): AbortSignal {
const a = new AbortController();
const handler = () => {
console.log("Aborted.");
a.abort();
if (callback) callback();
};
Deno.addSignalListener("SIGINT", handler);
if (Deno.build.os !== "windows") {
Deno.addSignalListener("SIGKILL", handler);
}
return a.signal;
}

View File

@@ -93,7 +93,10 @@ export class TaskManager {
}
}
close() {
if (this.#closed) return;
if (this.#closed) {
console.trace("Manager closed multiple times.");
return;
}
this.#closed = true;
this.db.close();
}

View File

@@ -90,3 +90,18 @@ export async function asyncFilter<T>(
)).filter((i) => i !== fail);
return t.map((t) => t[0]);
}
export async function asyncForEach<T, V>(
arr: ArrayLike<T>,
callback: (
this: V | undefined,
element: T,
index: number,
array: ArrayLike<T>,
) => Promise<void>,
thisArg?: V,
) {
for (let i = 0; i < arr.length; i++) {
await callback.apply(thisArg, [arr[i], i, arr]);
}
}

View File

@@ -1,6 +1,12 @@
import { assertEquals } from "std/testing/asserts.ts";
import { check_running } from "./pid_check.ts";
import { asyncFilter, promiseState, PromiseStatus, sleep } from "./utils.ts";
import {
asyncFilter,
asyncForEach,
promiseState,
PromiseStatus,
sleep,
} from "./utils.ts";
Deno.test("promiseState_test", async () => {
const p1 = new Promise((res) => setTimeout(() => res(100), 100));
@@ -42,3 +48,12 @@ Deno.test("asyncFilter_test", async () => {
assertEquals(v, e);
await Promise.allSettled(e);
});
Deno.test("asyncForEach", async () => {
const e = [new Promise<number>((res) => setTimeout(() => res(100), 100))];
const t = { test: 2 };
await asyncForEach(e, async function (e) {
assertEquals(this, t);
await e;
}, t);
});