Puter.js `puter.kv.expireAt()` 深度指南:为键设置绝对过期时间戳
2026/9/9 20:28:58 网站建设 项目流程

Puter.jsputer.kv.expireAt()深度指南:为键设置绝对过期时间戳

【免费下载链接】puter🌐 The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter

puter.kv.expireAt()是 Puter 云键值存储(Key-Value Store)API 中用于按绝对 Unix 时间戳控制键生命周期的核心方法,适用于 Web 网站、App、Node.js 及 Serverless Worker 等多种平台场景。通过本文,你将掌握expireAt的完整语法、参数语义与返回约定,理解它与相对 TTL 的expire()在实现上的关键差异,并学会用它构建"定时失效"的缓存、临时凭证与限时数据等真实场景。

背景:一个托管于用户账户的键值存储

在深入expireAt之前,先厘清它的运行环境。Puter 的 KV Store 允许应用以"键值对"的形式在云端存取数据,其基础设施完全由 Puter 托管,开发者无需自建服务器、无需关心扩容与备份。关键特性在于隔离边界:KV 模块索引说明 明确指出"每个应用在每位用户的账户内拥有自己独立的存储,应用之间无法访问彼此的存储"。

因此,puter.kv.expireAt()操作的对象始终是当前用户自己账户内、当前应用命名空间下的键;单靠 KV API 无法跨用户读取数据。若需要所有用户共享的集中式存储,官方 KV 概览建议改用 Serverless Worker,由 Worker 代码代表其所有者访问资源。此外,借助appUuid配置项配合puter.perms.requestAppData()权限,也可以让一个应用寻址另一个应用的命名空间(见 types.js 中KVOptConfig的定义)。

方法与函数签名

根据原文档,方法签名只有一个:

puter.kv.expireAt(key, timestampSeconds)

将过期语义对照到 SDK 实现,会得到一个重要的设计提示。expireAt.js 的实现注释写道:

Sets the expiration for a key as a UNIX timestamp in seconds; after that time the key is deleted.Clients whose clock is out of sync with the server may see keys expire early or late — preferexpirefor a server-relative TTL.

expireAt用一个绝对时间点定义"何时删除该键";由于该时间点由客户端时钟换算而来,一旦客户端设备与服务器之间存在时钟偏差,键就可能提前或滞后过期。这正是它与expire()(相对 TTL,以服务器时间为基准计算)的本质区别,下文会专门展开。

expire()的关系

KV Store 同时提供两种过期 API,二者的关系可以概括为"同一底层机制的两种取值方式":

方法语义参数适用场景
puter.kv.expire(key, ttlSeconds)相对 TTL:从现在起 N 秒后删除秒数服务端计时,无需关心客户端时钟
puter.kv.expireAt(key, timestampSeconds)绝对时间戳:在指定 Unix 时刻删除Unix 秒级时间戳存在一个"墙上时间"业务约定(如某日 0 点失效)时

二者在 SDK 层几乎是"镜像实现":expire.js 通过makeDriverMethod({ iface: 'puter-kvstore', method: 'expire', argNames: ['key', 'ttl'] })调用后端驱动,而 expireAt.js 以method: 'expireAt'argNames: ['key', 'timestamp']调用同一puter-kvstore接口。JSDoc 中的原始描述则互为建议:expire的注释(expire.js)提醒"当时间戳应由服务端决定时,优先使用expire以避免时钟漂移问题"。

对于expire()官方文档(KV/expire.md)同样定义了expire(key, ttlSeconds)形式,两者均返回一个 resolve 为truePromise,表示过期设定已生效。

参数详解

expireAt接收两个必填位置参数,SDK 层还会在请求发出前做一次键名校验。

key(String,必填)

包含目标键名的字符串。在 expireAt.js 中,参数首先经过assertKeySize(key)校验:若键长度超过1 KB(1024 字节),会抛出带有稳定错误码key_too_large{ message, code }对象(见 lib/validate.js)。键名在调用真正发出前即被拒绝,因此无需等待网络往返即可捕获这类低级错误。同时,set()文档(KV/set.md)明确 key 为空(undefined/null)会由assertKeyPresent抛出key_undefined错误。

timestampSeconds(Number,必填)

键将被从存储中移除的 Unix 时间戳(秒级)。这是本方法与expire()的核心差异点:这里传的不是"从现在起的秒数",而是一个绝对时间点。实践中通常用Date.now()/1000 + offsetSeconds计算得到(原文档示例即采用(Date.now()/1000) + 1)。需要注意,若该值已经位于过去,则键的过期行为由后端对该时间点的判断决定——按文档语义,到达该时刻键即被删除,因此传入过去的时间戳可视为要求"立即失效"。

返回值

返回一个Promise

  • 当过期时间被成功设定时,Promise resolve 为布尔值true
  • 该 Promise 仅在服务端确认设定成功后 resolve,配合await使用可保证后续逻辑发生在设定生效之后。

平台支持

原文档 front matter 标注的platforms[websites, apps, nodejs, workers],即以下四种运行形态均可直接调用:

  • websites:通过<script src="https://js.puter.com/v2/"></script>引入浏览器端 SDK 的网页;
  • apps:Puter 生态内的应用;
  • nodejs:Node.js 环境(SDK 的 Node 入口);
  • workers:Puter 的 Serverless Worker 运行时。

此外puter.kv.expireAt与其它方法一样由 KVModule 在构造时以bind重绑为模块方法,因此无论puter.kv.expireAt(...)整体调用,还是先解构出const { expireAt } = puter.kv再单独调用,语义保持一致。

完整示例:读取一个已到期的键

原文档给出的示例演示了"创建 → 设定绝对过期时刻 → 等待后读取为空"的完整闭环,直接可复制到浏览器控制台或网页运行:

