How do I persist changes to values
inside a Singleton
class object?
I set and get a class object value
with a setter
and getter
method like:
wwjsInstances.setInstance("name1", client);
wwjsInstances.getInstance("name1")
My wwjsInstances.js
:
/*
|--------------------------------------------------------------------------
| Singleton : wwjsInstances Class
|--------------------------------------------------------------------------
*/
class wwjsInstances {
// Var > Initialize
message;
instances = {};
/*
|--------------------------------------------------------------------------
| Constructor
|--------------------------------------------------------------------------
*/
constructor() {
this.message = 'I am an instance';
}
/*
|--------------------------------------------------------------------------
| Method
|--------------------------------------------------------------------------
*/
setInstance(clientId, clientSession) {
try {
this.instances[clientId] = clientSession;
} catch (err) {
throw new Error("[wwjsInstances] : Failed to Attach Session to Singleton", err);
}
return true;
}
/*
|--------------------------------------------------------------------------
| Method
|--------------------------------------------------------------------------
*/
getInstance( clientId ){
return this.instances[clientId]
}
}
module.exports = new wwjsInstances();
The value
of the class object is another object ( non UI WhatsApp Web Client Object, used for all WhatsApp operations )
Inside my /server.js
file, I got this snippet:
/*
|--------------------------------------------------------------------------
| Whatsapp Client
|--------------------------------------------------------------------------
*/
const wwjsServiceModule = require("./app/services/wwjsService");
const wwjsInstances = require('./app/services/wwjsInstances');
// Starts > Non-UI WhatsApp Web App
wwjsServiceModule.createSession("name1").then((client) => {
// Add > Instance Object [ Non-UI WhatsApp Web App ] > To > Singleton > Object Array [ There can be multiple clients running concurrently ]
wwjsInstances.setInstance("name1", client);
// Log
console.log('wwjsInstances.getInstance: ', wwjsInstances.getInstance("name1")); // works, sample log below:
// <ref *1> Client
// {
// _events: [Object
// :
// null
// prototype
// ]
// {
// authenticated: [Function(anonymous)],
// auth_failure
// :
// [Function(anonymous)],
// loading_screen
// :
// [Function(anonymous)],
// qr
// :
// [Function(anonymous)],
// message
// :
// [AsyncFunction(anonymous)],
// message_create
// :
// [Function(anonymous)],
//
// ....
//
//
// }
//
// }
});
The wwjsInstances.getInstance("name1")
in the .then()
callback works and it returns the Client
object
I got another .js
file named process.js
, it is a .js
file I run with node ./app/queues/process.js
to run & process my jobs.
I am using node.js
OptimalBits/bull
queue
This is my process.js
file:
const EventEmitter = require("events");
EventEmitter.defaultMaxListeners = 50;
// The processor to define/link [ Job Processing Function ]
const processorModule = require("../tasks/File/processor");
// The producer [ Queue ]
const { uploadFileByIdQueue, sendWhatsAppMessageQueue } = require(".");
const wwjsServiceModule = require("../services/wwjsService");
const wwjsInstances = require('../../app/services/wwjsInstances');
/*
|--------------------------------------------------------------------------
| Handler : Failure
|--------------------------------------------------------------------------
*/
const handleFailure = (job, err) => {
if (job.attemptsMade >= job.opts.attempts) {
console.log(`Job failures above threshold in ${job.queue.name} for: ${JSON.stringify(
job.data
)}`);
job.remove();
return null;
}
console.log(`Job in ${job.queue.name} failed for: ${JSON.stringify(job.data)} with ${
err.message
}. ${job.opts.attempts - job.attemptsMade} attempts left`);
};
/*
|--------------------------------------------------------------------------
| Handler : Completed
|--------------------------------------------------------------------------
*/
const handleCompleted = job => {
console.log(`Job in ${job.queue.name} completed for: ${JSON.stringify(job.data)}`);
job.remove();
};
/*
|--------------------------------------------------------------------------
| Handler : Stalled
|--------------------------------------------------------------------------
*/
const handleStalled = job => {
console.log(`Job in ${job.queue.name} stalled for: ${JSON.stringify(job.data)}`);
};
/*
|--------------------------------------------------------------------------
| Queue(s) > Active
|--------------------------------------------------------------------------
*/
const activeQueues = [
// {
// queue: uploadFileByIdQueue, // Queue
// processor: processorModule.uploadFileByIdProcessor // Processor
// },
{
queue: sendWhatsAppMessageQueue, // Queue
processor: processorModule.sendWhatsAppProcessor // Processor
}
];
/*
|--------------------------------------------------------------------------
| Queue(s) > For Each > Loop
|--------------------------------------------------------------------------
*/
activeQueues.forEach(handler => {
console.log('[WhatsApp] : process.js > activeQueues.forEach() > wwjsInstances > Singleton: ', wwjsInstances);
// [WRONG, NOT UPDATED] > Result: wwjsInstances { message: 'I am an instance', instances: {} }
let client = wwjsInstances.getInstance("foodcrush")
console.log('[WhatsApp] : process.js > activeQueues.forEach() > wwjsInstances.getInstance("foodcrush"):', client);
// [WRONG, NOT UPDATED] > Result: undefined
// Get > Queue
const queue = handler.queue;
// Get > Processor
const processor = handler.processor;
const failHandler = handler.failHandler || handleFailure;
const completedHandler = handler.completedHandler || handleCompleted;
// here are samples of listener events : "failed","completed","stalled", the other events will be ignored
queue.on("failed", failHandler);
queue.on("completed", completedHandler);
queue.on("stalled", handleStalled);
queue.process(processor);// link the correspondant processor/worker
console.log(`Queue > getJobs: ${JSON.stringify(queue.getJobs(), null, 2)}...`);
console.log(`Processing ${queue.name}...`);
});
As you can see with the process.js
I ran with node ./app/queues/process.js
, the Singleton
class object value (instance
) is never updated,
it still shows the old default value defined in the .js
class file
wwjsInstances
returns { message: 'I am an instance', instances: {} }
and
wwjsInstances.getInstance("foodcrush")
returns undefined
the update to the instance
class object value done in /server.js
never persisted, why is that?