memento-mcp-server 1.16.1-a → 1.16.2-a

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.
Files changed (163) hide show
  1. package/dist/client/index.d.ts.map +1 -1
  2. package/dist/client/index.js +4 -3
  3. package/dist/client/index.js.map +1 -1
  4. package/dist/domains/anchor/services/anchor/anchor-interfaces.d.ts +2 -4
  5. package/dist/domains/anchor/services/anchor/anchor-interfaces.d.ts.map +1 -1
  6. package/dist/domains/anchor/services/anchor/anchor-interfaces.js.map +1 -1
  7. package/dist/domains/anchor/services/anchor/anchor-manager.d.ts +2 -2
  8. package/dist/domains/anchor/services/anchor/anchor-manager.d.ts.map +1 -1
  9. package/dist/domains/anchor/services/anchor/anchor-manager.js.map +1 -1
  10. package/dist/domains/anchor/services/anchor/anchor-search-service.d.ts +11 -34
  11. package/dist/domains/anchor/services/anchor/anchor-search-service.d.ts.map +1 -1
  12. package/dist/domains/anchor/services/anchor/anchor-search-service.js +66 -549
  13. package/dist/domains/anchor/services/anchor/anchor-search-service.js.map +1 -1
  14. package/dist/domains/anchor/services/anchor/database-types.d.ts +28 -0
  15. package/dist/domains/anchor/services/anchor/database-types.d.ts.map +1 -0
  16. package/dist/domains/anchor/services/anchor/database-types.js +6 -0
  17. package/dist/domains/anchor/services/anchor/database-types.js.map +1 -0
  18. package/dist/domains/anchor/services/anchor/embedding-types.d.ts +20 -0
  19. package/dist/domains/anchor/services/anchor/embedding-types.d.ts.map +1 -0
  20. package/dist/domains/anchor/services/anchor/embedding-types.js +6 -0
  21. package/dist/domains/anchor/services/anchor/embedding-types.js.map +1 -0
  22. package/dist/domains/anchor/services/anchor/fallback-search-service.d.ts +36 -0
  23. package/dist/domains/anchor/services/anchor/fallback-search-service.d.ts.map +1 -0
  24. package/dist/domains/anchor/services/anchor/fallback-search-service.js +85 -0
  25. package/dist/domains/anchor/services/anchor/fallback-search-service.js.map +1 -0
  26. package/dist/domains/anchor/services/anchor/fallback-strategy.d.ts +25 -0
  27. package/dist/domains/anchor/services/anchor/fallback-strategy.d.ts.map +1 -0
  28. package/dist/domains/anchor/services/anchor/fallback-strategy.js +35 -0
  29. package/dist/domains/anchor/services/anchor/fallback-strategy.js.map +1 -0
  30. package/dist/domains/anchor/services/anchor/local-search-service.d.ts +72 -0
  31. package/dist/domains/anchor/services/anchor/local-search-service.d.ts.map +1 -0
  32. package/dist/domains/anchor/services/anchor/local-search-service.js +129 -0
  33. package/dist/domains/anchor/services/anchor/local-search-service.js.map +1 -0
  34. package/dist/domains/anchor/services/anchor/n-hop-search-service.d.ts +90 -0
  35. package/dist/domains/anchor/services/anchor/n-hop-search-service.d.ts.map +1 -0
  36. package/dist/domains/anchor/services/anchor/n-hop-search-service.js +385 -0
  37. package/dist/domains/anchor/services/anchor/n-hop-search-service.js.map +1 -0
  38. package/dist/domains/anchor/services/anchor/n-hop-search-strategy.d.ts +24 -0
  39. package/dist/domains/anchor/services/anchor/n-hop-search-strategy.d.ts.map +1 -0
  40. package/dist/domains/anchor/services/anchor/n-hop-search-strategy.js +39 -0
  41. package/dist/domains/anchor/services/anchor/n-hop-search-strategy.js.map +1 -0
  42. package/dist/domains/anchor/services/anchor/query-filter-service.d.ts +52 -0
  43. package/dist/domains/anchor/services/anchor/query-filter-service.d.ts.map +1 -0
  44. package/dist/domains/anchor/services/anchor/query-filter-service.js +136 -0
  45. package/dist/domains/anchor/services/anchor/query-filter-service.js.map +1 -0
  46. package/dist/domains/anchor/services/anchor/query-filter-strategy.d.ts +24 -0
  47. package/dist/domains/anchor/services/anchor/query-filter-strategy.d.ts.map +1 -0
  48. package/dist/domains/anchor/services/anchor/query-filter-strategy.js +34 -0
  49. package/dist/domains/anchor/services/anchor/query-filter-strategy.js.map +1 -0
  50. package/dist/domains/anchor/services/anchor/search-strategy-interfaces.d.ts +52 -0
  51. package/dist/domains/anchor/services/anchor/search-strategy-interfaces.d.ts.map +1 -0
  52. package/dist/domains/anchor/services/anchor/search-strategy-interfaces.js +6 -0
  53. package/dist/domains/anchor/services/anchor/search-strategy-interfaces.js.map +1 -0
  54. package/dist/domains/anchor/services/anchor/vector-search-engine-types.d.ts +18 -0
  55. package/dist/domains/anchor/services/anchor/vector-search-engine-types.d.ts.map +1 -0
  56. package/dist/domains/anchor/services/anchor/vector-search-engine-types.js +11 -0
  57. package/dist/domains/anchor/services/anchor/vector-search-engine-types.js.map +1 -0
  58. package/dist/domains/memory/repositories/core-memory-database.interface.d.ts +47 -0
  59. package/dist/domains/memory/repositories/core-memory-database.interface.d.ts.map +1 -0
  60. package/dist/domains/memory/repositories/core-memory-database.interface.js +7 -0
  61. package/dist/domains/memory/repositories/core-memory-database.interface.js.map +1 -0
  62. package/dist/domains/memory/repositories/core-memory-repository.d.ts +7 -77
  63. package/dist/domains/memory/repositories/core-memory-repository.d.ts.map +1 -1
  64. package/dist/domains/memory/repositories/core-memory-repository.interface.d.ts +92 -0
  65. package/dist/domains/memory/repositories/core-memory-repository.interface.d.ts.map +1 -0
  66. package/dist/domains/memory/repositories/core-memory-repository.interface.js +6 -0
  67. package/dist/domains/memory/repositories/core-memory-repository.interface.js.map +1 -0
  68. package/dist/domains/memory/repositories/core-memory-repository.js +7 -259
  69. package/dist/domains/memory/repositories/core-memory-repository.js.map +1 -1
  70. package/dist/domains/memory/services/core-memory-cache-service.d.ts +55 -0
  71. package/dist/domains/memory/services/core-memory-cache-service.d.ts.map +1 -1
  72. package/dist/domains/memory/services/core-memory-cache-service.js +110 -8
  73. package/dist/domains/memory/services/core-memory-cache-service.js.map +1 -1
  74. package/dist/domains/memory/services/core-memory-service.d.ts +2 -2
  75. package/dist/domains/memory/services/core-memory-service.d.ts.map +1 -1
  76. package/dist/domains/memory/services/core-memory-service.js +43 -24
  77. package/dist/domains/memory/services/core-memory-service.js.map +1 -1
  78. package/dist/domains/memory/tools/recall-tool.d.ts.map +1 -1
  79. package/dist/domains/memory/tools/recall-tool.js +2 -2
  80. package/dist/domains/memory/tools/recall-tool.js.map +1 -1
  81. package/dist/domains/memory/tools/remember-tool.d.ts.map +1 -1
  82. package/dist/domains/memory/tools/remember-tool.js +2 -2
  83. package/dist/domains/memory/tools/remember-tool.js.map +1 -1
  84. package/dist/domains/monitoring/services/performance-monitor.d.ts +8 -0
  85. package/dist/domains/monitoring/services/performance-monitor.d.ts.map +1 -1
  86. package/dist/domains/monitoring/services/performance-monitor.js +16 -0
  87. package/dist/domains/monitoring/services/performance-monitor.js.map +1 -1
  88. package/dist/infrastructure/async-optimizer.d.ts.map +1 -1
  89. package/dist/infrastructure/async-optimizer.js +8 -7
  90. package/dist/infrastructure/async-optimizer.js.map +1 -1
  91. package/dist/infrastructure/database/adapters/sqlite-core-memory-adapter.d.ts +31 -0
  92. package/dist/infrastructure/database/adapters/sqlite-core-memory-adapter.d.ts.map +1 -0
  93. package/dist/infrastructure/database/adapters/sqlite-core-memory-adapter.js +112 -0
  94. package/dist/infrastructure/database/adapters/sqlite-core-memory-adapter.js.map +1 -0
  95. package/dist/infrastructure/database/database/init.d.ts.map +1 -1
  96. package/dist/infrastructure/database/database/init.js +23 -2
  97. package/dist/infrastructure/database/database/init.js.map +1 -1
  98. package/dist/infrastructure/database/database/migration/migrations/010-add-core-memory-version.d.ts +64 -0
  99. package/dist/infrastructure/database/database/migration/migrations/010-add-core-memory-version.d.ts.map +1 -0
  100. package/dist/infrastructure/database/database/migration/migrations/010-add-core-memory-version.js +174 -0
  101. package/dist/infrastructure/database/database/migration/migrations/010-add-core-memory-version.js.map +1 -0
  102. package/dist/infrastructure/database/database/migration/migrations/010-add-core-memory-version.sql +25 -0
  103. package/dist/infrastructure/database/database-lock-monitor.d.ts +105 -0
  104. package/dist/infrastructure/database/database-lock-monitor.d.ts.map +1 -0
  105. package/dist/infrastructure/database/database-lock-monitor.js +265 -0
  106. package/dist/infrastructure/database/database-lock-monitor.js.map +1 -0
  107. package/dist/infrastructure/database/factories/core-memory-repository.factory.d.ts +17 -0
  108. package/dist/infrastructure/database/factories/core-memory-repository.factory.d.ts.map +1 -0
  109. package/dist/infrastructure/database/factories/core-memory-repository.factory.js +43 -0
  110. package/dist/infrastructure/database/factories/core-memory-repository.factory.js.map +1 -0
  111. package/dist/infrastructure/database/repositories/core-memory-repository-sqlite.impl.d.ts +63 -0
  112. package/dist/infrastructure/database/repositories/core-memory-repository-sqlite.impl.d.ts.map +1 -0
  113. package/dist/infrastructure/database/repositories/core-memory-repository-sqlite.impl.js +281 -0
  114. package/dist/infrastructure/database/repositories/core-memory-repository-sqlite.impl.js.map +1 -0
  115. package/dist/infrastructure/database/wal-checkpoint-scheduler.d.ts +166 -0
  116. package/dist/infrastructure/database/wal-checkpoint-scheduler.d.ts.map +1 -0
  117. package/dist/infrastructure/database/wal-checkpoint-scheduler.js +285 -0
  118. package/dist/infrastructure/database/wal-checkpoint-scheduler.js.map +1 -0
  119. package/dist/npm-client/memento-client.d.ts.map +1 -1
  120. package/dist/npm-client/memento-client.js +5 -4
  121. package/dist/npm-client/memento-client.js.map +1 -1
  122. package/dist/npm-client/memory-manager.d.ts.map +1 -1
  123. package/dist/npm-client/memory-manager.js +4 -3
  124. package/dist/npm-client/memory-manager.js.map +1 -1
  125. package/dist/scripts/check-migration-status.d.ts.map +1 -1
  126. package/dist/scripts/check-migration-status.js +1 -0
  127. package/dist/scripts/check-migration-status.js.map +1 -1
  128. package/dist/server/bootstrap.d.ts +4 -0
  129. package/dist/server/bootstrap.d.ts.map +1 -1
  130. package/dist/server/bootstrap.js +27 -2
  131. package/dist/server/bootstrap.js.map +1 -1
  132. package/dist/server/http-server.d.ts.map +1 -1
  133. package/dist/server/http-server.js +59 -31
  134. package/dist/server/http-server.js.map +1 -1
  135. package/dist/server/index.js +32 -16
  136. package/dist/server/index.js.map +1 -1
  137. package/dist/server/simple-mcp-server.d.ts.map +1 -1
  138. package/dist/server/simple-mcp-server.js +15 -14
  139. package/dist/server/simple-mcp-server.js.map +1 -1
  140. package/dist/shared/config/environment.d.ts.map +1 -1
  141. package/dist/shared/config/environment.js +13 -1
  142. package/dist/shared/config/environment.js.map +1 -1
  143. package/dist/shared/config/index.d.ts.map +1 -1
  144. package/dist/shared/config/index.js +13 -1
  145. package/dist/shared/config/index.js.map +1 -1
  146. package/dist/shared/types/index.d.ts +10 -0
  147. package/dist/shared/types/index.d.ts.map +1 -1
  148. package/dist/tools/base-tool.d.ts.map +1 -1
  149. package/dist/tools/base-tool.js +5 -4
  150. package/dist/tools/base-tool.js.map +1 -1
  151. package/dist/tools/migrate-embeddings-tool.d.ts.map +1 -1
  152. package/dist/tools/migrate-embeddings-tool.js +2 -1
  153. package/dist/tools/migrate-embeddings-tool.js.map +1 -1
  154. package/dist/tools/tool-registry.d.ts.map +1 -1
  155. package/dist/tools/tool-registry.js +4 -3
  156. package/dist/tools/tool-registry.js.map +1 -1
  157. package/dist/workers/consolidation-score-worker.d.ts.map +1 -1
  158. package/dist/workers/consolidation-score-worker.js +5 -4
  159. package/dist/workers/consolidation-score-worker.js.map +1 -1
  160. package/package.json +1 -1
  161. package/scripts/check-file-sizes.ts +405 -0
  162. package/scripts/count-any-types.ts +375 -0
  163. package/scripts/count-console-logs.ts +451 -0
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Migration: 010 - Add Core Memory Version Column
3
+ * Description: Add version column to core_memory table for cache invalidation
4
+ * Version: 10.0
5
+ * Date: 2025-12-25
6
+ */
7
+ import type Database from 'better-sqlite3';
8
+ import type { Migration } from '../types.js';
9
+ /**
10
+ * Add Core Memory Version Column Migration
11
+ *
12
+ * This migration:
13
+ * 1. Adds version column to core_memory table (INTEGER NOT NULL DEFAULT 0)
14
+ * 2. Sets version = 1 for all existing rows
15
+ * 3. Creates index on version column for efficient queries
16
+ *
17
+ * Purpose:
18
+ * - Enable version-based cache invalidation
19
+ * - Track changes to core memory records
20
+ * - Support distributed cache synchronization in the future
21
+ */
22
+ export declare class AddCoreMemoryVersionMigration implements Migration {
23
+ version: string;
24
+ name: string;
25
+ description: string;
26
+ /**
27
+ * Load SQL file content
28
+ */
29
+ private loadSQLFile;
30
+ /**
31
+ * Execute SQL script
32
+ * Removes transaction commands (BEGIN TRANSACTION, COMMIT) as MigrationRunner manages transactions
33
+ */
34
+ private executeSQL;
35
+ /**
36
+ * Check if table exists
37
+ */
38
+ private tableExists;
39
+ /**
40
+ * Check if index exists
41
+ */
42
+ private indexExists;
43
+ /**
44
+ * Check if column exists in table
45
+ */
46
+ private columnExists;
47
+ /**
48
+ * Validate before migration
49
+ */
50
+ validateBefore(db: Database.Database): Promise<void>;
51
+ /**
52
+ * Execute migration (Up)
53
+ */
54
+ up(db: Database.Database): Promise<void>;
55
+ /**
56
+ * Rollback migration (Down)
57
+ */
58
+ down(db: Database.Database): Promise<void>;
59
+ /**
60
+ * Validate after migration
61
+ */
62
+ validateAfter(db: Database.Database): Promise<void>;
63
+ }
64
+ //# sourceMappingURL=010-add-core-memory-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"010-add-core-memory-version.d.ts","sourceRoot":"","sources":["../../../../../../src/infrastructure/database/database/migration/migrations/010-add-core-memory-version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAI3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAM7C;;;;;;;;;;;;GAYG;AACH,qBAAa,6BAA8B,YAAW,SAAS;IAC7D,OAAO,SAAU;IACjB,IAAI,SAA6B;IACjC,WAAW,SAAoE;IAE/E;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAsBlB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACG,cAAc,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D;;OAEG;IACG,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C;;OAEG;IACG,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BhD;;OAEG;IACG,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAyC1D"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Migration: 010 - Add Core Memory Version Column
3
+ * Description: Add version column to core_memory table for cache invalidation
4
+ * Version: 10.0
5
+ * Date: 2025-12-25
6
+ */
7
+ import { readFileSync } from 'fs';
8
+ import { join, dirname } from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import { DependencyValidator } from '../dependency-validator.js';
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = dirname(__filename);
13
+ /**
14
+ * Add Core Memory Version Column Migration
15
+ *
16
+ * This migration:
17
+ * 1. Adds version column to core_memory table (INTEGER NOT NULL DEFAULT 0)
18
+ * 2. Sets version = 1 for all existing rows
19
+ * 3. Creates index on version column for efficient queries
20
+ *
21
+ * Purpose:
22
+ * - Enable version-based cache invalidation
23
+ * - Track changes to core memory records
24
+ * - Support distributed cache synchronization in the future
25
+ */
26
+ export class AddCoreMemoryVersionMigration {
27
+ version = '10.0';
28
+ name = 'add-core-memory-version';
29
+ description = 'Add version column to core_memory table for cache invalidation';
30
+ /**
31
+ * Load SQL file content
32
+ */
33
+ loadSQLFile(filename) {
34
+ const filePath = join(__dirname, filename);
35
+ return readFileSync(filePath, 'utf-8');
36
+ }
37
+ /**
38
+ * Execute SQL script
39
+ * Removes transaction commands (BEGIN TRANSACTION, COMMIT) as MigrationRunner manages transactions
40
+ */
41
+ executeSQL(db, sql) {
42
+ // MigrationRunner가 트랜잭션을 관리하므로 SQL에서 트랜잭션 명령 제거
43
+ let cleanedSQL = sql
44
+ // BEGIN TRANSACTION 제거
45
+ .replace(/BEGIN\s+TRANSACTION\s*;/gi, '')
46
+ // COMMIT 제거
47
+ .replace(/COMMIT\s*;/gi, '')
48
+ // PRAGMA foreign_keys 명령은 유지 (트랜잭션 외부에서도 작동)
49
+ .trim();
50
+ // 빈 줄 제거 및 정리
51
+ cleanedSQL = cleanedSQL
52
+ .split('\n')
53
+ .map(line => line.trim())
54
+ .filter(line => line.length > 0)
55
+ .join('\n');
56
+ if (cleanedSQL.length > 0) {
57
+ db.exec(cleanedSQL);
58
+ }
59
+ }
60
+ /**
61
+ * Check if table exists
62
+ */
63
+ tableExists(db, tableName) {
64
+ const result = db.prepare(`
65
+ SELECT name FROM sqlite_master
66
+ WHERE type='table' AND name=?
67
+ `).get(tableName);
68
+ return !!result;
69
+ }
70
+ /**
71
+ * Check if index exists
72
+ */
73
+ indexExists(db, indexName) {
74
+ const result = db.prepare(`
75
+ SELECT name FROM sqlite_master
76
+ WHERE type='index' AND name=?
77
+ `).get(indexName);
78
+ return !!result;
79
+ }
80
+ /**
81
+ * Check if column exists in table
82
+ */
83
+ columnExists(db, tableName, columnName) {
84
+ const columns = db.prepare(`PRAGMA table_info(${tableName})`).all();
85
+ return columns.some(col => col.name === columnName);
86
+ }
87
+ /**
88
+ * Validate before migration
89
+ */
90
+ async validateBefore(db) {
91
+ // Check if core_memory table exists (required dependency)
92
+ if (!this.tableExists(db, 'core_memory')) {
93
+ throw new Error('core_memory table does not exist. Please run migration 002 first.');
94
+ }
95
+ // Check if version column already exists (should not exist)
96
+ if (this.columnExists(db, 'core_memory', 'version')) {
97
+ throw new Error('version column already exists in core_memory table. Migration may have been already applied.');
98
+ }
99
+ // Note: DependencyValidator는 선택적으로 사용 (테스트 환경에서는 생략 가능)
100
+ // 실제 마이그레이션 실행 시 MigrationRunner가 의존성을 관리함
101
+ }
102
+ /**
103
+ * Execute migration (Up)
104
+ */
105
+ async up(db) {
106
+ // Load and execute SQL script
107
+ const sqlScript = this.loadSQLFile('010-add-core-memory-version.sql');
108
+ this.executeSQL(db, sqlScript);
109
+ // Note: Schema version is recorded by MigrationRunner, not here
110
+ // MigrationRunner.recordVersion() will be called after successful migration
111
+ }
112
+ /**
113
+ * Rollback migration (Down)
114
+ */
115
+ async down(db) {
116
+ // Drop index first
117
+ if (this.indexExists(db, 'idx_core_memory_version')) {
118
+ db.exec('DROP INDEX IF EXISTS idx_core_memory_version');
119
+ }
120
+ // SQLite does not support DROP COLUMN directly, so we need to recreate the table
121
+ // This is a simplified rollback - in production, you might want to preserve data
122
+ // For now, we'll just remove the index and log a warning
123
+ // Full rollback would require recreating the table without the version column
124
+ // Note: SQLite does not support ALTER TABLE DROP COLUMN in older versions
125
+ // For a complete rollback, we would need to:
126
+ // 1. Create a new table without version column
127
+ // 2. Copy data (excluding version)
128
+ // 3. Drop old table
129
+ // 4. Rename new table
130
+ // This is complex and risky, so we'll just remove the index for now
131
+ // Remove schema version record (if table exists)
132
+ try {
133
+ if (this.tableExists(db, 'memento_schema_version')) {
134
+ db.prepare('DELETE FROM memento_schema_version WHERE version = ?').run('10.0');
135
+ }
136
+ }
137
+ catch (error) {
138
+ // 테이블이 없으면 무시 (테스트 환경 등)
139
+ }
140
+ }
141
+ /**
142
+ * Validate after migration
143
+ */
144
+ async validateAfter(db) {
145
+ // Verify version column exists
146
+ if (!this.columnExists(db, 'core_memory', 'version')) {
147
+ throw new Error('version column was not created in core_memory table');
148
+ }
149
+ // Verify index exists
150
+ if (!this.indexExists(db, 'idx_core_memory_version')) {
151
+ throw new Error('idx_core_memory_version index was not created');
152
+ }
153
+ // Verify no rows have version = 0 (all existing rows should have version = 1)
154
+ const zeroVersionCount = db.prepare(`
155
+ SELECT COUNT(*) as count FROM core_memory WHERE version = 0
156
+ `).get();
157
+ if (zeroVersionCount.count > 0) {
158
+ throw new Error(`Migration validation failed: ${zeroVersionCount.count} rows still have version = 0. All existing rows should have version = 1.`);
159
+ }
160
+ // Verify column type is INTEGER
161
+ const columns = db.prepare(`PRAGMA table_info(core_memory)`).all();
162
+ const versionColumn = columns.find(col => col.name === 'version');
163
+ if (!versionColumn) {
164
+ throw new Error('version column not found in core_memory table');
165
+ }
166
+ if (!versionColumn.type.toUpperCase().includes('INTEGER')) {
167
+ throw new Error(`version column type is ${versionColumn.type}, expected INTEGER`);
168
+ }
169
+ if (versionColumn.notnull !== 1) {
170
+ throw new Error('version column should be NOT NULL');
171
+ }
172
+ }
173
+ }
174
+ //# sourceMappingURL=010-add-core-memory-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"010-add-core-memory-version.js","sourceRoot":"","sources":["../../../../../../src/infrastructure/database/database/migration/migrations/010-add-core-memory-version.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,6BAA6B;IACxC,OAAO,GAAG,MAAM,CAAC;IACjB,IAAI,GAAG,yBAAyB,CAAC;IACjC,WAAW,GAAG,gEAAgE,CAAC;IAE/E;;OAEG;IACK,WAAW,CAAC,QAAgB;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC3C,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED;;;OAGG;IACK,UAAU,CAAC,EAAqB,EAAE,GAAW;QACnD,gDAAgD;QAChD,IAAI,UAAU,GAAG,GAAG;YAClB,uBAAuB;aACtB,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC;YACzC,YAAY;aACX,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;YAC5B,6CAA6C;aAC5C,IAAI,EAAE,CAAC;QAEV,cAAc;QACd,UAAU,GAAG,UAAU;aACpB,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aACxB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;aAC/B,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,EAAqB,EAAE,SAAiB;QAC1D,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;;;KAGzB,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAClB,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,EAAqB,EAAE,SAAiB;QAC1D,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;;;KAGzB,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAClB,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,EAAqB,EAAE,SAAiB,EAAE,UAAkB;QAC/E,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,qBAAqB,SAAS,GAAG,CAAC,CAAC,GAAG,EAA6B,CAAC;QAC/F,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,EAAqB;QACxC,0DAA0D;QAC1D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,aAAa,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;QACvF,CAAC;QAED,4DAA4D;QAC5D,IAAI,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,8FAA8F,CAAC,CAAC;QAClH,CAAC;QAED,wDAAwD;QACxD,2CAA2C;IAC7C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,EAAqB;QAC5B,8BAA8B;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,iCAAiC,CAAC,CAAC;QACtE,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QAE/B,gEAAgE;QAChE,4EAA4E;IAC9E,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CAAC,EAAqB;QAC9B,mBAAmB;QACnB,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,yBAAyB,CAAC,EAAE,CAAC;YACpD,EAAE,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;QAC1D,CAAC;QAED,iFAAiF;QACjF,iFAAiF;QACjF,yDAAyD;QACzD,8EAA8E;QAE9E,0EAA0E;QAC1E,6CAA6C;QAC7C,+CAA+C;QAC/C,mCAAmC;QACnC,oBAAoB;QACpB,sBAAsB;QACtB,oEAAoE;QAEpE,iDAAiD;QACjD,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,EAAE,CAAC;gBACnD,EAAE,CAAC,OAAO,CAAC,sDAAsD,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACjF,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,yBAAyB;QAC3B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,EAAqB;QACvC,+BAA+B;QAC/B,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QAED,sBAAsB;QACtB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,yBAAyB,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,8EAA8E;QAC9E,MAAM,gBAAgB,GAAG,EAAE,CAAC,OAAO,CAAC;;KAEnC,CAAC,CAAC,GAAG,EAAuB,CAAC;QAE9B,IAAI,gBAAgB,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,gCAAgC,gBAAgB,CAAC,KAAK,0EAA0E,CAAC,CAAC;QACpJ,CAAC;QAED,gCAAgC;QAChC,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC,GAAG,EAK9D,CAAC;QAEH,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAClE,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1D,MAAM,IAAI,KAAK,CAAC,0BAA0B,aAAa,CAAC,IAAI,oBAAoB,CAAC,CAAC;QACpF,CAAC;QAED,IAAI,aAAa,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ -- Migration: 010 - Add Core Memory Version Column
2
+ -- Description: Add version column to core_memory table for cache invalidation
3
+ -- Version: 10.0
4
+ -- Date: 2025-12-25
5
+
6
+ -- Core Memory 테이블에 version 컬럼 추가
7
+ -- version 컬럼은 캐시 무효화를 위한 단조 증가하는 버전 번호입니다.
8
+ -- INSERT 시: version = 1
9
+ -- UPDATE 시: version = version + 1
10
+
11
+ PRAGMA foreign_keys = OFF;
12
+ BEGIN TRANSACTION;
13
+
14
+ -- 1. version 컬럼 추가 (기본값 0)
15
+ ALTER TABLE core_memory ADD COLUMN version INTEGER NOT NULL DEFAULT 0;
16
+
17
+ -- 2. 기존 행에 version = 1 설정 (마이그레이션 전 데이터는 초기 버전으로 설정)
18
+ UPDATE core_memory SET version = 1 WHERE version = 0;
19
+
20
+ -- 3. version 컬럼에 대한 인덱스 생성 (버전 기반 쿼리 최적화)
21
+ CREATE INDEX IF NOT EXISTS idx_core_memory_version ON core_memory(version);
22
+
23
+ COMMIT;
24
+ PRAGMA foreign_keys = ON;
25
+
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Database Lock Monitor
3
+ * SQLite 데이터베이스 락을 주기적으로 모니터링하고 자동으로 해결
4
+ *
5
+ * 클린코드 원칙:
6
+ * - 단일 책임 원칙: 데이터베이스 락 모니터링만 담당
7
+ * - 명확한 인터페이스: LockStatus와 DatabaseLockMonitorConfig로 명확한 타입 정의
8
+ */
9
+ /**
10
+ * 락 상태 정보
11
+ */
12
+ export interface LockStatus {
13
+ /**
14
+ * 락 상태 여부
15
+ */
16
+ isLocked: boolean;
17
+ /**
18
+ * 락 지속 시간 (밀리초)
19
+ */
20
+ lockDuration: number;
21
+ /**
22
+ * 락 감지 방법
23
+ * - immediate_transaction: IMMEDIATE 트랜잭션 시도로 감지
24
+ * - busy_timeout: busy_timeout 초과로 감지
25
+ */
26
+ detectionMethod: 'immediate_transaction' | 'busy_timeout';
27
+ /**
28
+ * busy_timeout 초과 횟수
29
+ */
30
+ busyCount: number;
31
+ }
32
+ /**
33
+ * 데이터베이스 락 모니터 설정
34
+ */
35
+ export interface DatabaseLockMonitorConfig {
36
+ /**
37
+ * 모니터링 주기 (밀리초)
38
+ * 기본값: 1분 (60000ms)
39
+ */
40
+ intervalMs: number;
41
+ /**
42
+ * 경고 임계값 (밀리초)
43
+ * 기본값: 5초 (5000ms)
44
+ */
45
+ warningThresholdMs: number;
46
+ /**
47
+ * 위험 임계값 (밀리초)
48
+ * 기본값: 30초 (30000ms)
49
+ */
50
+ dangerThresholdMs: number;
51
+ /**
52
+ * 치명적 임계값 (밀리초)
53
+ * 기본값: 60초 (60000ms)
54
+ */
55
+ criticalThresholdMs: number;
56
+ }
57
+ import Database from 'better-sqlite3';
58
+ import type { Logger, PerformanceMonitor } from './wal-checkpoint-scheduler.js';
59
+ import type { WalCheckpointScheduler } from './wal-checkpoint-scheduler.js';
60
+ /**
61
+ * 데이터베이스 락 모니터 클래스
62
+ * SQLite 데이터베이스 락을 주기적으로 모니터링하고 자동으로 해결
63
+ */
64
+ export declare class DatabaseLockMonitor {
65
+ private db;
66
+ private config;
67
+ private logger?;
68
+ private performanceMonitor?;
69
+ private checkpointScheduler?;
70
+ private intervalId;
71
+ private isRunning;
72
+ private lockStartTime;
73
+ private busyCount;
74
+ private busyEventTimes;
75
+ private statsResetTime;
76
+ constructor(db: Database.Database, config: DatabaseLockMonitorConfig, logger?: Logger | undefined, performanceMonitor?: PerformanceMonitor | undefined, checkpointScheduler?: WalCheckpointScheduler | undefined);
77
+ /**
78
+ * 모니터 시작 (idempotent)
79
+ */
80
+ start(): void;
81
+ /**
82
+ * 모니터 중지 (idempotent)
83
+ */
84
+ stop(): void;
85
+ /**
86
+ * 주기적 모니터링
87
+ */
88
+ private monitor;
89
+ /**
90
+ * busy_timeout 통계 업데이트
91
+ * 시간당 발생 횟수 모니터링
92
+ */
93
+ private updateBusyStatistics;
94
+ /**
95
+ * 락 상태 확인
96
+ * IMMEDIATE 트랜잭션 시도와 단순 상태 확인 쿼리를 통해 락을 감지
97
+ */
98
+ private checkLockStatus;
99
+ /**
100
+ * 락 상태 처리
101
+ * 임계값 기반 경고 및 조치 로직
102
+ */
103
+ private handleLockStatus;
104
+ }
105
+ //# sourceMappingURL=database-lock-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-lock-monitor.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/database/database-lock-monitor.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,eAAe,EAAE,uBAAuB,GAAG,cAAc,CAAC;IAE1D;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E;;;GAGG;AACH,qBAAa,mBAAmB;IAS5B,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM,CAAC;IACf,OAAO,CAAC,kBAAkB,CAAC;IAC3B,OAAO,CAAC,mBAAmB,CAAC;IAZ9B,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,cAAc,CAAgC;gBAG5C,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,MAAM,EAAE,yBAAyB,EACjC,MAAM,CAAC,EAAE,MAAM,YAAA,EACf,kBAAkB,CAAC,EAAE,kBAAkB,YAAA,EACvC,mBAAmB,CAAC,EAAE,sBAAsB,YAAA;IAGtD;;OAEG;IACH,KAAK,IAAI,IAAI;IAcb;;OAEG;IACH,IAAI,IAAI,IAAI;IAmBZ;;OAEG;IACH,OAAO,CAAC,OAAO;IAYf;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA0B5B;;;OAGG;YACW,eAAe;IAoG7B;;;OAGG;YACW,gBAAgB;CAsE/B"}
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Database Lock Monitor
3
+ * SQLite 데이터베이스 락을 주기적으로 모니터링하고 자동으로 해결
4
+ *
5
+ * 클린코드 원칙:
6
+ * - 단일 책임 원칙: 데이터베이스 락 모니터링만 담당
7
+ * - 명확한 인터페이스: LockStatus와 DatabaseLockMonitorConfig로 명확한 타입 정의
8
+ */
9
+ import Database from 'better-sqlite3';
10
+ /**
11
+ * 데이터베이스 락 모니터 클래스
12
+ * SQLite 데이터베이스 락을 주기적으로 모니터링하고 자동으로 해결
13
+ */
14
+ export class DatabaseLockMonitor {
15
+ db;
16
+ config;
17
+ logger;
18
+ performanceMonitor;
19
+ checkpointScheduler;
20
+ intervalId = null;
21
+ isRunning = false;
22
+ lockStartTime = null;
23
+ busyCount = 0;
24
+ busyEventTimes = []; // busy_timeout 발생 시간 기록 (시간당 통계용)
25
+ statsResetTime = Date.now() + 3600000; // 1시간 후 통계 리셋
26
+ constructor(db, config, logger, performanceMonitor, checkpointScheduler) {
27
+ this.db = db;
28
+ this.config = config;
29
+ this.logger = logger;
30
+ this.performanceMonitor = performanceMonitor;
31
+ this.checkpointScheduler = checkpointScheduler;
32
+ }
33
+ /**
34
+ * 모니터 시작 (idempotent)
35
+ */
36
+ start() {
37
+ if (this.isRunning) {
38
+ this.logger?.warn('데이터베이스 락 모니터가 이미 실행 중입니다');
39
+ return;
40
+ }
41
+ this.isRunning = true;
42
+ this.monitor();
43
+ this.logger?.info('데이터베이스 락 모니터 시작됨', {
44
+ intervalMs: this.config.intervalMs
45
+ });
46
+ }
47
+ /**
48
+ * 모니터 중지 (idempotent)
49
+ */
50
+ stop() {
51
+ if (!this.isRunning) {
52
+ return;
53
+ }
54
+ if (this.intervalId) {
55
+ clearInterval(this.intervalId);
56
+ this.intervalId = null;
57
+ }
58
+ this.isRunning = false;
59
+ this.lockStartTime = null;
60
+ this.busyCount = 0;
61
+ this.busyEventTimes = [];
62
+ this.statsResetTime = Date.now() + 3600000;
63
+ this.logger?.info('데이터베이스 락 모니터 중지됨');
64
+ }
65
+ /**
66
+ * 주기적 모니터링
67
+ */
68
+ monitor() {
69
+ this.intervalId = setInterval(async () => {
70
+ try {
71
+ const status = await this.checkLockStatus();
72
+ this.handleLockStatus(status);
73
+ this.updateBusyStatistics();
74
+ }
75
+ catch (error) {
76
+ this.logger?.error('락 모니터링 실패', { error });
77
+ }
78
+ }, this.config.intervalMs);
79
+ }
80
+ /**
81
+ * busy_timeout 통계 업데이트
82
+ * 시간당 발생 횟수 모니터링
83
+ */
84
+ updateBusyStatistics() {
85
+ const now = Date.now();
86
+ // 1시간이 지났으면 통계 리셋 및 메트릭 기록
87
+ if (now >= this.statsResetTime) {
88
+ const hourlyBusyCount = this.busyEventTimes.length;
89
+ // 시간당 발생 횟수 메트릭 기록
90
+ if (this.performanceMonitor && hourlyBusyCount > 0) {
91
+ this.performanceMonitor.recordMetric('database_lock_hourly_count', hourlyBusyCount);
92
+ // 시간당 발생 횟수가 높으면 경고
93
+ if (hourlyBusyCount > 100) {
94
+ this.logger?.warn('시간당 busy_timeout 발생 횟수가 높음', {
95
+ hourlyBusyCount,
96
+ threshold: 100
97
+ });
98
+ }
99
+ }
100
+ // 통계 리셋
101
+ this.busyEventTimes = [];
102
+ this.statsResetTime = now + 3600000; // 다음 리셋 시간 설정
103
+ }
104
+ }
105
+ /**
106
+ * 락 상태 확인
107
+ * IMMEDIATE 트랜잭션 시도와 단순 상태 확인 쿼리를 통해 락을 감지
108
+ */
109
+ async checkLockStatus() {
110
+ // 방법 1: IMMEDIATE 트랜잭션 시도 (관측만 수행, 실제 체크포인트 유발 없음)
111
+ try {
112
+ this.db.prepare('BEGIN IMMEDIATE TRANSACTION').run();
113
+ // 트랜잭션 성공 = 락 없음
114
+ this.db.prepare('ROLLBACK').run();
115
+ // 락이 해제됨
116
+ if (this.lockStartTime) {
117
+ const duration = Date.now() - this.lockStartTime;
118
+ this.lockStartTime = null;
119
+ this.logger?.info('데이터베이스 락 해제됨', { duration });
120
+ }
121
+ return {
122
+ isLocked: false,
123
+ lockDuration: 0,
124
+ detectionMethod: 'immediate_transaction',
125
+ busyCount: this.busyCount
126
+ };
127
+ }
128
+ catch (error) {
129
+ if (error.code === 'SQLITE_BUSY') {
130
+ // 락 감지 (IMMEDIATE 트랜잭션 방법)
131
+ this.busyCount++;
132
+ // busy_timeout 발생 시간 기록 (시간당 통계용)
133
+ this.busyEventTimes.push(Date.now());
134
+ // 락 시작 시간 기록
135
+ if (!this.lockStartTime) {
136
+ this.lockStartTime = Date.now();
137
+ }
138
+ // 락 지속 시간 계산
139
+ const lockDuration = this.lockStartTime ? Date.now() - this.lockStartTime : 0;
140
+ return {
141
+ isLocked: true,
142
+ lockDuration,
143
+ detectionMethod: 'immediate_transaction',
144
+ busyCount: this.busyCount
145
+ };
146
+ }
147
+ // 다른 에러가 발생한 경우, 보조 방법으로 단순 상태 확인 쿼리 시도
148
+ // 방법 2: 단순 상태 확인 쿼리 (읽기 전용, 락 유발 없음)
149
+ try {
150
+ this.db.prepare('SELECT COUNT(*) FROM sqlite_master').get();
151
+ // 쿼리 성공 = 락 없음 (IMMEDIATE 트랜잭션의 다른 에러는 무시)
152
+ if (this.lockStartTime) {
153
+ const duration = Date.now() - this.lockStartTime;
154
+ this.lockStartTime = null;
155
+ this.logger?.info('데이터베이스 락 해제됨', { duration });
156
+ }
157
+ return {
158
+ isLocked: false,
159
+ lockDuration: 0,
160
+ detectionMethod: 'immediate_transaction',
161
+ busyCount: this.busyCount
162
+ };
163
+ }
164
+ catch (queryError) {
165
+ if (queryError.code === 'SQLITE_BUSY') {
166
+ // 락 감지 (단순 상태 확인 쿼리 방법)
167
+ this.busyCount++;
168
+ // busy_timeout 발생 시간 기록 (시간당 통계용)
169
+ this.busyEventTimes.push(Date.now());
170
+ // 락 시작 시간 기록
171
+ if (!this.lockStartTime) {
172
+ this.lockStartTime = Date.now();
173
+ }
174
+ // 락 지속 시간 계산
175
+ const lockDuration = this.lockStartTime ? Date.now() - this.lockStartTime : 0;
176
+ return {
177
+ isLocked: true,
178
+ lockDuration,
179
+ detectionMethod: 'busy_timeout',
180
+ busyCount: this.busyCount
181
+ };
182
+ }
183
+ // 두 방법 모두 실패한 경우, 에러 로그만 출력
184
+ this.logger?.error('락 감지 중 예상치 못한 에러 발생', {
185
+ immediateTransactionError: error,
186
+ queryError
187
+ });
188
+ return {
189
+ isLocked: false,
190
+ lockDuration: 0,
191
+ detectionMethod: 'immediate_transaction',
192
+ busyCount: this.busyCount
193
+ };
194
+ }
195
+ }
196
+ }
197
+ /**
198
+ * 락 상태 처리
199
+ * 임계값 기반 경고 및 조치 로직
200
+ */
201
+ async handleLockStatus(status) {
202
+ if (!status.isLocked) {
203
+ return; // 락이 없으면 처리하지 않음
204
+ }
205
+ const { lockDuration } = status;
206
+ // PerformanceMonitor 메트릭 수집
207
+ if (this.performanceMonitor) {
208
+ this.performanceMonitor.incrementCounter('database_lock_count');
209
+ this.performanceMonitor.recordMetric('database_lock_duration', lockDuration);
210
+ }
211
+ // 치명적 임계값 (60초 이상)
212
+ if (lockDuration >= this.config.criticalThresholdMs) {
213
+ this.logger?.warn('데이터베이스 락 치명적 상태 감지', {
214
+ lockDuration,
215
+ detectionMethod: status.detectionMethod,
216
+ busyCount: status.busyCount
217
+ });
218
+ // 체크포인트 시도
219
+ if (this.checkpointScheduler) {
220
+ try {
221
+ await this.checkpointScheduler.checkpointNow();
222
+ }
223
+ catch (error) {
224
+ this.logger?.error('체크포인트 실행 실패', { error });
225
+ }
226
+ }
227
+ // 에러 로깅
228
+ this.logger?.error('데이터베이스 락 치명적 상태', {
229
+ lockDuration,
230
+ detectionMethod: status.detectionMethod,
231
+ busyCount: status.busyCount
232
+ });
233
+ return;
234
+ }
235
+ // 위험 임계값 (30초 이상)
236
+ if (lockDuration >= this.config.dangerThresholdMs) {
237
+ this.logger?.warn('데이터베이스 락 위험 상태 감지', {
238
+ lockDuration,
239
+ detectionMethod: status.detectionMethod,
240
+ busyCount: status.busyCount
241
+ });
242
+ // 체크포인트 시도
243
+ if (this.checkpointScheduler) {
244
+ try {
245
+ await this.checkpointScheduler.checkpointNow();
246
+ }
247
+ catch (error) {
248
+ this.logger?.error('체크포인트 실행 실패', { error });
249
+ }
250
+ }
251
+ return;
252
+ }
253
+ // 경고 임계값 (5초 이상)
254
+ if (lockDuration >= this.config.warningThresholdMs) {
255
+ this.logger?.warn('데이터베이스 락 경고 상태 감지', {
256
+ lockDuration,
257
+ detectionMethod: status.detectionMethod,
258
+ busyCount: status.busyCount
259
+ });
260
+ return;
261
+ }
262
+ // 임계값 미만이면 로그 출력하지 않음
263
+ }
264
+ }
265
+ //# sourceMappingURL=database-lock-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-lock-monitor.js","sourceRoot":"","sources":["../../../src/infrastructure/database/database-lock-monitor.ts"],"names":[],"mappings":"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"}