<html> <body> <script src="https://js.puter.com/v2/"></script> <script> (async () => { // (1) Create a new key-value pair await puter.kv.set('name', 'Puter Smith'); puter.print("Key-value pair 'name' created/updated<br>"); // (2) Set key to expire in 1 second await puter.kv.expireAt('name', (Date.now()/1000) + 1); // (3) Wait 2 seconds and get the value setTimeout(async () => { const name = await puter.kv.get('name'); puter.print("Value :", name); }, 2000); })(); </script> </body> </html>

分步解读:

  1. puter.kv.set('name', 'Puter Smith')写入键值对并await其完成;
  2. puter.kv.expireAt('name', (Date.now()/1000) + 1)把过期时刻设定为"当前 Unix 秒 + 1 秒"。Date.now()返回毫秒,因此必须除以 1000 换算为秒后才能与 API 的秒级约定匹配,这是最常见的笔误点;
  3. 等待 2 秒后调用puter.kv.get('name'),此时过期窗口(1 秒)已过,读取结果应为空(null)。

数值约定提示

与过期时间戳不同,写入 KV 的遵循set()文档(KV/set.md)中的精度规则:每个数字(包括嵌套在对象或数组中的)必须在Number.MAX_SAFE_INTEGER(±9,007,199,254,740,991)范围内,超出部分会被钳制而非拒绝,NaN则以null存储。需要精确保存的 ID 或累计值,请以字符串形式存储。

expireAt 与 expire 的选型建议

结合两个方法的 SDK 实现注释(expireAt.js、expire.js)与官方文档,给出可落地的选型准则:

  • 服务端负责计时:当语义是"从现在起 60 秒后失效",优先选择puter.kv.expire('key', 60)。TTL 由服务器解释,不受客户端设备时钟偏差影响,是防止"用户把系统时间调前/调后导致缓存提前/延后失效"的首选。
  • 业务有绝对截止点:当失效时刻必须锚定在业务约定的墙上时间——例如"会话在当天 23:59:59 作废""限时优惠到某日结束""临时访问令牌在固定时刻回收"——用expireAt更自然,也便于直接与后端计算出的截止时间戳对接。
  • 注意时钟一致性问题expireAttimestampSeconds来自客户端本地时钟换算,一旦客户端时钟与服务端偏差明显,键的实际删除可能早于或晚于预期。若你的业务对时间误差敏感,请优先评估expire方案;若必须使用绝对时间戳,可考虑在服务端/Worker 侧计算时间戳后传入,让计时基准尽量靠近服务端。

两个方法都先经assertKeySize做键长校验,再经puter-kvstore接口发往后端 KV 驱动(见 expireAt.js),整体行为一致,差异仅在时间取值语义。

扩展应用:把过期时间戳带进set()

值得留意的是,绝对过期时间并非只能事后调用expireAt。SDK 的puter.kv.set()本身就支持内联的expireAt字段,且该参数在后端与独立调用的expireAt语义一致(见 KVSetItem 的类型注释:Timestamp, in seconds, at which the key should expire)。例如:

// 写入时即声明:该键于 1 小时后失效 await puter.kv.set('sessionToken', 'abc123', (Date.now() / 1000) + 3600); // 对象形式亦可(详见 set 文档的多种重载) await puter.kv.set({ key: 'otp', value: 483920, expireAt: (Date.now() / 1000) + 300 });

批量形式puter.kv.set([{ key, value, expireAt }, ...])同样允许逐条携带过期时间。这样可以在单次写入请求内完成"数据 + 生命周期"的原子设定,减少一次额外的过期调用,也让"一次性数据"的意图在代码中自解释。

典型实战场景

综合官方 KV 概览(KV.md)与本文方法语义,expireAt在真实业务中适合支撑以下能力:

  • 带截止时刻的缓存:缓存某个到"整点"就必须失效的数据(如汇率快照、当日排行榜),用expireAt(key, nextHourTimestamp)精确对齐刷新边界;
  • 限时内容与临时凭据:一次性链接、OTP、临时 token 等在业务上"到点必须作废"的条目;
  • 临时状态位:如"该用户 24 小时内不再提示"之类的标记,配合incr/decr构成带有生命周期的计数逻辑;
  • disableSharing组合的隐私条目:用set(key, value, { disableSharing: true, expireAt })写一条既私有又按时销毁的数据(如缓存中的访问令牌),即便用户之后授权其它应用访问本命名空间,该条目也对其不可见(见 KV/set.md 的disableSharing说明)。

总结

puter.kv.expireAt(key, timestampSeconds)用最直接的方式为键挂上"墙上时钟"型的生命周期:传入 Unix 秒级时间戳,到点即删,成功即返回true。它与相对 TTL 的puter.kv.expire()形成互补,前者适合锚定业务截止时刻,后者适合规避客户端时钟漂移。若要深入理解其底层,可以沿着这条路径继续阅读当前仓库:

  • SDK 实现 expireAt.js:参数校验与驱动方法封装;
  • SDK 实现 expire.js:相对 TTL 的镜像实现;
  • KV 模块聚合 index.js:模块结构、方法绑定与MAX_KEY_SIZE/MAX_VALUE_SIZE常量;
  • 客户端校验 lib/validate.js:key_too_largevalue_too_large等稳定错误码;
  • 类型与选项 types.js:expireAt在各批量接口中的内联形态;
  • 官方文档 KV/expire.md 与 KV/set.md:相邻 API 的完整语法与限制(key ≤ 1 KB、value ≤ 400 KB)。

至此,你可以直接在自己的页面、Node 脚本或 Worker 中按上文示例落地"定时过期"的数据管理,并依据时钟敏感度在expireexpireAt之间做出正确取舍。

【免费下载链接】puter🌐 The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询