Skip to content

Commit 3910c14

Browse files
authored
102 performant send (#120)
* add: performance test as subproject, run it in CI * fix: producer interface after rebase * fix: improve readability * add message buffer in producer * add: buffer data in writer grows in size as needed, with max hard limit * fix test: add maxFrameSize parameter in PublishRequeest instantiation * add test for scheduled flush of producer queue * update: perftest forces NullLogger in connection object * add: write buffer size parameters (max, growth ratio, initial size) can be passed to connection objects * fix: passed parameters to perftest * fix: exit immediately on perftest error * fix: constant reference when computing new write buffer size * update: use connection frameMax parameter when creating a new publisher * fix: type definition in perftest
1 parent 00d56f6 commit 3910c14

26 files changed

+521
-69
lines changed

package-lock.json

Lines changed: 80 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,16 @@
3131
"@tsconfig/node16": "^1.0.3",
3232
"@types/amqplib": "^0.10.1",
3333
"@types/chai": "^4.3.4",
34+
"@types/chai-as-promised": "^7.1.8",
35+
"@types/chai-spies": "^1.0.6",
3436
"@types/mocha": "^10.0.1",
3537
"@types/node": "^16.18.11",
3638
"@typescript-eslint/eslint-plugin": "^5.50.0",
3739
"@typescript-eslint/parser": "^5.50.0",
3840
"amqplib": "^0.10.3",
3941
"chai": "^4.3.7",
42+
"chai-as-promised": "^7.1.1",
43+
"chai-spies": "^1.1.0",
4044
"cspell": "^6.21.0",
4145
"eslint": "^8.33.0",
4246
"eslint-config-prettier": "^8.6.0",

performance_test/index.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { randomUUID } from "crypto"
44
import { argv } from "process"
55
import { PerfTestProducer } from "./perf_test_producer"
66
import { inspect } from "util"
7+
import { BufferSizeSettings } from "../dist/requests/request"
78

89
const logger = createLogger({
910
level: "info",
@@ -18,6 +19,8 @@ const logger = createLogger({
1819
transports: new transports.Console(),
1920
})
2021

22+
const connLogger = undefined
23+
2124
function parseArgs(args) {
2225
const zip = (a: string[], b: string[]): [string, number][] => {
2326
const shorterArray = a.length < b.length ? a : b
@@ -36,23 +39,30 @@ function parseArgs(args) {
3639
async function main() {
3740
const rabbitUser = process.env.RABBITMQ_USER || "rabbit"
3841
const rabbitPassword = process.env.RABBITMQ_PASSWORD || "rabbit"
42+
const bufferSizeSettings: BufferSizeSettings = { initialSize: 16384 }
43+
const frameMax = 65536
44+
3945
const connection = await connect(
4046
{
4147
hostname: "localhost",
4248
port: 5552,
4349
username: rabbitUser,
4450
password: rabbitPassword,
51+
bufferSizeSettings: bufferSizeSettings,
4552
vhost: "/",
53+
frameMax,
4654
},
47-
logger
55+
connLogger
4856
)
4957

5058
const streamName = `my-stream-${randomUUID()}`
5159
await connection.createStream({ stream: streamName, arguments: {} })
5260
const publisherRef = `my-publisher-${randomUUID()}`
5361
const passedArgs = parseArgs(argv.slice(2))
5462
logger.info(
55-
`Stream: ${streamName} - publisher ${publisherRef} - max messages ${passedArgs.maxMessages} - message size: ${passedArgs.messageSize} bytes`
63+
`Stream: ${streamName} - publisher ${publisherRef} - max messages ${passedArgs.maxMessages} - message size: ${
64+
passedArgs.messageSize
65+
} bytes - write buffer settings: ${inspect(bufferSizeSettings)}`
5666
)
5767

5868
const perfTestProducer = new PerfTestProducer(
@@ -67,8 +77,8 @@ async function main() {
6777
}
6878

6979
main()
70-
.then((_v) => {
71-
logger.info(`Ending...`)
72-
setTimeout(() => process.exit(0), 1000)
80+
.then((_v) => setTimeout(() => process.exit(0), 1000))
81+
.catch((res) => {
82+
logger.error("ERROR ", res)
83+
process.exit(400)
7384
})
74-
.catch((res) => logger.error("ERROR ", res))

performance_test/package-lock.json

Lines changed: 10 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

performance_test/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"main": "index.js",
66
"scripts": {
77
"test": "echo \"Error: no test specified\" && exit 1",
8-
"perftest": "ts-node ./index.ts"
8+
"perftest": "ts-node ./index.ts",
9+
"perftest-reset": "cd .. && npm run build && cd - && npm install --force && ts-node ./index.ts"
910
},
1011
"author": "",
1112
"license": "ISC",

performance_test/perf_test_producer.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,36 +27,39 @@ export class PerfTestProducer {
2727
const publisher = await this.connection.declarePublisher(this.publisherParams)
2828
publisher.on("publish_confirm", (err, confirmedIds) => {
2929
if (err) {
30-
console.log(err)
30+
this.logger.error(err)
3131
}
3232
this.metrics.addCounter("confirmed", confirmedIds.length)
3333
})
3434

3535
this.displayTimer = setInterval(() => {
3636
this.displayMetrics()
3737
this.metrics.setStart()
38-
}, 1000)
38+
}, 500)
3939

4040
await this.send(publisher)
41+
42+
return true
4143
}
4244

4345
private displayMetrics(stop: boolean = false) {
4446
const metrics = { ...this.metrics.getMetrics(), total: this.ctr }
45-
this.logger.info(`${new Date().toISOString()} - ${inspect(metrics)}`)
47+
this.logger.info(`${inspect(metrics)}`)
4648
if (stop && this.displayTimer) {
4749
clearInterval(this.displayTimer)
4850
}
4951
}
5052

5153
private async send(publisher: Producer) {
5254
while (this.maxMessages === -1 || this.ctr < this.maxMessages) {
53-
const nmsgs = this.maxMessages > 0 ? Math.min(this.maxChunkSize, this.maxMessages) : this.maxChunkSize
54-
for (let index = 0; index < nmsgs; index++) {
55+
const messageQuantity = this.maxMessages > 0 ? Math.min(this.maxChunkSize, this.maxMessages) : this.maxChunkSize
56+
for (let index = 0; index < messageQuantity; index++) {
5557
await publisher.send(this.payload, {})
5658
}
57-
this.ctr = this.ctr + nmsgs
58-
this.metrics.addCounter("published", nmsgs)
59+
this.ctr = this.ctr + messageQuantity
60+
this.metrics.addCounter("published", messageQuantity)
5961
}
62+
this.displayMetrics(true)
6063
}
6164

6265
public getDisplayTimer() {

0 commit comments

Comments
 (0)