2025-11-18 14:53:44 -08:00
|
|
|
import Logger from '@joplin/utils/Logger';
|
2025-07-07 08:07:27 -07:00
|
|
|
import ActionTracker from './ActionTracker';
|
|
|
|
|
import Client from './Client';
|
|
|
|
|
import { CleanupTask, FuzzContext } from './types';
|
|
|
|
|
|
|
|
|
|
type AddCleanupTask = (task: CleanupTask)=> void;
|
|
|
|
|
type ClientFilter = (client: Client)=> boolean;
|
|
|
|
|
|
2025-11-18 14:53:44 -08:00
|
|
|
const logger = Logger.create('ClientPool');
|
|
|
|
|
|
2025-07-07 08:07:27 -07:00
|
|
|
export default class ClientPool {
|
|
|
|
|
public static async create(
|
|
|
|
|
context: FuzzContext,
|
|
|
|
|
clientCount: number,
|
|
|
|
|
addCleanupTask: AddCleanupTask,
|
|
|
|
|
) {
|
|
|
|
|
if (clientCount <= 0) throw new Error('There must be at least 1 client');
|
|
|
|
|
|
|
|
|
|
const actionTracker = new ActionTracker(context);
|
|
|
|
|
const clientPool: Client[] = [];
|
|
|
|
|
for (let i = 0; i < clientCount; i++) {
|
|
|
|
|
const client = await Client.create(actionTracker, context);
|
|
|
|
|
addCleanupTask(() => client.close());
|
|
|
|
|
clientPool.push(client);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new ClientPool(context, clientPool);
|
|
|
|
|
}
|
2025-11-18 14:53:44 -08:00
|
|
|
private constructor(
|
2025-07-07 08:07:27 -07:00
|
|
|
private readonly context_: FuzzContext,
|
2025-08-10 01:14:25 -07:00
|
|
|
private clients_: Client[],
|
|
|
|
|
) {
|
|
|
|
|
for (const client of clients_) {
|
|
|
|
|
this.listenForClientClose_(client);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private listenForClientClose_(client: Client) {
|
|
|
|
|
client.onClose(() => {
|
|
|
|
|
this.clients_ = this.clients_.filter(other => other !== client);
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-07-07 08:07:27 -07:00
|
|
|
|
2025-11-18 14:53:44 -08:00
|
|
|
public async createInitialItemsAndSync() {
|
|
|
|
|
for (const client of this.clients) {
|
|
|
|
|
logger.info('Creating items for ', client.email);
|
|
|
|
|
const actionCount = this.context_.randomFrom([0, 10, 100]);
|
|
|
|
|
await client.createOrUpdateMany(actionCount);
|
|
|
|
|
|
|
|
|
|
await client.sync();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-19 23:46:23 -07:00
|
|
|
public clientsByEmail(email: string) {
|
|
|
|
|
return this.clients.filter(client => client.email === email);
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-07 08:07:27 -07:00
|
|
|
public randomClient(filter: ClientFilter = ()=>true) {
|
2025-08-10 01:14:25 -07:00
|
|
|
const clients = this.clients_.filter(filter);
|
2025-07-07 08:07:27 -07:00
|
|
|
return clients[
|
|
|
|
|
this.context_.randInt(0, clients.length)
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-18 05:57:44 -07:00
|
|
|
public async newWithSameAccount(sourceClient: Client) {
|
|
|
|
|
const client = await sourceClient.createClientOnSameAccount();
|
|
|
|
|
this.listenForClientClose_(client);
|
|
|
|
|
this.clients_ = [...this.clients_, client];
|
|
|
|
|
return client;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public othersWithSameAccount(client: Client) {
|
|
|
|
|
return this.clients_.filter(other => other !== client && other.hasSameAccount(client));
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-07 08:07:27 -07:00
|
|
|
public async checkState() {
|
2025-08-10 01:14:25 -07:00
|
|
|
for (const client of this.clients_) {
|
|
|
|
|
await client.checkState();
|
2025-07-07 08:07:27 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async syncAll() {
|
2025-11-18 14:53:44 -08:00
|
|
|
// Sync all clients at roughly the same time. Some sync bugs are only apparent
|
|
|
|
|
// when multiple clients are syncing simultaneously.
|
|
|
|
|
await Promise.all(this.clients_.map(c => c.sync()));
|
|
|
|
|
|
|
|
|
|
// Note: For more deterministic behavior, sync clients individually instead:
|
|
|
|
|
// for (const client of this.clients_) { await client.sync(); }
|
2025-07-07 08:07:27 -07:00
|
|
|
}
|
|
|
|
|
|
2025-08-10 01:14:25 -07:00
|
|
|
public get clients() {
|
|
|
|
|
return [...this.clients_];
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-07 08:07:27 -07:00
|
|
|
public helpText() {
|
2025-08-10 01:14:25 -07:00
|
|
|
return this.clients_.map(client => client.getHelpText()).join('\n\n');
|
2025-07-07 08:07:27 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|