客户端使用 Node.js 生成的文档序列



我们希望构建一个Node.js API,它将无模式文档存储在MongoDB集合中。每个文档都应该有一个键"no",按顺序排列它们:

[
{ "no": 1, ... }, 
{ "no": 2, ... }, 
{ "no": 3, ... }, 
{ "no": 4, ... }, 
...
]

我们有以下约束:

  • 排序(包括其他参数)需要进行加密签名。因此,服务器无法设置客户端在签名和发送数据之前不知道的序列号。
  • no必须是唯一的(不允许:1 -> 1 -> 2 -> 3)
  • 排序中不得有任何间隙(不允许:1 -> 2 -> 4 -> 5)
  • API是复制的,因此会有很多针对MongoDB的并发请求。
  • API 客户端不是浏览器应用程序,它实际上也是一个 Node.js 应用程序。将只有一个 API 客户端

我们的起点是拥有一个 API,该 API 在每个存储请求上返回下一个序列号。

POST /collection { "no": 1, ...}
returns {"next": 2}

这行得通吗?

在客户端,它可能是这样的伪代码:

let next
module.exports.create = (document, cb) => {
if (!next) next = 1 // here it is probably better to sync the initial no with the db instead always starting with 1
document.no = next
return post('/collection', document, (err, res) => {
if (err) ...
next = res.next
return cb(...)
}
}

如果客户端的create由许多并发调用方调用,是否存在两个或多个创建请求具有重复no的情况?

当您有并发 API 调用并且客户端有权确定序列时,如果客户端具有确定序列的全部权限,则几乎不可能实现您尝试的目标。

但是,如果序列no 之间不能有任何间隙并且必须是顺序的,为什么客户端必须是提供序列 no的人?您可以轻松地就排序模式(例如 1,2,3,4 或 AB1、AB2、AB3 等)达成一致,并让服务器端根据哪个请求先进入来插入序列 no。创建一个使用findAndModify生成运行编号的集合,并让服务器将序列 no 更新到数据库中。

最新更新