chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type { McpTool } from '@/lib/mcp/types'
|
||||
import { MCP_CONSTANTS } from '@/lib/mcp/utils'
|
||||
import type { McpCacheEntry, McpCacheStorageAdapter } from './adapter'
|
||||
|
||||
const logger = createLogger('McpMemoryCache')
|
||||
|
||||
export class MemoryMcpCache implements McpCacheStorageAdapter {
|
||||
private cache = new Map<string, McpCacheEntry>()
|
||||
private readonly maxCacheSize = MCP_CONSTANTS.MAX_CACHE_SIZE
|
||||
private cleanupInterval: NodeJS.Timeout | null = null
|
||||
|
||||
constructor() {
|
||||
this.startPeriodicCleanup()
|
||||
}
|
||||
|
||||
private startPeriodicCleanup(): void {
|
||||
this.cleanupInterval = setInterval(
|
||||
() => {
|
||||
this.cleanupExpiredEntries()
|
||||
},
|
||||
5 * 60 * 1000 // 5 minutes
|
||||
)
|
||||
// Don't keep Node process alive just for cache cleanup
|
||||
this.cleanupInterval.unref()
|
||||
}
|
||||
|
||||
private cleanupExpiredEntries(): void {
|
||||
const now = Date.now()
|
||||
const expiredKeys: string[] = []
|
||||
|
||||
this.cache.forEach((entry, key) => {
|
||||
if (entry.expiry <= now) {
|
||||
expiredKeys.push(key)
|
||||
}
|
||||
})
|
||||
|
||||
expiredKeys.forEach((key) => this.cache.delete(key))
|
||||
|
||||
if (expiredKeys.length > 0) {
|
||||
logger.debug(`Cleaned up ${expiredKeys.length} expired cache entries`)
|
||||
}
|
||||
}
|
||||
|
||||
private evictIfNeeded(): void {
|
||||
if (this.cache.size <= this.maxCacheSize) {
|
||||
return
|
||||
}
|
||||
|
||||
// Evict oldest entries (by insertion order - Map maintains order)
|
||||
const entriesToRemove = this.cache.size - this.maxCacheSize
|
||||
const keys = Array.from(this.cache.keys()).slice(0, entriesToRemove)
|
||||
keys.forEach((key) => this.cache.delete(key))
|
||||
|
||||
logger.debug(`Evicted ${entriesToRemove} cache entries`)
|
||||
}
|
||||
|
||||
async get(key: string): Promise<McpCacheEntry | null> {
|
||||
const entry = this.cache.get(key)
|
||||
const now = Date.now()
|
||||
|
||||
if (!entry || entry.expiry <= now) {
|
||||
if (entry) {
|
||||
this.cache.delete(key)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// Return copy to prevent caller from mutating cache
|
||||
return {
|
||||
tools: entry.tools,
|
||||
expiry: entry.expiry,
|
||||
}
|
||||
}
|
||||
|
||||
async set(key: string, tools: McpTool[], ttlMs: number): Promise<void> {
|
||||
const now = Date.now()
|
||||
const entry: McpCacheEntry = {
|
||||
tools,
|
||||
expiry: now + ttlMs,
|
||||
}
|
||||
|
||||
this.cache.set(key, entry)
|
||||
this.evictIfNeeded()
|
||||
}
|
||||
|
||||
async delete(key: string): Promise<void> {
|
||||
this.cache.delete(key)
|
||||
}
|
||||
|
||||
async clear(): Promise<void> {
|
||||
this.cache.clear()
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
if (this.cleanupInterval) {
|
||||
clearInterval(this.cleanupInterval)
|
||||
this.cleanupInterval = null
|
||||
}
|
||||
this.cache.clear()
|
||||
logger.info('Memory cache disposed')
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user