refactor; backtest using lmdbx

This commit is contained in:
2024-08-07 21:57:03 -04:00
parent 1d83cd419a
commit 93d5ac8a30
21 changed files with 397 additions and 296 deletions
+19 -12
View File
@@ -1,6 +1,7 @@
import { createClient as createClickhouseClient } from "@clickhouse/client";
import type { DataFormat } from "@clickhouse/client";
import { Env } from "@humanwhocodes/env";
import { retry } from "./utils/retry.js";
const env = new Env();
@@ -11,21 +12,27 @@ export const clickhouse = createClickhouseClient({
host: CLICKHOUSE_HOST,
username: CLICKHOUSE_USER,
password: CLICKHOUSE_PASS,
keep_alive: {
enabled: true,
socket_ttl: 2500,
},
});
export async function query<T>(
queryString: string,
format: DataFormat = "JSONEachRow"
format: DataFormat = "JSONEachRow",
): Promise<Array<T>> {
return await (
await clickhouse.query({
query: queryString,
format,
clickhouse_settings: {
output_format_json_quote_64bit_integers: 0,
//output_format_json_quote_64bit_floats: false,
//output_format_json_quote_64bit_decimals: false,
},
})
).json();
return await retry(
async () => {
const result = await clickhouse.query({
query: queryString,
format,
clickhouse_settings: {
output_format_json_quote_64bit_integers: 0,
},
});
return await result.json();
},
{ maxRetries: 5 },
);
}
+61
View File
@@ -0,0 +1,61 @@
type RetryDecision = {
shouldRetry: boolean;
maxRetries?: number;
delay?: number;
};
type RetryOptions = {
maxRetries?: number;
delay?: number;
shouldRetry?: (error: unknown) => RetryDecision;
};
export async function retry<T>(
fn: () => Promise<T>,
options: RetryOptions = {},
): Promise<T> {
const {
maxRetries: defaultMaxRetries = 3,
delay: defaultDelay = 1000,
shouldRetry = retryOnAnyError,
} = options;
let attempt = 1;
while (true) {
try {
return await fn();
} catch (error) {
const decision = shouldRetry(error);
if (!decision.shouldRetry) throw error;
const currentMaxRetries = decision.maxRetries ?? defaultMaxRetries;
const currentDelay = decision.delay ?? defaultDelay;
if (attempt >= currentMaxRetries) throw error;
console.warn(
`Error occurred, retrying (attempt ${attempt}/${currentMaxRetries})...`,
);
console.error(error);
await new Promise((resolve) => setTimeout(resolve, currentDelay));
attempt++;
}
}
}
export const retryOnAnyError = (): RetryDecision => ({ shouldRetry: true });
export const retryOnTimeout = (error: unknown): RetryDecision =>
error instanceof Error && error.message.includes("timeout")
? { shouldRetry: true, maxRetries: 5, delay: 2000 }
: { shouldRetry: false };
export const retryOnErrorType =
(errorType: new () => Error, options?: Partial<RetryDecision>) =>
(error: unknown) =>
error instanceof errorType
? { shouldRetry: true, ...options }
: { shouldRetry: false };
export const retryOnErrorSubstring =
(substring: string, options?: Partial<RetryDecision>) => (error: unknown) =>
error instanceof Error && error.message.includes(substring)
? { shouldRetry: true, ...options }
: { shouldRetry: false };