Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cli): optimize client id gen logic for bench #1829

Merged
merged 3 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions cli/src/__tests__/utils/getBenchClientId.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { expect, describe, it } from '@jest/globals'
import getBenchClientId from '../../utils/getBenchClientId'

describe('getBenchClientId', () => {
describe('single connection (count = 1)', () => {
it('should return original clientId when no placeholder', () => {
expect(getBenchClientId('mqtt_client', 1, 1)).toBe('mqtt_client')
})

it('should replace %i when has placeholder', () => {
expect(getBenchClientId('mqtt_client_%i', 1, 1)).toBe('mqtt_client_1')
})
})

describe('multiple connections (count > 1)', () => {
it('should append index when no placeholder', () => {
expect(getBenchClientId('mqtt_client', 1, 5)).toBe('mqtt_client_1')
})

it('should replace %i when has placeholder', () => {
expect(getBenchClientId('mqtt_client_%i', 2, 5)).toBe('mqtt_client_2')
})

it('should handle multiple %i placeholders', () => {
expect(getBenchClientId('mqtt_%i_client_%i', 3, 5)).toBe('mqtt_3_client_3')
})
})

describe('edge cases', () => {
it('should handle empty clientId', () => {
expect(getBenchClientId('', 1, 5)).toBe('_1')
})

it('should handle clientId with only %i', () => {
expect(getBenchClientId('%i', 1, 5)).toBe('1')
})
})
})
3 changes: 2 additions & 1 deletion cli/src/lib/conn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import delay from '../utils/delay'
import { handleSaveOptions, handleLoadOptions } from '../utils/options'
import * as Debug from 'debug'
import { triggerExitInfo } from '../utils/exitInfo'
import getBenchClientId from '../utils/getBenchClientId'

const conn = (options: ConnectOptions) => {
const { debug, saveOptions, loadOptions } = options
Expand Down Expand Up @@ -83,7 +84,7 @@ const benchConn = async (options: BenchConnectOptions) => {
;((i: number, connOpts: mqtt.IClientOptions) => {
const opts = { ...connOpts }

opts.clientId = clientId.includes('%i') ? clientId.replaceAll('%i', i.toString()) : `${clientId}_${i}`
opts.clientId = getBenchClientId(clientId, i, count)

const client = mqtt.connect(opts)

Expand Down
3 changes: 2 additions & 1 deletion cli/src/lib/pub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { serializeProtobufToBuffer } from '../utils/protobuf'
import { serializeAvroToBuffer } from '../utils/avro'
import { loadSimulator } from '../utils/simulate'
import { triggerExitInfo } from '../utils/exitInfo'
import getBenchClientId from '../utils/getBenchClientId'

/**
* Processes the outgoing message through two potential stages:
Expand Down Expand Up @@ -390,7 +391,7 @@ const multiPub = async (commandType: CommandType, options: BenchPublishOptions |
;((i: number, connOpts: mqtt.IClientOptions) => {
const opts = { ...connOpts }

opts.clientId = clientId.includes('%i') ? clientId.replaceAll('%i', i.toString()) : `${clientId}_${i}`
opts.clientId = getBenchClientId(clientId, i, count)

let topicName = topic.replaceAll('%i', i.toString()).replaceAll('%c', clientId)
username && (topicName = topicName.replaceAll('%u', username))
Expand Down
3 changes: 2 additions & 1 deletion cli/src/lib/sub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { deserializeBufferToProtobuf } from '../utils/protobuf'
import isSupportedBinaryFormatForMQTT from '../utils/binaryFormats'
import * as Debug from 'debug'
import { deserializeBufferToAvro } from '../utils/avro'
import getBenchClientId from '../utils/getBenchClientId'

/**
*
Expand Down Expand Up @@ -266,7 +267,7 @@ const benchSub = async (options: BenchSubscribeOptions) => {
;((i: number, connOpts: mqtt.IClientOptions) => {
const opts = { ...connOpts }

opts.clientId = clientId.includes('%i') ? clientId.replaceAll('%i', i.toString()) : `${clientId}_${i}`
opts.clientId = getBenchClientId(clientId, i, count)

const client = mqtt.connect(opts)

Expand Down
18 changes: 18 additions & 0 deletions cli/src/utils/getBenchClientId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Generate a unique client ID for benchmarking purposes
* @param clientId - Base client ID string that may contain '%i' placeholder
* @param index - Index number to replace placeholder or append to client ID
* @param count - Total count of clients being generated
* @returns Modified client ID string with index incorporated
*
* If clientId contains '%i', replaces all instances with index.
* If count > 1 and no '%i' placeholder exists, appends '_index' to clientId.
* Otherwise returns clientId unchanged.
*/
const getBenchClientId = (clientId: string, index: number, count: number) => {
const hasPlaceholder = clientId.includes('%i')
const baseClientId = hasPlaceholder ? clientId.replaceAll('%i', index.toString()) : clientId
return count > 1 && !hasPlaceholder ? `${baseClientId}_${index}` : baseClientId
}

export default getBenchClientId