mcpField
B
b2c-custom-caches

b2c-custom-caches

github.com/salesforcecommercecloud开发5791 次安装今天更新
代码仓库

关于 b2c-custom-caches

b2c-custom-caches 面向在 Salesforce B2C Commerce 中实现应用级缓存的开发者,介绍 JSON 缓存定义和 Script API 用法,包括加载器填充、键作用域、过期设置及平台限制。

主要功能

  1. 01在 JSON 文件中定义缓存
  2. 02通过 Script API 访问缓存
  3. 03使用加载器填充条目
  4. 04按站点或目录设置键作用域
  5. 05配置过期与失效

适用场景

  1. 01缓存外部 API 响应
  2. 02避免重复执行高成本计算
  3. 03复用频繁访问的商品数据
  4. 04缓存站点级配置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling --skill b2c-custom-caches

安装后在 Claude Code 中输入/b2c-custom-caches确认已加载。

附带文件evals/trigger-evals.json

详细介绍

B2C 自定义缓存

自定义缓存通过存储计算开销大、检索耗时长或访问频繁的数据来提升代码性能。缓存定义在代码库中的 JSON 文件内,并通过 Script API 访问。

何时使用自定义缓存

使用场景示例
开销大的计算检查是否有任何变体商品在基础商品展示中处于促销状态
外部系统响应缓存来自外部 API 的门店库存或价格
配置设置存储来自 JSON 文件或外部来源的配置数据
频繁访问的数据商品属性、类别数据、站点偏好设置

限制

限制项值
每台应用程序服务器的总内存所有自定义缓存共约 20 MB
每个代码版本的最大缓存数100
最大条目大小128 KB
支持的值类型基本类型、数组、普通对象、null(不包括 undefined)
跨服务器同步无(缓存按应用程序服务器隔离)

定义自定义缓存

文件结构
my_cartridge/
├── package.json       # References caches.json
└── caches.json        # Cache definitions
package.json

添加一个 caches 条目,指向缓存定义文件:

{
  "name": "my_cartridge",
  "caches": "./caches.json"
}
caches.json

定义具有唯一 ID 和可选过期时间的缓存:

{
  "caches": [
    {
      "id": "ProductAttributeCache"
    },
    {
      "id": "ExternalPriceCache",
      "expireAfterSeconds": 300
    },
    {
      "id": "SiteConfigCache",
      "expireAfterSeconds": 60
    }
  ]
}
属性必需说明
id是在代码版本的所有代码库中唯一的 ID
expireAfterSeconds否条目保留的最长秒数

使用自定义缓存

Script API 类
类说明
dw.system.CacheMgr访问已定义缓存的入口点
dw.system.Cache用于存储和检索条目的缓存实例
基本用法
var CacheMgr = require('dw/system/CacheMgr');

// Get a defined cache
var cache = CacheMgr.getCache('ProductAttributeCache');

// Get value (returns undefined if not found)
var value = cache.get('myKey');

// Store value directly
cache.put('myKey', { data: 'value' });

// Remove entry
cache.invalidate('myKey');
推荐模式:使用加载器调用 get

使用 get(key, loader),在缓存未命中时自动填充缓存:

var CacheMgr = require('dw/system/CacheMgr');
var Site = require('dw/system/Site');

var cache = CacheMgr.getCache('SiteConfigCache');

// Loader function called only on cache miss
var config = cache.get(Site.current.ID + '_config', function() {
    // Expensive operation - only runs if not cached
    return loadConfigurationFromFile(Site.current);
});
带作用域的缓存键

在键中包含作用域标识符,以按上下文区分条目:

var CacheMgr = require('dw/system/CacheMgr');
var Site = require('dw/system/Site');

var cache = CacheMgr.getCache('ProductCache');

// Site-scoped key
var siteKey = Site.current.ID + '_' + productID;
var productData = cache.get(siteKey, loadProductData);

// Catalog-scoped key
var catalogKey = 'catalog_' + catalogID + '_' + productID;
var catalogData = cache.get(catalogKey, loadCatalogData);

