Refactor connections (#298)

* REF: mysql connections

* REF: mysql connections
This commit is contained in:
Overtorment 2025-07-02 17:34:10 +01:00 committed by GitHub
parent caa5b4bd9f
commit f1c97586c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 193 additions and 181 deletions

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "groundcontrol",
"version": "3.0.1",
"version": "3.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {

View File

@ -1,6 +1,6 @@
{
"name": "groundcontrol",
"version": "3.0.1",
"version": "3.1.0",
"description": "GroundControl push server API",
"devDependencies": {
"@types/node": "18.7.16",

View File

@ -0,0 +1,81 @@
export const ADDRESS_IGNORE_LIST = [
"1NXNHZr6Pbzi3VStcgaxwEhspTWNXQ3Q4G",
"bc1qee7hk4a3k3km7j8hwclm0pkl76dhhgxay5nevu",
"bc1qclyfsxuu8vcwq38yygs5zrskwacq8sjlyvk9mx",
"bc1qltxjty7xfrnkzlrhmxpcekknr3uncne8sht7rn",
"bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
"bc1qw8wrek2m7nlqldll66ajnwr9mh64syvkt67zlu",
"1111111111111111111114oLvT2",
"1BrasiLb2KMbdtuhb1chAVnS2FvcNGfV9J",
"1GQdrgqAbkeEPUef1UpiTc4X1mUHMcyuGW",
"1KHwtS5mn7NMUm7Ls7Y1XwxLqMriLdaGbX",
"bc1q7cyrfmck2ffu2ud3rn5l5a8yv6f0chkp0zpemf",
"bc1qwfgdjyy95aay2686fn74h6a4nu9eev6np7q4fn204dkj3274frlqrskvx0",
"bc1qm34lsc65zpw79lxes69zkqmk6ee3ewf0j77s3h",
"bc1qrnn4wfhgz2e0etek66sh3n9l6k99alxk044mhr",
"13nCMaHDNRGM29UfMMkhUQjHkVYY1ZyrpU",
"bc1qel7tps3wu6zqztaanczvt76hffwh7k06jd8r9xh2v3ztpa5ty5dsz358ys",
"bc1qyzxdu4px4jy8gwhcj82zpv7qzhvc0fvumgnh0r",
"bc1qyemk24czaa6a2nr89nrz775ewvptxg7yfe750u",
"bc1qq904ynep5mvwpjxdlyecgeupg22dm8am6cfvgq",
"37biYvTEcBVMoR1NGkPTGvHUuLTrzcLpiv",
"bc1qq9tk3uhcx58y5qvmzs50nhs49m0pdkmrfpkzs4",
"1Kr6QSydW9bFQG1mXiPNNu6WpJGmUa9i1g",
"3DGxAYYUA61WrrdbBac8Ra9eA9peAQwTJF",
"bc1qmgj3w0aw5455y9s4zfhts2kxm4qstwyjx5f907",
"bc1qgrxsrmrhsapvh9addyx6sh8j4rw0sn9xtur9uq",
"bc1qp3f7vnmuj4pjxpfvkvf7yznac9h9r5arlv4fpv",
"bc1qnsupj8eqya02nm8v6tmk93zslu2e2z8chlmcej",
"bc1qt5m8xeclsja4lkfvl2nvmrt6z9vg60sd8w2kc6",
"bc1qsatlphjcgvzlt9xhsgn0dnjus5jgwg83dr05c6",
"bc1quq29mutxkgxmjfdr7ayj3zd9ad0ld5mrhh89l2",
"bc1qe9nagya0tvfhvymt8sejwedlukwq4a094h6ht9",
"1GrwDkr33gT6LuumniYjKEGjTLhsL5kmqC",
"33WSGLeVoEpuZDjB54HKZ1y5YsERELoVNq",
"3A8n8rwMnHnt2BqnjW4R73eZCMcUDTpYvv",
"bc1qns9f7yfx3ry9lj6yz7c9er0vwa0ye2eklpzqfw",
"38XnPvu9PmonFU9WouPXUjYbW91wa5MerL",
"1Bo8hs81QwnR6A3oFBXcWNZXgtwpfgByb3",
"37Z6neB2wDC3hsPDHLy2n2kFahNNU3eos8",
"1CK6KHY6MHgYvmRQ4PAafKYDrg1ejbH1cE",
"36XWTfSYJJz3WSNPZVZ3q3aa5eFuJHR9nu",
"bc1qc8ee9860cdnkyej0ag5hf49pcx7uvz89lkwpr9",
"bc1q7ug4w4as2sefar89q057hnmxkakp58a25535ttlmurn6cncs8tms4e7gp2",
"3JodN7GmkHdPgKj9G7HCkn9NDLhrcWCjVN",
"bc1qujepl0k5n0ga2e86yskvxa6auehpf6dlf84dx0",
"bc1qg9lgqyukp2rup5x4frrz7hhw7988k5q26luakm",
"3JSdUu1ivm3rqMvuCTAdAj6Dc2hdVhHiEe",
"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"bc1qr35hws365juz5rtlsjtvmulu97957kqvr3zpw3",
"bc1qzlcvh2k3xs2jyzvya7xmx8l2ylpt259txy7wnd",
"bc1qprdf80adfz7aekh5nejjfrp3jksc8r929svpxk",
"35iMHbUZeTssxBodiHwEEkb32jpBfVueEL",
"3QiETomgUhPu573ZvhXbdofq7y5ocNS1ie",
"3HcEUguUZ4vyyMAPWDPUDjLqz882jXwMfV",
"3J7cUjBZxvGRCwFBz3q23zAsnhFfZrDSSU",
"bc1qamgjuxaywqls56h7rg7afga3m6rgqwfkew688k",
"1G47mSr3oANXMafVrR8UC4pzV7FEAzo3r9",
"17StnGroPUsNXBq4AVJQ1fqGftoFZh3zva",
"1FWQiwK27EnGXb6BiBMRLJvunJQZZPMcGd",
"16r7U7GqbVPeKukgfd3mUN9LCkuoKbfpXM",
"bc1q22hp7n28whk5h94z93vm05hfx2zxs8ca9gglk7",
"bc1q0wu0tqp2u3rtunjl0h0rsl9pvf86acy6sep63st0lp7lgg67ykzqeq89pn",
"bc1qryhgpmfv03qjhhp2dj8nw8g4ewg08jzmgy3cyx",
"bc1quhruqrghgcca950rvhtrg7cpd7u8k6svpzgzmrjy8xyukacl5lkq0r8l2d",
"bc1q0s6rca52mjumq8fjuz4j6ka5h9jhq57esyd40r",
"bc1qjguxrqjx9qnpmklzymdr0y6mqxrth9d3swzdpr",
"bc1qr4dl5wa7kl8yu792dceg9z5knl2gkn220lk7a9",
"1Dy8gSw3Zbpatr4bGn7zR4phNX18XuTD56",
"bc1qcdqj2smprre85c78d942wx5tauw5n7uw92r7wr",
"bc1qmhq4sgtchfgh6ul75x3rsuegt55mef0zx3ehm2",
"bc1qws8yeyfxzykuq7tevwwxezyv3ad99emlyy9uls",
"bc1q42kvqt0e3f27qhd2ucnprarl5ywpuj7tu0h9v2",
"bc1q5k9tyr30xhmvmnj2z2cx0psprz44ksnmpuw7q8",
"bc1qfpeps3wcmzk422hvm5jeq5lelnqlzznjwyfy69",
"bc1qfy4ck4xpu3vg2226ew9jssly6xvc8w5xhjkzxz",
"bc1q9yn6zdkjjlh0z5y6sqpdvwq7pwkeh5r0ka28ad",
"bc1qpsys7sfk5u7ue3lffwzszzvffhtku78kr0vva4",
"bc1q0qfzuge7vr5s2xkczrjkccmxemlyyn8mhx298v",
"bc1pz454nh8mdcq093zfcc4qe2hw5ejha98k3e6n9apqkhemqv9w5kuqh2xcst",
"bc1qynygs8d3ju9cpum9pepmh94qk57tf67paka78g",
];

View File

@ -9,6 +9,7 @@ import { PushLog } from "../entity/PushLog";
import { KeyValue } from "../entity/KeyValue";
import dataSource from "../data-source";
import { paths, components } from "../openapi/api";
import { ADDRESS_IGNORE_LIST } from "../address-ignore-list";
require("dotenv").config();
const pck = require("../../package.json");
if (!process.env.JAWSDB_MARIA_URL || !process.env.GOOGLE_KEY_FILE || !process.env.APNS_P8 || !process.env.APNS_TOPIC || !process.env.APPLE_TEAM_ID || !process.env.APNS_P8_KID || !process.env.GOOGLE_PROJECT_ID) {
@ -18,187 +19,24 @@ if (!process.env.JAWSDB_MARIA_URL || !process.env.GOOGLE_KEY_FILE || !process.en
const LAST_PROCESSED_BLOCK = "LAST_PROCESSED_BLOCK";
const ADDRESS_IGNORE_LIST = [
"1NXNHZr6Pbzi3VStcgaxwEhspTWNXQ3Q4G",
"bc1qee7hk4a3k3km7j8hwclm0pkl76dhhgxay5nevu",
"bc1qclyfsxuu8vcwq38yygs5zrskwacq8sjlyvk9mx",
"bc1qltxjty7xfrnkzlrhmxpcekknr3uncne8sht7rn",
"bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
"bc1qw8wrek2m7nlqldll66ajnwr9mh64syvkt67zlu",
"1111111111111111111114oLvT2",
"1BrasiLb2KMbdtuhb1chAVnS2FvcNGfV9J",
"1GQdrgqAbkeEPUef1UpiTc4X1mUHMcyuGW",
"1KHwtS5mn7NMUm7Ls7Y1XwxLqMriLdaGbX",
"bc1q7cyrfmck2ffu2ud3rn5l5a8yv6f0chkp0zpemf",
"bc1qwfgdjyy95aay2686fn74h6a4nu9eev6np7q4fn204dkj3274frlqrskvx0",
"bc1qm34lsc65zpw79lxes69zkqmk6ee3ewf0j77s3h",
"bc1qrnn4wfhgz2e0etek66sh3n9l6k99alxk044mhr",
"13nCMaHDNRGM29UfMMkhUQjHkVYY1ZyrpU",
"bc1qel7tps3wu6zqztaanczvt76hffwh7k06jd8r9xh2v3ztpa5ty5dsz358ys",
"bc1qyzxdu4px4jy8gwhcj82zpv7qzhvc0fvumgnh0r",
"bc1qyemk24czaa6a2nr89nrz775ewvptxg7yfe750u",
"bc1qq904ynep5mvwpjxdlyecgeupg22dm8am6cfvgq",
"37biYvTEcBVMoR1NGkPTGvHUuLTrzcLpiv",
"bc1qq9tk3uhcx58y5qvmzs50nhs49m0pdkmrfpkzs4",
"1Kr6QSydW9bFQG1mXiPNNu6WpJGmUa9i1g",
"3DGxAYYUA61WrrdbBac8Ra9eA9peAQwTJF",
"bc1qmgj3w0aw5455y9s4zfhts2kxm4qstwyjx5f907",
"bc1qgrxsrmrhsapvh9addyx6sh8j4rw0sn9xtur9uq",
"bc1qp3f7vnmuj4pjxpfvkvf7yznac9h9r5arlv4fpv",
"bc1qnsupj8eqya02nm8v6tmk93zslu2e2z8chlmcej",
"bc1qt5m8xeclsja4lkfvl2nvmrt6z9vg60sd8w2kc6",
"bc1qsatlphjcgvzlt9xhsgn0dnjus5jgwg83dr05c6",
"bc1quq29mutxkgxmjfdr7ayj3zd9ad0ld5mrhh89l2",
"bc1qe9nagya0tvfhvymt8sejwedlukwq4a094h6ht9",
"1GrwDkr33gT6LuumniYjKEGjTLhsL5kmqC",
"33WSGLeVoEpuZDjB54HKZ1y5YsERELoVNq",
"3A8n8rwMnHnt2BqnjW4R73eZCMcUDTpYvv",
"bc1qns9f7yfx3ry9lj6yz7c9er0vwa0ye2eklpzqfw",
"38XnPvu9PmonFU9WouPXUjYbW91wa5MerL",
"1Bo8hs81QwnR6A3oFBXcWNZXgtwpfgByb3",
"37Z6neB2wDC3hsPDHLy2n2kFahNNU3eos8",
"1CK6KHY6MHgYvmRQ4PAafKYDrg1ejbH1cE",
"36XWTfSYJJz3WSNPZVZ3q3aa5eFuJHR9nu",
"bc1qc8ee9860cdnkyej0ag5hf49pcx7uvz89lkwpr9",
"bc1q7ug4w4as2sefar89q057hnmxkakp58a25535ttlmurn6cncs8tms4e7gp2",
"3JodN7GmkHdPgKj9G7HCkn9NDLhrcWCjVN",
"bc1qujepl0k5n0ga2e86yskvxa6auehpf6dlf84dx0",
"bc1qg9lgqyukp2rup5x4frrz7hhw7988k5q26luakm",
"3JSdUu1ivm3rqMvuCTAdAj6Dc2hdVhHiEe",
"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"bc1qr35hws365juz5rtlsjtvmulu97957kqvr3zpw3",
"bc1qzlcvh2k3xs2jyzvya7xmx8l2ylpt259txy7wnd",
"bc1qprdf80adfz7aekh5nejjfrp3jksc8r929svpxk",
"35iMHbUZeTssxBodiHwEEkb32jpBfVueEL",
"3QiETomgUhPu573ZvhXbdofq7y5ocNS1ie",
"3HcEUguUZ4vyyMAPWDPUDjLqz882jXwMfV",
"3J7cUjBZxvGRCwFBz3q23zAsnhFfZrDSSU",
"bc1qamgjuxaywqls56h7rg7afga3m6rgqwfkew688k",
"1G47mSr3oANXMafVrR8UC4pzV7FEAzo3r9",
"17StnGroPUsNXBq4AVJQ1fqGftoFZh3zva",
"1FWQiwK27EnGXb6BiBMRLJvunJQZZPMcGd",
"16r7U7GqbVPeKukgfd3mUN9LCkuoKbfpXM",
"bc1q22hp7n28whk5h94z93vm05hfx2zxs8ca9gglk7",
"bc1q0wu0tqp2u3rtunjl0h0rsl9pvf86acy6sep63st0lp7lgg67ykzqeq89pn",
"bc1qryhgpmfv03qjhhp2dj8nw8g4ewg08jzmgy3cyx",
"bc1quhruqrghgcca950rvhtrg7cpd7u8k6svpzgzmrjy8xyukacl5lkq0r8l2d",
"bc1q0s6rca52mjumq8fjuz4j6ka5h9jhq57esyd40r",
"bc1qjguxrqjx9qnpmklzymdr0y6mqxrth9d3swzdpr",
"bc1qr4dl5wa7kl8yu792dceg9z5knl2gkn220lk7a9",
"1Dy8gSw3Zbpatr4bGn7zR4phNX18XuTD56",
"bc1qcdqj2smprre85c78d942wx5tauw5n7uw92r7wr",
"bc1qmhq4sgtchfgh6ul75x3rsuegt55mef0zx3ehm2",
"bc1qws8yeyfxzykuq7tevwwxezyv3ad99emlyy9uls",
"bc1q42kvqt0e3f27qhd2ucnprarl5ywpuj7tu0h9v2",
"bc1q5k9tyr30xhmvmnj2z2cx0psprz44ksnmpuw7q8",
"bc1qfpeps3wcmzk422hvm5jeq5lelnqlzznjwyfy69",
"bc1qfy4ck4xpu3vg2226ew9jssly6xvc8w5xhjkzxz",
"bc1q9yn6zdkjjlh0z5y6sqpdvwq7pwkeh5r0ka28ad",
"bc1qpsys7sfk5u7ue3lffwzszzvffhtku78kr0vva4",
"bc1q0qfzuge7vr5s2xkczrjkccmxemlyyn8mhx298v",
"bc1pz454nh8mdcq093zfcc4qe2hw5ejha98k3e6n9apqkhemqv9w5kuqh2xcst",
"bc1qynygs8d3ju9cpum9pepmh94qk57tf67paka78g",
];
let connection: DataSource;
const pushLogPurge = () => {
console.log("purging PushLog...");
let today = new Date();
connection
.createQueryBuilder()
.delete()
.from(PushLog)
.where("created <= :currentDate", { currentDate: new Date(today.getTime() - 3 * 24 * 60 * 60 * 1000) })
.execute()
.then(() => console.log("PushLog purged ok"))
.catch((error) => console.log("error purging PushLog:", error));
};
const purgeOldTxidSubscriptions = () => {
console.log("purging TokenToTxid...");
let today = new Date();
connection
.createQueryBuilder()
.delete()
.from(TokenToTxid)
.where("created <= :currentDate", { currentDate: new Date(today.getTime() - 3 * 30 * 24 * 60 * 60 * 1000) }) // 3 mo
.execute()
.then(() => console.log("TokenToTxid purged ok"))
.catch((error) => console.log("error purging TokenToTxid:", error));
};
const purgeIgnoredAddressesSubscriptions = () => {
console.log("Purging addresses subscriptions...");
connection
.createQueryBuilder()
.delete()
.from(TokenToAddress)
.where("address IN (:...id)", { id: ADDRESS_IGNORE_LIST })
.execute()
.then(() => console.log("Addresses subscriptions purged ok"))
.catch((error) => console.log("error purging addresses subscriptions:", error));
};
const killSleepingMySQLProcesses = () => {
console.log("Checking for sleeping MySQL processes...");
// Query to find processes sleeping for more than 3600 seconds
const query = `
SELECT id, user, host, db, command, time, state, info
FROM information_schema.processlist
WHERE command = 'Sleep' AND time > 3600 AND id != CONNECTION_ID()
`;
connection
.query(query)
.then((sleepingProcesses: any[]) => {
if (sleepingProcesses.length > 0) {
console.log(`Found ${sleepingProcesses.length} sleeping processes older than 1 hour`);
// Kill each sleeping process
const killPromises = sleepingProcesses.map((process) => {
console.log(`Killing process ID ${process.id} (user: ${process.user}, host: ${process.host}, sleeping for ${process.time}s)`);
return connection
.query(`KILL ${process.id}`)
.then(() => console.log(`Successfully killed process ${process.id}`))
.catch((error) => console.log(`Error killing process ${process.id}:`, error.message));
});
return Promise.all(killPromises);
} else {
console.log("No sleeping processes found that are older than 1 hour");
}
})
.catch((error) => {
console.log("Error checking sleeping processes:", error.message);
});
};
dataSource.initialize().then((c) => {
console.log("db connected");
connection = c;
purgeIgnoredAddressesSubscriptions();
pushLogPurge();
purgeOldTxidSubscriptions();
killSleepingMySQLProcesses();
setInterval(pushLogPurge, 3600 * 1000);
setInterval(killSleepingMySQLProcesses, 3600 * 1000); // Run every hour
});
export class GroundController {
private _tokenToAddressRepository;
private _tokenToHashRepository;
private _tokenToTxidRepository;
private _tokenConfigurationRepository;
private _sendQueueRepository;
private _connection: DataSource;
constructor(connection: DataSource) {
this._connection = connection;
}
get tokenToAddressRepository() {
if (this._tokenToAddressRepository) {
return this._tokenToAddressRepository;
}
this._tokenToAddressRepository = connection.getRepository(TokenToAddress);
this._tokenToAddressRepository = this._connection.getRepository(TokenToAddress);
return this._tokenToAddressRepository;
}
@ -206,7 +44,7 @@ export class GroundController {
if (this._tokenToHashRepository) {
return this._tokenToHashRepository;
}
this._tokenToHashRepository = connection.getRepository(TokenToHash);
this._tokenToHashRepository = this._connection.getRepository(TokenToHash);
return this._tokenToHashRepository;
}
@ -215,7 +53,7 @@ export class GroundController {
return this._tokenToTxidRepository;
}
this._tokenToTxidRepository = connection.getRepository(TokenToTxid);
this._tokenToTxidRepository = this._connection.getRepository(TokenToTxid);
return this._tokenToTxidRepository;
}
@ -224,7 +62,7 @@ export class GroundController {
return this._tokenConfigurationRepository;
}
this._tokenConfigurationRepository = connection.getRepository(TokenConfiguration);
this._tokenConfigurationRepository = this._connection.getRepository(TokenConfiguration);
return this._tokenConfigurationRepository;
}
@ -233,7 +71,7 @@ export class GroundController {
return this._sendQueueRepository;
}
this._sendQueueRepository = connection.getRepository(SendQueue);
this._sendQueueRepository = this._connection.getRepository(SendQueue);
return this._sendQueueRepository;
}
@ -395,13 +233,13 @@ export class GroundController {
}
async ping(request: Request, response: Response, next: NextFunction) {
const keyValueRepository = connection.getRepository(KeyValue);
const sendQueueRepository = connection.getRepository(SendQueue);
const keyValueRepository = this._connection.getRepository(KeyValue);
const sendQueueRepository = this._connection.getRepository(SendQueue);
const keyVal = await keyValueRepository.findOneBy({ key: LAST_PROCESSED_BLOCK });
const send_queue_size = await sendQueueRepository.count();
const ts = new Date(+new Date() - 1000 * 3600 * 24).toISOString();
const sent_24h = await connection.createQueryBuilder(PushLog, "PushLog").where("PushLog.created >= :ts", { ts }).getCount();
const sent_24h = await this._connection.createQueryBuilder(PushLog, "PushLog").where("PushLog.created >= :ts", { ts }).getCount();
const serverInfo: paths["/ping"]["get"]["responses"]["200"]["content"]["application/json"] = {
name: pck.name,

View File

@ -4,6 +4,11 @@ import * as bodyParser from "body-parser";
import { Request, Response } from "express";
import { Routes } from "./routes";
import dataSource from "./data-source";
import { PushLog } from "./entity/PushLog";
import { TokenToTxid } from "./entity/TokenToTxid";
import { TokenToAddress } from "./entity/TokenToAddress";
import { DataSource } from "typeorm";
import { ADDRESS_IGNORE_LIST } from "./address-ignore-list";
require("dotenv").config();
const helmet = require("helmet");
const cors = require("cors");
@ -12,9 +17,94 @@ if (!process.env.JAWSDB_MARIA_URL || !process.env.GOOGLE_KEY_FILE || !process.en
process.exit();
}
let connection: DataSource;
const pushLogPurge = () => {
console.log("purging PushLog...");
let today = new Date();
connection
.createQueryBuilder()
.delete()
.from(PushLog)
.where("created <= :currentDate", { currentDate: new Date(today.getTime() - 3 * 24 * 60 * 60 * 1000) })
.execute()
.then(() => console.log("PushLog purged ok"))
.catch((error) => console.log("error purging PushLog:", error));
};
const purgeOldTxidSubscriptions = () => {
console.log("purging TokenToTxid...");
let today = new Date();
connection
.createQueryBuilder()
.delete()
.from(TokenToTxid)
.where("created <= :currentDate", { currentDate: new Date(today.getTime() - 3 * 30 * 24 * 60 * 60 * 1000) }) // 3 mo
.execute()
.then(() => console.log("TokenToTxid purged ok"))
.catch((error) => console.log("error purging TokenToTxid:", error));
};
const purgeIgnoredAddressesSubscriptions = () => {
console.log("Purging addresses subscriptions...");
connection
.createQueryBuilder()
.delete()
.from(TokenToAddress)
.where("address IN (:...id)", { id: ADDRESS_IGNORE_LIST })
.execute()
.then(() => console.log("Addresses subscriptions purged ok"))
.catch((error) => console.log("error purging addresses subscriptions:", error));
};
const killSleepingMySQLProcesses = () => {
console.log("Checking for sleeping MySQL processes...");
// Query to find processes sleeping for too long
const query = `
SELECT id, user, host, db, command, time, state, info
FROM information_schema.processlist
WHERE command = 'Sleep' AND time > 100 AND id != CONNECTION_ID()
`;
connection
.query(query)
.then((sleepingProcesses: any[]) => {
if (sleepingProcesses.length > 0) {
console.log(`Found ${sleepingProcesses.length} old sleeping processes`);
// Kill each sleeping process
const killPromises = sleepingProcesses.map((process) => {
console.log(`Killing process ID ${process.id} (user: ${process.user}, host: ${process.host}, sleeping for ${process.time}s)`);
return connection
.query(`KILL ${process.id}`)
.then(() => console.log(`Successfully killed process ${process.id}`))
.catch((error) => console.log(`Error killing process ${process.id}:`, error.message));
});
return Promise.all(killPromises);
} else {
console.log("No old sleeping processes found");
}
})
.catch((error) => {
console.log("Error checking sleeping processes:", error.message);
});
};
dataSource
.initialize()
.then(async (connection) => {
.then(async (c) => {
console.log("db connected");
connection = c;
purgeIgnoredAddressesSubscriptions();
pushLogPurge();
purgeOldTxidSubscriptions();
killSleepingMySQLProcesses();
setInterval(pushLogPurge, 3600 * 1000);
setInterval(killSleepingMySQLProcesses, 100 * 1000);
// create express app
const app = express();
app.use(bodyParser.json());
@ -25,7 +115,7 @@ dataSource
// register express routes from defined application routes
Routes.forEach((route) => {
(app as any)[route.method](route.route, (req: Request, res: Response, next: Function) => {
const result = new (route.controller as any)()[route.action](req, res, next);
const result = new (route.controller as any)(c)[route.action](req, res, next);
if (result instanceof Promise) {
result.then((result) => (result !== null && result !== undefined ? res.send(result) : undefined));
} else if (result !== null && result !== undefined) {

View File

@ -162,7 +162,7 @@ describe("GroundController", () => {
// Dynamically import GroundController after setting up environment
const { GroundController } = await import("../controller/GroundController");
groundController = new GroundController();
groundController = new GroundController((mockConnection as unknown) as DataSource);
// Mock the connection property by directly setting repositories
(groundController as any)._tokenToAddressRepository = mockRepository;

View File

@ -117,6 +117,7 @@ dataSource
.initialize()
.then(async (connection) => {
// start worker
console.log("db connected");
console.log("running groundcontrol worker-blockprocessor");
console.log(require("fs").readFileSync("./bowie.txt").toString("ascii"));

View File

@ -115,6 +115,7 @@ dataSource
.initialize()
.then(async (connection) => {
// start worker
console.log("db connected");
console.log("running groundcontrol worker-processmempool");
console.log(require("fs").readFileSync("./bowie.txt").toString("ascii"));

View File

@ -25,6 +25,7 @@ dataSource
.initialize()
.then(async (connection) => {
// start worker
console.log("db connected");
console.log("running groundcontrol worker-sender");
console.log(require("fs").readFileSync("./bowie.txt").toString("ascii"));