harness: parallelize service startup
This commit is contained in:
parent
7fbe28e640
commit
ec3ae6f5e3
@ -540,7 +540,7 @@ function backoffStart(): number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function backoffIncrement(n: number): number {
|
function backoffIncrement(n: number): number {
|
||||||
return Math.max(n * 2, 1000);
|
return Math.min(Math.floor(n * 1.5), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -563,7 +563,7 @@ export async function pingProc(
|
|||||||
return;
|
return;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
logger.warn(`service ${serviceName} not ready:`, e.toString());
|
logger.warn(`service ${serviceName} not ready:`, e.toString());
|
||||||
//console.log(e);
|
logger.info(`waiting ${nextDelay}ms`);
|
||||||
await delayMs(nextDelay);
|
await delayMs(nextDelay);
|
||||||
nextDelay = backoffIncrement(nextDelay);
|
nextDelay = backoffIncrement(nextDelay);
|
||||||
}
|
}
|
||||||
@ -1535,15 +1535,20 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(): Promise<void> {
|
async start(opts: { skipSetup?: boolean } = {}): Promise<void> {
|
||||||
if (this.isRunning()) {
|
if (this.isRunning()) {
|
||||||
throw Error("exchange is already running");
|
throw Error("exchange is already running");
|
||||||
}
|
}
|
||||||
await sh(
|
|
||||||
this.globalState,
|
const skipSetup = opts.skipSetup ?? false;
|
||||||
"exchange-dbinit",
|
|
||||||
`taler-exchange-dbinit -c "${this.configFilename}"`,
|
if (!skipSetup) {
|
||||||
);
|
await sh(
|
||||||
|
this.globalState,
|
||||||
|
"exchange-dbinit",
|
||||||
|
`taler-exchange-dbinit -c "${this.configFilename}"`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.helperCryptoEddsaProc = this.globalState.spawnService(
|
this.helperCryptoEddsaProc = this.globalState.spawnService(
|
||||||
"taler-exchange-secmod-eddsa",
|
"taler-exchange-secmod-eddsa",
|
||||||
@ -1574,7 +1579,11 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await this.pingUntilAvailable();
|
await this.pingUntilAvailable();
|
||||||
await this.keyup();
|
if (!skipSetup) {
|
||||||
|
await this.keyup();
|
||||||
|
} else {
|
||||||
|
logger.info("skipping keyup");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async pingUntilAvailable(): Promise<void> {
|
async pingUntilAvailable(): Promise<void> {
|
||||||
@ -1912,13 +1921,17 @@ export class MerchantService implements MerchantServiceInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(): Promise<void> {
|
async start(opts: { skipSetup?: boolean } = {}): Promise<void> {
|
||||||
await runCommand(
|
const skipSetup = opts.skipSetup ?? false;
|
||||||
this.globalState,
|
|
||||||
"merchant-dbinit",
|
if (!skipSetup) {
|
||||||
"taler-merchant-dbinit",
|
await runCommand(
|
||||||
["-c", this.configFilename],
|
this.globalState,
|
||||||
);
|
"merchant-dbinit",
|
||||||
|
"taler-merchant-dbinit",
|
||||||
|
["-c", this.configFilename],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.proc = this.globalState.spawnService(
|
this.proc = this.globalState.spawnService(
|
||||||
"taler-merchant-httpd",
|
"taler-merchant-httpd",
|
||||||
@ -2285,12 +2298,14 @@ export class WalletService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async pingUntilAvailable(): Promise<void> {
|
async pingUntilAvailable(): Promise<void> {
|
||||||
|
let nextDelay = backoffStart();
|
||||||
while (1) {
|
while (1) {
|
||||||
try {
|
try {
|
||||||
await tryUnixConnect(this.socketPath);
|
await tryUnixConnect(this.socketPath);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.info(`connection attempt failed: ${e}`);
|
logger.info(`connection attempt failed: ${e}`);
|
||||||
await delayMs(200);
|
await delayMs(nextDelay);
|
||||||
|
nextDelay = backoffIncrement(nextDelay);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
logger.info("connection to wallet-core succeeded");
|
logger.info("connection to wallet-core succeeded");
|
||||||
|
@ -218,9 +218,6 @@ export async function createSimpleTestkudosEnvironment(
|
|||||||
export async function useSharedTestkudosEnvironment(t: GlobalTestState) {
|
export async function useSharedTestkudosEnvironment(t: GlobalTestState) {
|
||||||
const coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS"));
|
const coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS"));
|
||||||
|
|
||||||
// FIXME: We should probably have some file to indicate that
|
|
||||||
// the previous env setup finished successfully.
|
|
||||||
|
|
||||||
const sharedDir = `/tmp/taler-harness@${process.env.USER}`;
|
const sharedDir = `/tmp/taler-harness@${process.env.USER}`;
|
||||||
|
|
||||||
fs.mkdirSync(sharedDir, { recursive: true });
|
fs.mkdirSync(sharedDir, { recursive: true });
|
||||||
@ -270,7 +267,7 @@ export async function useSharedTestkudosEnvironment(t: GlobalTestState) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("setting up exchange");
|
logger.info("setting up merchant");
|
||||||
|
|
||||||
let merchant: MerchantService;
|
let merchant: MerchantService;
|
||||||
const merchantName = "testmerchant-1";
|
const merchantName = "testmerchant-1";
|
||||||
@ -308,38 +305,59 @@ export async function useSharedTestkudosEnvironment(t: GlobalTestState) {
|
|||||||
|
|
||||||
logger.info("basic setup done, starting services");
|
logger.info("basic setup done, starting services");
|
||||||
|
|
||||||
await bank.start();
|
const bankStart = async () => {
|
||||||
|
await bank.start();
|
||||||
|
|
||||||
await bank.pingUntilAvailable();
|
await bank.pingUntilAvailable();
|
||||||
|
};
|
||||||
|
|
||||||
await exchange.start();
|
const exchangeStart = async () => {
|
||||||
await exchange.pingUntilAvailable();
|
await exchange.start({
|
||||||
|
skipSetup: prevSetupDone,
|
||||||
|
});
|
||||||
|
await exchange.pingUntilAvailable();
|
||||||
|
};
|
||||||
|
|
||||||
await merchant.start();
|
const merchStart = async () => {
|
||||||
await merchant.pingUntilAvailable();
|
await merchant.start({
|
||||||
|
skipSetup: prevSetupDone,
|
||||||
|
});
|
||||||
|
await merchant.pingUntilAvailable();
|
||||||
|
|
||||||
await merchant.addInstance({
|
if (!prevSetupDone) {
|
||||||
id: "default",
|
await merchant.addInstance({
|
||||||
name: "Default Instance",
|
id: "default",
|
||||||
paytoUris: [getPayto("merchant-default")],
|
name: "Default Instance",
|
||||||
defaultWireTransferDelay: Duration.toTalerProtocolDuration(
|
paytoUris: [getPayto("merchant-default")],
|
||||||
Duration.fromSpec({ minutes: 1 }),
|
defaultWireTransferDelay: Duration.toTalerProtocolDuration(
|
||||||
),
|
Duration.fromSpec({ minutes: 1 }),
|
||||||
});
|
),
|
||||||
|
});
|
||||||
|
|
||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "minst1",
|
id: "minst1",
|
||||||
name: "minst1",
|
name: "minst1",
|
||||||
paytoUris: [getPayto("minst1")],
|
paytoUris: [getPayto("minst1")],
|
||||||
defaultWireTransferDelay: Duration.toTalerProtocolDuration(
|
defaultWireTransferDelay: Duration.toTalerProtocolDuration(
|
||||||
Duration.fromSpec({ minutes: 1 }),
|
Duration.fromSpec({ minutes: 1 }),
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const { walletClient, walletService } = await createWalletDaemonWithClient(
|
const walletStart = async () => {
|
||||||
t,
|
return await createWalletDaemonWithClient(t, { name: "wallet" });
|
||||||
{ name: "wallet" },
|
};
|
||||||
);
|
|
||||||
|
const res = await Promise.all([
|
||||||
|
exchangeStart(),
|
||||||
|
merchStart(),
|
||||||
|
bankStart(),
|
||||||
|
walletStart(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const walletClient = res[3].walletClient;
|
||||||
|
const walletService = res[3].walletService;
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
|
|
||||||
@ -399,7 +417,7 @@ export async function createSimpleTestkudosEnvironmentV2(
|
|||||||
bank.setSuggestedExchange(exchange, exchangeBankAccount.accountPaytoUri);
|
bank.setSuggestedExchange(exchange, exchangeBankAccount.accountPaytoUri);
|
||||||
|
|
||||||
if (opts.additionalBankConfig) {
|
if (opts.additionalBankConfig) {
|
||||||
opts.additionalBankConfig(bank)
|
opts.additionalBankConfig(bank);
|
||||||
}
|
}
|
||||||
await bank.start();
|
await bank.start();
|
||||||
|
|
||||||
@ -428,7 +446,7 @@ export async function createSimpleTestkudosEnvironmentV2(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opts.additionalExchangeConfig) {
|
if (opts.additionalExchangeConfig) {
|
||||||
opts.additionalExchangeConfig(exchange)
|
opts.additionalExchangeConfig(exchange);
|
||||||
}
|
}
|
||||||
await exchange.start();
|
await exchange.start();
|
||||||
await exchange.pingUntilAvailable();
|
await exchange.pingUntilAvailable();
|
||||||
@ -436,7 +454,7 @@ export async function createSimpleTestkudosEnvironmentV2(
|
|||||||
merchant.addExchange(exchange);
|
merchant.addExchange(exchange);
|
||||||
|
|
||||||
if (opts.additionalMerchantConfig) {
|
if (opts.additionalMerchantConfig) {
|
||||||
opts.additionalMerchantConfig(merchant)
|
opts.additionalMerchantConfig(merchant);
|
||||||
}
|
}
|
||||||
await merchant.start();
|
await merchant.start();
|
||||||
await merchant.pingUntilAvailable();
|
await merchant.pingUntilAvailable();
|
||||||
|
Loading…
Reference in New Issue
Block a user