Skip to content

Commit

Permalink
+ k6 scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
palkan committed Sep 13, 2024
1 parent 40e8c03 commit 23885f6
Show file tree
Hide file tree
Showing 2 changed files with 225 additions and 0 deletions.
141 changes: 141 additions & 0 deletions scripts/k6/benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Build k6 with xk6-cable like this:
// xk6 build v0.38.3 --with github.com/anycable/[email protected]

import { check, sleep, fail } from "k6";
import cable from "k6/x/cable";
import { randomIntBetween } from "https://jslib.k6.io/k6-utils/1.1.0/index.js";

const rampingOptions = {
scenarios: {
default: {
executor: "ramping-vus",
startVUs: 100,
stages: [
{ duration: "20s", target: 300 },
{ duration: "20s", target: 500 },
{ duration: "30s", target: 1000 },
{ duration: "30s", target: 1300 },
{ duration: "30s", target: 1500 },
{ duration: "50s", target: 1500 },
{ duration: "60s", target: 0 },
],
gracefulStop: "5m",
gracefulRampDown: "5m",
},
},
};

export const options = __ENV.SKIP_OPTIONS ? {} : rampingOptions;

import { Trend, Counter } from "k6/metrics";
let rttTrend = new Trend("rtt", true);
let broadcastTrend = new Trend("broadcast_duration", true);
let broadcastsSent = new Counter("broadcasts_sent");
let broadcastsRcvd = new Counter("broadcasts_rcvd");
let acksRcvd = new Counter("acks_rcvd");

// Load ENV from .env
function loadDotEnv() {
try {
let dotenv = open("./.env");
dotenv.split(/[\n\r]/m).forEach((line) => {
// Ignore comments
if (line[0] === "#") return;

let parts = line.split("=", 2);

__ENV[parts[0]] = parts[1];
});
} catch (_err) {}
}

loadDotEnv();

let config = __ENV;

config.URL = config.URL || "ws://localhost:8080/cable";

let url = config.URL;
let channelName = config.CHANNEL_ID || "BenchmarkChannel";

let sendersRatio = parseFloat(config.SENDERS_RATIO || "0.2") || 1;
let sendersMod = (1 / sendersRatio) | 0;
let sender = __VU % sendersMod == 0;

let sendingRate = parseFloat(config.SENDING_RATE || "0.2");

let iterations = (config.N || "100") | 0;

export default function () {
let cableOptions = {
receiveTimeoutMs: 15000,
};

// Prevent from creating a lot of connections at once
sleep(randomIntBetween(2, 10) / 5);

let client = cable.connect(url, cableOptions);

if (
!check(client, {
"successful connection": (obj) => obj,
})
) {
// Cooldown
sleep(randomIntBetween(5, 10) / 5);
fail("connection failed");
}

let channel = client.subscribe(channelName);

if (
!check(channel, {
"successful subscription": (obj) => obj,
})
) {
// Cooldown
sleep(randomIntBetween(5, 10) / 5);
fail("failed to subscribe");
}

for (let i = 0; ; i++) {
// Sampling
if (sender && randomIntBetween(1, 10) / 10 <= sendingRate) {
let start = Date.now();
broadcastsSent.add(1);
// Create message via cable instead of a form
channel.perform("broadcast", {
ts: start,
content: `hello from ${__VU} numero ${i + 1}`,
});
}

sleep(randomIntBetween(5, 10) / 100);

let incoming = channel.receiveAll(1);

for (let message of incoming) {
let received = message.__timestamp__ || Date.now();

if (message.action == "broadcastResult") {
acksRcvd.add(1);
let ts = message.ts;
rttTrend.add(received - ts);
}

if (message.action == "broadcast") {
broadcastsRcvd.add(1);
let ts = message.ts;
broadcastTrend.add(received - ts);
}
}

sleep(randomIntBetween(5, 10) / 10);

if (i > iterations) break;
}

sleep(randomIntBetween(5, 10) / 10);

client.disconnect();
}
84 changes: 84 additions & 0 deletions scripts/k6/connect_subscribe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Build k6 with xk6-cable like this:
// xk6 build v0.38.3 --with github.com/anycable/[email protected]

import { check, sleep, fail } from "k6";
import cable from "k6/x/cable";
import { randomIntBetween } from "https://jslib.k6.io/k6-utils/1.1.0/index.js";

const rampingOptions = {
scenarios: {
default: {
executor: "ramping-vus",
startVUs: 100,
stages: [
{ duration: "10s", target: 300 },
{ duration: "20s", target: 500 },
{ duration: "30s", target: 1000 },
{ duration: "60s", target: 1000 },
{ duration: "120s", target: 0 },
],
gracefulStop: "5m",
gracefulRampDown: "5m",
},
},
};

export const options = __ENV.SKIP_OPTIONS ? {} : rampingOptions;

let config = __ENV;

config.URL = config.URL || "ws://localhost:8080/cable";

let url = config.URL;
let channelName = config.CHANNEL || "BenchmarkChannel";
let streamsNum = (config.STREAMS || "50") | 0;
let streamId = __VU % streamsNum;
let iterations = (config.N || "100") | 0;

export default function () {
let cableOptions = {
receiveTimeoutMs: 15000,
};

// Prevent from creating a lot of connections at once
sleep(randomIntBetween(5, 10) / 10);

let client = cable.connect(url, cableOptions);

if (
!check(client, {
"successful connection": (obj) => obj,
})
) {
fail("connection failed");
}

let channel = client.subscribe(channelName, { id: streamId });

if (
!check(channel, {
"successful subscription": (obj) => obj,
})
) {
fail("failed to subscribe");
}

for (let i = 0; ; i++) {
// Sampling
if (randomIntBetween(1, 10) / 10 <= 0.3) {
channel.perform("broadcast", {
content: `hello from ${__VU} numero ${i + 1}`,
});
}

sleep(randomIntBetween(5, 10) / 100);

let incoming = channel.receiveAll(0.2);

sleep(randomIntBetween(5, 10) / 100);

if (i > iterations) break;
}

client.disconnect();
}

0 comments on commit 23885f6

Please sign in to comment.