kythia-core 0.9.4-beta → 0.9.4-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +25 -0
- package/package.json +1 -1
- package/src/database/KythiaModel.js +21 -24
- package/src/database/KythiaORM.js +10 -5
package/changelog.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
|
+
|
|
5
|
+
### [0.9.4-beta.1](https://github.com/kenndeclouv/kythia-core/compare/v0.9.4-beta.0...v0.9.4-beta.1) (2025-11-09)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ✨ Added
|
|
9
|
+
|
|
10
|
+
* Refactor KythiaORM to sync multiple models in a single operation, improving efficiency and logging. Updated version hashes in model_versions table after sync completion. ([1bc195d](https://github.com/kenndeclouv/kythia-core/commit/1bc195d17d67865d01cb6c0290a2715f876b2451))
|
|
11
|
+
|
|
12
|
+
### 0.9.4-beta.0 (2025-11-04)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### 🔧 Changed
|
|
16
|
+
|
|
17
|
+
* Kythia core library structure and update version to 0.9.1-beta. Simplified index.js exports, improved README with installation instructions, and enhanced documentation across various modules. Updated license to CC BY NC 4.0. Cleaned up unnecessary comments and improved code readability. ([1967b65](https://github.com/kenndeclouv/kythia-core/commit/1967b651d49b4c2a85403c2e5d7a58d95ba1d1ed))
|
|
18
|
+
* Update package name to "kythia-core", adjust LRUCache import, and ensure logger availability in InteractionManager for command execution context. ([9e90cf6](https://github.com/kenndeclouv/kythia-core/commit/9e90cf6e04c4655ffbf71813e173de8b8d074b79))
|
|
19
|
+
* Update version to 0.9.2-beta, enhance caching layer with LRU cache support, and improve sharding awareness in KythiaModel. ([6cfb275](https://github.com/kenndeclouv/kythia-core/commit/6cfb275543410aee6e5df429036be9571134618b))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### ✨ Added
|
|
23
|
+
|
|
24
|
+
* Enhance KythiaModel with multi-Redis fallback support, allowing connection to multiple Redis URLs for improved failover handling. Updated dependency injection to accept various Redis options and refined error handling for Redis connections. ([9eac22b](https://github.com/kenndeclouv/kythia-core/commit/9eac22b299b06842514e9576cdf1c08c09944a50))
|
|
25
|
+
* Introduce failover cache flushing in KythiaModel during Redis connection recovery, enhancing error handling and connection management. Added a flag to track failover state and updated event handlers for improved logging and cache management. ([bb30d36](https://github.com/kenndeclouv/kythia-core/commit/bb30d36a845086675fd35774d773fc04d213bc0b))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kythia-core",
|
|
3
|
-
"version": "0.9.4-beta",
|
|
3
|
+
"version": "0.9.4-beta.1",
|
|
4
4
|
"description": "Core library for the Kythia main Discord bot: extensible, modular, and scalable foundation for commands, components, and event management.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -74,6 +74,7 @@ class KythiaModel extends Model {
|
|
|
74
74
|
static _redisFallbackURLs = [];
|
|
75
75
|
static _redisCurrentIndex = 0;
|
|
76
76
|
static _redisFailedIndexes = new Set();
|
|
77
|
+
static _justFailedOver = false;
|
|
77
78
|
|
|
78
79
|
/**
|
|
79
80
|
* 💉 Injects core dependencies into the KythiaModel class.
|
|
@@ -187,6 +188,9 @@ class KythiaModel extends Model {
|
|
|
187
188
|
this.logger.warn(
|
|
188
189
|
`[REDIS][FAILOVER] Trying to switch Redis connection from url index ${prevIndex} to ${this._redisCurrentIndex}`
|
|
189
190
|
);
|
|
191
|
+
|
|
192
|
+
this._justFailedOver = true;
|
|
193
|
+
|
|
190
194
|
this._closeCurrentRedis();
|
|
191
195
|
this.initializeRedis();
|
|
192
196
|
return true;
|
|
@@ -214,7 +218,6 @@ class KythiaModel extends Model {
|
|
|
214
218
|
*/
|
|
215
219
|
static initializeRedis(redisOptions) {
|
|
216
220
|
if (redisOptions) {
|
|
217
|
-
// ... (Logic ini biarin aja, udah bener) ...
|
|
218
221
|
if (Array.isArray(redisOptions)) {
|
|
219
222
|
this._redisFallbackURLs = redisOptions.slice();
|
|
220
223
|
this._redisCurrentIndex = 0;
|
|
@@ -228,7 +231,6 @@ class KythiaModel extends Model {
|
|
|
228
231
|
}
|
|
229
232
|
|
|
230
233
|
if (!Array.isArray(this._redisFallbackURLs) || this._redisFallbackURLs.length === 0) {
|
|
231
|
-
// ... (Logic error ini biarin aja, udah bener) ...
|
|
232
234
|
if (this.isShardMode) {
|
|
233
235
|
this.logger.error('❌ [REDIS][SHARD] No Redis URL/options provided but shard:true. Will run without caching!');
|
|
234
236
|
this.isRedisConnected = false;
|
|
@@ -252,12 +254,8 @@ class KythiaModel extends Model {
|
|
|
252
254
|
|
|
253
255
|
let redisOpt;
|
|
254
256
|
if (typeof opt === 'string') {
|
|
255
|
-
// --- 👇 PERUBAHAN DI SINI 👇 ---
|
|
256
|
-
// HAPUS lazyConnect: true
|
|
257
257
|
redisOpt = { url: opt, retryStrategy: this._makeRetryStrategy() };
|
|
258
258
|
} else if (opt && typeof opt === 'object') {
|
|
259
|
-
// --- 👇 PERUBAHAN DI SINI 👇 ---
|
|
260
|
-
// HAPUS lazyConnect: true
|
|
261
259
|
redisOpt = {
|
|
262
260
|
maxRetriesPerRequest: 2,
|
|
263
261
|
enableReadyCheck: true,
|
|
@@ -276,21 +274,13 @@ class KythiaModel extends Model {
|
|
|
276
274
|
}`
|
|
277
275
|
);
|
|
278
276
|
|
|
279
|
-
// --- 👇 PERUBAHAN DI SINI 👇 ---
|
|
280
|
-
// Biarin ioredis otomatis konek (nggak pake lazy)
|
|
281
277
|
this.redis = new Redis(redisOpt.url || redisOpt);
|
|
282
|
-
|
|
283
|
-
// Langsung pasang handler
|
|
278
|
+
|
|
284
279
|
this._setupRedisEventHandlers();
|
|
285
280
|
|
|
286
|
-
// HAPUS PANGGILAN ke _attemptConnection()
|
|
287
|
-
|
|
288
281
|
return this.redis;
|
|
289
282
|
}
|
|
290
283
|
|
|
291
|
-
// HAPUS Fungsi _attemptConnection
|
|
292
|
-
// (Sudah tidak ada atau di bawah ini harus DIHAPUS sepenuhnya)
|
|
293
|
-
|
|
294
284
|
/**
|
|
295
285
|
* Internal: Makes retry strategy function which wraps the fallback failover logic if all failed.
|
|
296
286
|
* Used by initializeRedis.
|
|
@@ -314,7 +304,7 @@ class KythiaModel extends Model {
|
|
|
314
304
|
* @private
|
|
315
305
|
*/
|
|
316
306
|
static _setupRedisEventHandlers() {
|
|
317
|
-
this.redis.on('connect', () => {
|
|
307
|
+
this.redis.on('connect', async () => {
|
|
318
308
|
if (!this.isRedisConnected) {
|
|
319
309
|
this.logger.info('✅ [REDIS] Connection established. Switching to Redis Cache mode.');
|
|
320
310
|
}
|
|
@@ -324,14 +314,23 @@ class KythiaModel extends Model {
|
|
|
324
314
|
clearTimeout(this.reconnectTimeout);
|
|
325
315
|
this.reconnectTimeout = null;
|
|
326
316
|
}
|
|
327
|
-
this._redisFailedIndexes.delete(this._redisCurrentIndex);
|
|
317
|
+
this._redisFailedIndexes.delete(this._redisCurrentIndex);
|
|
318
|
+
|
|
319
|
+
if (this._justFailedOver) {
|
|
320
|
+
this.logger.warn(`[REDIS][FAILOVER] Connected to new server, flushing potentially stale cache...`);
|
|
321
|
+
try {
|
|
322
|
+
await this.redis.flushdb();
|
|
323
|
+
this.logger.info(`[REDIS][FAILOVER] Stale cache flushed successfully.`);
|
|
324
|
+
} catch (err) {
|
|
325
|
+
this.logger.error(`[REDIS][FAILOVER] FAILED TO FLUSH CACHE:`, err);
|
|
326
|
+
}
|
|
327
|
+
this._justFailedOver = false;
|
|
328
|
+
}
|
|
328
329
|
});
|
|
329
330
|
|
|
330
331
|
this.redis.on('error', (err) => {
|
|
331
|
-
// (Biarkan handler 'error' ini kosong atau cuma nge-log,
|
|
332
|
-
// karena 'close' yang akan nanganin failover)
|
|
333
332
|
if (err && (err.code === 'ECONNREFUSED' || err.message)) {
|
|
334
|
-
|
|
333
|
+
this.logger.warn(`🟠 [REDIS] Connection error: ${err.message}`);
|
|
335
334
|
}
|
|
336
335
|
});
|
|
337
336
|
|
|
@@ -345,9 +344,8 @@ class KythiaModel extends Model {
|
|
|
345
344
|
}
|
|
346
345
|
this.isRedisConnected = false;
|
|
347
346
|
|
|
348
|
-
this._redisFailedIndexes.add(this._redisCurrentIndex);
|
|
347
|
+
this._redisFailedIndexes.add(this._redisCurrentIndex);
|
|
349
348
|
|
|
350
|
-
// --- INI LOGIKA KUNCINYA ---
|
|
351
349
|
this.logger.warn(`[REDIS] Connection #${this._redisCurrentIndex + 1} closed. Attempting immediate failover...`);
|
|
352
350
|
const triedFailover = this._tryRedisFailover();
|
|
353
351
|
|
|
@@ -355,7 +353,6 @@ class KythiaModel extends Model {
|
|
|
355
353
|
this.logger.warn(`[REDIS] Failover exhausted. Scheduling full reconnect...`);
|
|
356
354
|
this._scheduleReconnect();
|
|
357
355
|
}
|
|
358
|
-
// --- AKHIR LOGIKA KUNCI ---
|
|
359
356
|
});
|
|
360
357
|
}
|
|
361
358
|
|
|
@@ -380,7 +377,7 @@ class KythiaModel extends Model {
|
|
|
380
377
|
this.reconnectTimeout = null;
|
|
381
378
|
|
|
382
379
|
this._redisCurrentIndex = 0;
|
|
383
|
-
this._redisFailedIndexes.clear();
|
|
380
|
+
this._redisFailedIndexes.clear();
|
|
384
381
|
this._closeCurrentRedis();
|
|
385
382
|
this.initializeRedis();
|
|
386
383
|
}, RECONNECT_DELAY_MINUTES * 60 * 1000);
|
|
@@ -448,10 +448,17 @@ async function KythiaORM({ kythiaInstance, sequelize, KythiaModel, logger, confi
|
|
|
448
448
|
}
|
|
449
449
|
}
|
|
450
450
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
451
|
+
const modelNamesToSync = modelsToSync.map(m => m.model.name);
|
|
452
|
+
|
|
453
|
+
logger.info(`🔄 Syncing models via sequelize.sync(): ${modelNamesToSync.join(', ')}...`);
|
|
454
|
+
await sequelize.sync({
|
|
455
|
+
models: modelNamesToSync,
|
|
456
|
+
alter: true,
|
|
457
|
+
});
|
|
458
|
+
logger.info('✅ Model sync complete.');
|
|
454
459
|
|
|
460
|
+
logger.info('💾 Updating version hashes in model_versions table...');
|
|
461
|
+
for (const { model, newHash } of modelsToSync) {
|
|
455
462
|
await sequelize.query(
|
|
456
463
|
`INSERT INTO ${versionTableName} (model_name, version_hash, updated_at)
|
|
457
464
|
VALUES (?, ?, CURRENT_TIMESTAMP)
|
|
@@ -462,8 +469,6 @@ async function KythiaORM({ kythiaInstance, sequelize, KythiaModel, logger, confi
|
|
|
462
469
|
type: sequelize.QueryTypes.INSERT,
|
|
463
470
|
}
|
|
464
471
|
);
|
|
465
|
-
|
|
466
|
-
logger.info(`✅ Synced model: ${model.name} (${newHash})`);
|
|
467
472
|
}
|
|
468
473
|
|
|
469
474
|
logger.info('✨ Database sync completed successfully!');
|