DEBUG.WIKI
丽萨主机;为跨境业务选好 IP;原生 / 住宅 IP · 按套餐选择;查看 IP →
PanstarCloud:部署应用,接入 AI,云服务器与 AI 网关
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证

Luxon splitBy 传入负时长后进程卡住

Luxon 3.7.2 的 splitBy 只拦住零时长,没有阻止负步长。限定输入单位与分片上限,避免同步循环占满事件循环和内存。

日程接口调用 interval.splitBy({ hours: -1 }) 后不再返回,Node 进程 CPU 升高,其他请求也开始等待。若实际使用 Luxon 3.7.2,应检查切分步长是否为负,以及它是否直接来自请求输入。

该版 splitBy 会检查 Interval、Duration 的有效性,以及换算为毫秒后是否恰好等于零。负 Duration 可以是有效对象,因此仍会进入循环;游标向区间起点之前推进,无法达到正常终点,并持续增加结果。

有效 Duration 不代表能向前切分

不能仅用 duration.isValid 作为此操作的条件。负时长在“向前减一小时”等计算中有明确用途,但不适合作为这条切分循环的正向步长。

divideEqually 会先用区间长度除以 numberOfParts,再交给 splitBy。负数、零、无穷值或非整数份数都不符合通常的等分业务契约,应在调用前拒绝,不能指望除法或最后的 slice 自动验证它们。不同异常参数的具体返回表现也不必相同。

固定毫秒切分可以收紧入口

以下辅助函数只接收整数毫秒,不处理“一个月”或混合日历单位。示例分片上限 10000 是保护措施,需按业务的内存和响应大小要求设置:

function splitFixedMilliseconds(interval, stepMs) {
  if (!interval.isValid) throw new RangeError('Invalid interval');
  if (!Number.isSafeInteger(stepMs) || stepMs < 1) {
    throw new RangeError('stepMs must be a positive integer');
  }
  const count = Math.ceil(interval.length('milliseconds') / stepMs);
  if (!Number.isFinite(count) || count > 10000) {
    throw new RangeError('Too many interval parts');
  }
  return interval.splitBy({ milliseconds: stepMs });
}

只校验正数还不够:极小步长对很长区间同样可能生成过多对象。字符串参数也不能未经契约确认就隐式转数字;在解析层明确单位、格式和范围,再传进此函数。

日历月、日以及跨夏令时的切分不能一概替换成固定毫秒。需要这些单位时,应按支持的正向日历规则设计入口,并对每次计算的下一位置检查是否有效且严格前进,同时限制分片数量。不要用 Duration 的近似毫秒换算替代业务上的日历语义。

超时 Promise 不能打断已经卡住的同步循环

在同一线程外包一个 Promise.race 或 setTimeout,不会抢占 Luxon 正在执行的同步 while。输入校验必须发生在调用之前。对于必须处理不可信大计算的服务,还应按既有架构考虑隔离与资源限制,不能把一个请求超时当成进程保护。

正式 3.7.2 的对应实现仍只有零值检查,没有已核证的正式修复版本。本次入口限制不会改变合法时长在其他场景中的含义。验收时覆盖正向切分、空区间、负输入、零、超大份数以及数量上限;会触发原同步死循环的输入应由入口直接拒绝,不在运行中的服务上反复执行它。