fish2018/pansou · warning

内存缓存更新失败

Error message

内存缓存更新失败: %v

What it means

In the search cache write path, after serializing the value, the service updates the in-memory cache via mainCache.SetMemoryOnly and wraps any failure with this message. The disk write never proceeds, so a memory-cache infrastructure problem aborts the cache refresh.

Solutions

  1. Inspect the wrapped error from SetMemoryOnly to see the store's specific failure reason.
  2. Check cache configuration: max entries/bytes, ttl bounds, and whether the cache instance is properly initialized before use.
  3. Log and continue instead of failing the whole operation — a memory-cache miss only costs performance, not correctness.
  4. Verify shutdown ordering so globalCacheWriteManager/mainCache outlive in-flight refreshes.

Example fix

// before
if err := mainCache.SetMemoryOnly(key, data, ttl); err != nil {
    return fmt.Errorf("内存缓存更新失败: %v", err)
}
// after
if err := mainCache.SetMemoryOnly(key, data, ttl); err != nil {
    log.Printf("[缓存更新] 内存缓存写入失败(忽略): %v", err) // degrade gracefully
}
Defensive patterns

Strategy: try-catch

Validate before calling

if mainCache == nil {
    return fmt.Errorf("cache not initialized")
}

Try / catch

if err := mainCache.SetMemoryOnly(key, data, ttl); err != nil {
    log.Printf("memory cache set failed (non-fatal): %v", err)
    // proceed to disk write anyway
}

Prevention

When it happens

Trigger: mainCache.SetMemoryOnly returns an error while storing the serialized search result under key with the given ttl — e.g. the in-memory cache is closed, at capacity and refusing writes, or encountered an internal store error.

Common situations: Cache evicted/closed during shutdown while a refresh is in flight; memory pressure causing the cache to reject new entries; misconfigured max-size making all writes fail; ttl/value constraints violated by the cache implementation.


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/eee657736097241e. Report an issue: GitHub.

Appendix: source

Thrown at service/search_service.go:299

				displayKey := key[:8] + "..."
				if keyword != "" {
					fmt.Printf("[异步插件 %s] 初始缓存创建: %s(关键词:%s) | 结果数: %d\n", pluginName, displayKey, keyword, len(newResults))
				} else {
					fmt.Printf("[异步插件 %s] 初始缓存创建: %s | 结果数: %d\n", pluginName, key, len(newResults))
				}
			}
		}

		// 序列化合并后的结果
		data, err := mainCache.GetSerializer().Serialize(finalResults)
		if err != nil {
			fmt.Printf("[缓存更新] 序列化失败: %s | 错误: %v\n", key, err)
			return err
		}

		// 先更新内存缓存(立即可见)
		if err := mainCache.SetMemoryOnly(key, data, ttl); err != nil {
			return fmt.Errorf("内存缓存更新失败: %v", err)
		}

		// 使用新的缓存写入管理器处理磁盘写入(智能批处理)
		if cacheWriteManager := globalCacheWriteManager; cacheWriteManager != nil {
			operation := &cache.CacheOperation{
				Key:        key,
				Data:       finalResults, // 使用原始数据而不是序列化后的
				TTL:        ttl,
				IsFinal:    isFinal,
				PluginName: pluginName,
				Keyword:    keyword,
				Priority:   2, // 中等优先级
				Timestamp:  time.Now(),
				DataSize:   len(data), // 序列化后的数据大小
			}

			// 根据是否为最终结果设置优先级
			if isFinal {

View on GitHub (pinned to beaa561337)