// Locale-scoped key
var localeKey = request.locale + '_' + contentID;
var content = cache.get(localeKey, loadLocalizedContent);

缓存方法

方法说明
get(key)返回缓存值或 undefined
get(key, loader)返回缓存值,或调用加载器并存储结果
put(key, value)直接存储值(覆盖现有值)
invalidate(key)移除指定键的条目

最佳实践

应该做
  • 使用 get(key, loader) 模式自动填充缓存
  • 在缓存键中包含作用域(站点、目录、区域设置)
  • 为时效性数据设置适当的 expireAfterSeconds
  • 妥善处理缓存未命中(数据可能随时被逐出)
  • 使用描述性缓存 ID
不应该做
  • 不要在缓存键中包含个人用户数据(键可能会出现在日志中)
  • 不要存储 Script API 对象(仅存储基本类型和普通对象)
  • 不要依赖缓存条目始终存在(不保证持久性)
  • 不要期望缓存跨服务器同步
  • 不要存储 undefined 值(请改用 null)

缓存失效

以下情况会自动清除缓存:

  • 活动代码版本中的任何文件发生更改
  • 激活了新的代码版本
  • 数据复制完成
  • 代码复制完成

手动失效仅影响当前应用程序服务器:

var cache = CacheMgr.getCache('MyCache');

// Invalidate single entry (current app server only)
cache.invalidate('myKey');

// Storing undefined has same effect as invalidate
cache.put('myKey', undefined);

常见模式

缓存外部 API 响应
var CacheMgr = require('dw/system/CacheMgr');
var LocalServiceRegistry = require('dw/svc/LocalServiceRegistry');

var priceCache = CacheMgr.getCache('ExternalPriceCache');

function getExternalPrice(productID) {
    return priceCache.get('price_' + productID, function() {
        var service = LocalServiceRegistry.createService('PriceService', {
            createRequest: function(svc, args) {
                svc.setRequestMethod('GET');
                svc.addParam('productId', args.productID);
                return null;
            },
            parseResponse: function(svc, response) {
                return JSON.parse(response.text);
            }
        });

        var result = service.call({ productID: productID });
        return result.ok ? result.object : null;
    });
}
缓存开销大的计算结果
var CacheMgr = require('dw/system/CacheMgr');

var saleCache = CacheMgr.getCache('ProductSaleCache');

function isProductOnSale(masterProduct) {
    return saleCache.get('sale_' + masterProduct.ID, function() {
        var variants = masterProduct.variants.iterator();
        while (variants.hasNext()) {
            var variant = variants.next();
            if (isInPromotion(variant)) {
                return true;
            }
        }
        return false;
    });
}
使用站点作用域的配置缓存
var CacheMgr = require('dw/system/CacheMgr');
var Site = require('dw/system/Site');
var File = require('dw/io/File');
var FileReader = require('dw/io/FileReader');

var configCache = CacheMgr.getCache('SiteConfigCache');

function getSiteConfig() {
    var siteID = Site.current.ID;

    return configCache.get(siteID + '_config', function() {
        var configFile = new File(File.IMPEX + '/src/config/' + siteID + '.json');
        if (!configFile.exists()) {
            return null;
        }

        var reader = new FileReader(configFile);
        var content = reader.getString();
        reader.close();

        return JSON.parse(content);
    });
}

故障排除

问题原因解决方案
找不到缓存异常任意 caches.json 中均未定义缓存 ID将缓存定义添加到 caches.json
缓存 ID 重复错误多个代码库使用了相同 ID在所有代码库中使用唯一 ID
条目未存储值超过 128 KB 限制减小数据量或缓存部分数据
条目未存储值包含 Script API 对象仅使用基本类型和普通对象
缓存未命中异常使用了不同的应用程序服务器,或缓存已清除始终妥善处理缓存未命中

请检查自定义错误日志和自定义警告日志中的缓存相关消息。

评论

支持 Markdown