mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
238 lines
6.7 KiB
JavaScript
238 lines
6.7 KiB
JavaScript
// HotPocket test client to collect metrics.
|
|
// This assumes the HotPocket server we are connecting to is hosting the echo contract.
|
|
|
|
const HotPocket = require('hotpocket-js-client');
|
|
|
|
let server = 'wss://localhost:8080';
|
|
if (process.argv.length == 3) server = 'wss://localhost:' + process.argv[2];
|
|
if (process.argv.length == 4) server = 'wss://' + process.argv[2] + ':' + process.argv[3];
|
|
console.log("Server: " + server);
|
|
|
|
let activity = {};
|
|
|
|
async function main() {
|
|
|
|
HotPocket.setLogLevel(1);
|
|
|
|
const tests = {
|
|
"Large payload": () => largePayload(2),
|
|
"Single user read requests": () => multiUserReadRequests(10, 10, 1),
|
|
"Single user Input/Output": () => multiUserInputOutput(10, 10, 1),
|
|
"Multi user read requests": () => multiUserReadRequests(10, 10, 10),
|
|
"Multi user Input/Output": () => multiUserInputOutput(10, 10, 10),
|
|
};
|
|
|
|
activityLogger();
|
|
|
|
// Execute all tests.
|
|
for (const test in tests) {
|
|
|
|
console.log();
|
|
console.log(test + "...");
|
|
|
|
// The test will return single or multiple tuples of time periods.
|
|
// Multiple tuples mean that the test had multiple sub-tests inside it.
|
|
// Each tuple indicates [start time, end time] of a particular atomic test.
|
|
const result = await tests[test]();
|
|
|
|
// Test ended. Clear activity.
|
|
activity = {};
|
|
|
|
// If the result is a single period tuple, put them in a parent array.
|
|
const runPeriods = Array.isArray(result[0]) ? result : [result];
|
|
|
|
// Duration is calculated as the duration between earliest start time and latest end time.
|
|
const startTimes = runPeriods.map(p => p[0]);
|
|
const endTimes = runPeriods.map(p => p[1]);
|
|
const minStartTime = Math.min.apply(null, startTimes);
|
|
const maxEndTime = Math.max.apply(null, endTimes);
|
|
const duration = maxEndTime - minStartTime;
|
|
console.log(duration + "ms");
|
|
}
|
|
|
|
activity = null;
|
|
console.log("Done.");
|
|
}
|
|
|
|
async function activityLogger() {
|
|
if (activity && Object.keys(activity).length > 0)
|
|
console.log(JSON.stringify(activity));
|
|
|
|
if (activity)
|
|
setTimeout(() => activityLogger(), 1000);
|
|
}
|
|
|
|
async function createClient() {
|
|
increment("creating");
|
|
const keys = await HotPocket.generateKeys();
|
|
|
|
const hpc = await HotPocket.createClient([server], keys,
|
|
{
|
|
contractId: "3c349abe-4d70-4f50-9fa6-018f1f2530ab",
|
|
protocol: HotPocket.protocols.json
|
|
});
|
|
|
|
// Establish HotPocket connection.
|
|
if (!await hpc.connect()) {
|
|
throw "Connection failed."
|
|
}
|
|
decrement("creating");
|
|
increment("clients");
|
|
|
|
return hpc;
|
|
}
|
|
|
|
function singleUserReadRequests(payloadKB, requestCount) {
|
|
|
|
return new Promise(async resolve => {
|
|
|
|
const payload = "A".repeat(payloadKB * 1024);
|
|
let respCount = 0;
|
|
|
|
const hpc = await createClient();
|
|
const timer = new Timer();
|
|
|
|
hpc.on(HotPocket.events.contractReadResponse, (response) => {
|
|
increment("readresp");
|
|
respCount++;
|
|
if (respCount == requestCount) {
|
|
const runPeriod = timer.stop();
|
|
hpc.close().then(() => resolve(runPeriod));
|
|
}
|
|
});
|
|
|
|
timer.start();
|
|
for (let i = 0; i < requestCount; i++) {
|
|
increment("submitting");
|
|
hpc.sendContractReadRequest(payload).then(() => {
|
|
decrement("submitting");
|
|
increment("submitted");
|
|
});
|
|
}
|
|
})
|
|
}
|
|
|
|
function singleUserInputOutput(payloadKB, requestCount) {
|
|
return new Promise(async (resolve) => {
|
|
|
|
const payload = "A".repeat(payloadKB * 1024);
|
|
let respCount = 0;
|
|
|
|
const hpc = await createClient();
|
|
const timer = new Timer();
|
|
|
|
hpc.on(HotPocket.events.contractOutput, (r) => {
|
|
r.outputs.forEach(response => {
|
|
increment("outputs");
|
|
respCount++;
|
|
if (respCount == requestCount) {
|
|
const runPeriod = timer.stop();
|
|
hpc.close().then(() => resolve(runPeriod));
|
|
}
|
|
});
|
|
});
|
|
|
|
timer.start();
|
|
for (let i = 0; i < requestCount; i++) {
|
|
increment("submitting");
|
|
const input = await hpc.submitContractInput(payload);
|
|
decrement("submitting");
|
|
increment("submitted");
|
|
input.submissionStatus.then(onStatusResponse);
|
|
}
|
|
})
|
|
}
|
|
|
|
function multiUserReadRequests(payloadKB, requestCountPerUser, userCount) {
|
|
|
|
console.log("Submitting " + (requestCountPerUser * userCount) + " requests.");
|
|
|
|
const tasks = [];
|
|
for (let i = 0; i < userCount; i++) {
|
|
tasks.push(singleUserReadRequests(payloadKB, requestCountPerUser));
|
|
}
|
|
return Promise.all(tasks);
|
|
}
|
|
|
|
function multiUserInputOutput(payloadKB, requestCountPerUser, userCount) {
|
|
|
|
console.log("Submitting " + (requestCountPerUser * userCount) + " requests.");
|
|
|
|
const tasks = [];
|
|
for (let i = 0; i < userCount; i++) {
|
|
tasks.push(singleUserInputOutput(payloadKB, requestCountPerUser));
|
|
}
|
|
return Promise.all(tasks);
|
|
}
|
|
|
|
function largePayload(payloadMB) {
|
|
console.log("Submitting " + payloadMB + " MB request.")
|
|
return new Promise(async (resolve) => {
|
|
|
|
const payload = "A".repeat(payloadMB * 1024 * 1024);
|
|
|
|
const hpc = await createClient();
|
|
const timer = new Timer();
|
|
|
|
hpc.on(HotPocket.events.contractOutput, (r) => {
|
|
r.outputs.forEach(response => {
|
|
increment("outputs");
|
|
if (response.length < payload.length)
|
|
console.log("Payload length mismatch.");
|
|
|
|
const runPeriod = timer.stop();
|
|
hpc.close().then(() => resolve(runPeriod));
|
|
})
|
|
});
|
|
|
|
timer.start();
|
|
increment("submitting");
|
|
const input = await hpc.submitContractInput(payload);
|
|
decrement("submitting");
|
|
increment("submitted");
|
|
input.submissionStatus.then(onStatusResponse);
|
|
})
|
|
}
|
|
|
|
function increment(key) {
|
|
if (!activity[key])
|
|
activity[key] = 0;
|
|
activity[key]++;
|
|
}
|
|
|
|
function decrement(key) {
|
|
activity[key]--;
|
|
if (activity[key] == 0)
|
|
delete activity[key];
|
|
}
|
|
|
|
function onStatusResponse(s) {
|
|
|
|
increment("statresp");
|
|
|
|
if (!activity.groups)
|
|
activity.groups = {};
|
|
|
|
if (!activity.groups[s.status])
|
|
activity.groups[s.status] = 0;
|
|
|
|
activity.groups[s.status]++;
|
|
|
|
if (s.status != "accepted")
|
|
console.log(s.reason);
|
|
}
|
|
|
|
function Timer() {
|
|
let startedOn = null;
|
|
|
|
this.start = () => {
|
|
startedOn = new Date().getTime();
|
|
}
|
|
|
|
this.stop = () => {
|
|
const endedOn = new Date().getTime();
|
|
return [startedOn, endedOn];
|
|
}
|
|
}
|
|
|
|
main(); |