Merge pull request #95 from w3nder/develop

Melhorando o desempenho no carregamento da instância.
This commit is contained in:
Davidson Gomes 2023-09-05 21:41:29 -03:00 committed by GitHub
commit 7a7e72897a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -7,7 +7,6 @@ import { join } from 'path';
import { Auth, ConfigService, Database, DelInstance, HttpServer, Redis } from '../../config/env.config'; import { Auth, ConfigService, Database, DelInstance, HttpServer, Redis } from '../../config/env.config';
import { Logger } from '../../config/logger.config'; import { Logger } from '../../config/logger.config';
import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config'; import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config';
import { NotFoundException } from '../../exceptions';
import { dbserver } from '../../libs/db.connect'; import { dbserver } from '../../libs/db.connect';
import { RedisCache } from '../../libs/redis.client'; import { RedisCache } from '../../libs/redis.client';
import { import {
@ -76,77 +75,57 @@ export class WAMonitoringService {
public async instanceInfo(instanceName?: string) { public async instanceInfo(instanceName?: string) {
this.logger.verbose('get instance info'); this.logger.verbose('get instance info');
if (instanceName && !this.waInstances[instanceName]) {
throw new NotFoundException(`Instance "${instanceName}" not found`);
}
const instances: any[] = [];
for await (const [key, value] of Object.entries(this.waInstances)) {
if (value) {
this.logger.verbose('get instance info: ' + key);
let chatwoot: any;
const urlServer = this.configService.get<HttpServer>('SERVER').URL; const urlServer = this.configService.get<HttpServer>('SERVER').URL;
const findChatwoot = await this.waInstances[key].findChatwoot(); const instances: any[] = await Promise.all(
Object.entries(this.waInstances).map(async ([key, value]) => {
const status = value?.connectionStatus?.state || 'unknown';
if (findChatwoot && findChatwoot.enabled) { if (status === 'unknown') {
chatwoot = { return null;
...findChatwoot,
webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(key)}`,
};
} }
if (value.connectionStatus.state === 'open') { if (status === 'open') {
this.logger.verbose('instance: ' + key + ' - connectionStatus: open'); this.logger.verbose('instance: ' + key + ' - connectionStatus: open');
}
const instanceData = { const instanceData: any = {
instance: { instance: {
instanceName: key, instanceName: key,
owner: value.wuid, owner: value.wuid,
profileName: (await value.getProfileName()) || 'not loaded', profileName: (await value.getProfileName()) || 'not loaded',
profilePictureUrl: value.profilePictureUrl, profilePictureUrl: value.profilePictureUrl,
profileStatus: (await value.getProfileStatus()) || '', profileStatus: (await value.getProfileStatus()) || '',
status: value.connectionStatus.state, status: status,
}, },
}; };
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL; instanceData.instance.serverUrl = urlServer;
instanceData.instance.apikey = (await this.repository.auth.find(key))?.apikey;
instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey; const findChatwoot = await this.waInstances[key].findChatwoot();
if (findChatwoot && findChatwoot.enabled) {
instanceData.instance['chatwoot'] = chatwoot; instanceData.instance.chatwoot = {
} ...findChatwoot,
webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(key)}`,
instances.push(instanceData);
} else {
this.logger.verbose('instance: ' + key + ' - connectionStatus: ' + value.connectionStatus.state);
const instanceData = {
instance: {
instanceName: key,
status: value.connectionStatus.state,
},
}; };
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey;
instanceData.instance['chatwoot'] = chatwoot;
}
instances.push(instanceData);
}
} }
} }
return instanceData;
}),
).then((results) => results.filter((instance) => instance !== null));
this.logger.verbose('return instance info: ' + instances.length); this.logger.verbose('return instance info: ' + instances.length);
return instances.find((i) => i.instance.instanceName === instanceName) ?? instances; if (instanceName) {
const instance = instances.find((i) => i.instance.instanceName === instanceName);
return instance || [];
}
return instances;
} }
private delInstanceFiles() { private delInstanceFiles() {
@ -199,7 +178,6 @@ export class WAMonitoringService {
this.logger.verbose('cleaning up instance in redis: ' + instanceName); this.logger.verbose('cleaning up instance in redis: ' + instanceName);
this.cache.reference = instanceName; this.cache.reference = instanceName;
await this.cache.delAll(); await this.cache.delAll();
this.cache.disconnect();
return; return;
} }
@ -245,67 +223,83 @@ export class WAMonitoringService {
} }
public async loadInstance() { public async loadInstance() {
this.logger.verbose('load instances'); this.logger.verbose('Loading instances');
const set = async (name: string) => {
try {
if (this.redis.ENABLED) {
await this.loadInstancesFromRedis();
} else if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
await this.loadInstancesFromDatabase();
} else {
await this.loadInstancesFromFiles();
}
} catch (error) {
this.logger.error(error);
}
}
private async setInstance(name: string) {
const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache);
instance.instanceName = name; instance.instanceName = name;
this.logger.verbose('instance loaded: ' + name); this.logger.verbose('Instance loaded: ' + name);
await instance.connectToWhatsapp(); await instance.connectToWhatsapp();
this.logger.verbose('connectToWhatsapp: ' + name); this.logger.verbose('connectToWhatsapp: ' + name);
this.waInstances[name] = instance; this.waInstances[name] = instance;
}; }
try { private async loadInstancesFromRedis() {
if (this.redis.ENABLED) { this.logger.verbose('Redis enabled');
this.logger.verbose('redis enabled');
await this.cache.connect(this.redis as Redis); await this.cache.connect(this.redis as Redis);
const keys = await this.cache.instanceKeys(); const keys = await this.cache.instanceKeys();
if (keys?.length > 0) { if (keys?.length > 0) {
this.logger.verbose('reading instance keys and setting instances'); this.logger.verbose('Reading instance keys and setting instances');
keys.forEach(async (k) => await set(k.split(':')[1])); await Promise.all(keys.map((k) => this.setInstance(k.split(':')[1])));
} else { } else {
this.logger.verbose('no instance keys found'); this.logger.verbose('No instance keys found');
} }
this.cache.disconnect();
return;
} }
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { private async loadInstancesFromDatabase() {
this.logger.verbose('database enabled'); this.logger.verbose('Database enabled');
await this.repository.dbServer.connect(); await this.repository.dbServer.connect();
const collections: any[] = await this.dbInstance.collections(); const collections: any[] = await this.dbInstance.collections();
if (collections.length > 0) { if (collections.length > 0) {
this.logger.verbose('reading collections and setting instances'); this.logger.verbose('Reading collections and setting instances');
collections.forEach(async (coll) => await set(coll.namespace.replace(/^[\w-]+\./, ''))); await Promise.all(collections.map((coll) => this.setInstance(coll.namespace.replace(/^[\w-]+\./, ''))));
} else { } else {
this.logger.verbose('no collections found'); this.logger.verbose('No collections found');
} }
return;
} }
this.logger.verbose('store in files enabled'); private async loadInstancesFromFiles() {
this.logger.verbose('Store in files enabled');
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
const instanceDirs = [];
for await (const dirent of dir) { for await (const dirent of dir) {
if (dirent.isDirectory()) { if (dirent.isDirectory()) {
this.logger.verbose('reading instance files and setting instances'); instanceDirs.push(dirent.name);
const files = readdirSync(join(INSTANCE_DIR, dirent.name), { } else {
encoding: 'utf-8', this.logger.verbose('No instance files found');
}); }
if (files.length === 0) {
rmSync(join(INSTANCE_DIR, dirent.name), { recursive: true, force: true });
break;
} }
await set(dirent.name); await Promise.all(
instanceDirs.map(async (instanceName) => {
this.logger.verbose('Reading instance files and setting instances: ' + instanceName);
const files = readdirSync(join(INSTANCE_DIR, instanceName), { encoding: 'utf-8' });
if (files.length === 0) {
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
} else { } else {
this.logger.verbose('no instance files found'); await this.setInstance(instanceName);
}
}
} catch (error) {
this.logger.error(error);
} }
}),
);
} }
private removeInstance() { private removeInstance() {