Javascript 我应该使用什么作为文档键来保持幂等性? 我应该使用什么作为文档键来保持幂等性?
我正在构建一个文本消息传递应用程序,它使用CouchDB(客户端带有PockDB)在本地存储消息。Twilio(SMS provider)为每条消息生成一个ID,我使用它作为CouchDB文档ID。这种方式从Twilio的API获取消息是幂等的——如果我两次遇到同一条消息,它将只在我的数据库中存储一个副本Javascript 我应该使用什么作为文档键来保持幂等性? 我应该使用什么作为文档键来保持幂等性?,javascript,couchdb,twilio,Javascript,Couchdb,Twilio,我正在构建一个文本消息传递应用程序,它使用CouchDB(客户端带有PockDB)在本地存储消息。Twilio(SMS provider)为每条消息生成一个ID,我使用它作为CouchDB文档ID。这种方式从Twilio的API获取消息是幂等的——如果我两次遇到同一条消息,它将只在我的数据库中存储一个副本 // twilio API /messages [ {smsid: 123, body: 'foo'}, {smsid: 456, body: 'bar'} ] // transfo
// twilio API /messages
[
{smsid: 123, body: 'foo'},
{smsid: 456, body: 'bar'}
]
// transformed into couchdb docs
[
{id: 123, doc: {_id: 123, body: 'foo'}},
{id: 456, doc: {_id: 456, body: 'bar'}}
]
这在从twilio获取消息时很容易做到。但是当用户从客户端应用程序发送出站消息时,还没有twilio ID,因为它还没有被发送到twilio
传统的方法是将消息发布到我服务器上的某个端点,让服务器将其发送到twilio,然后在twilio的响应中包含smsid
后将记录添加到数据库中。问题在于(a)当用户按下“发送”键,消息显示在UI中时,会有明显的延迟,(b)我们无法利用couchdb的auth系统
相反,我将其设置为客户端生成一个随机ID,并将其插入数据库(通过PockDB w/sync)。然后,服务器监视添加的新出站记录,并将它们发送到twilio
这种方法工作得很好,但是如果我再次GET/messages
,它就不再是幂等的了——它将为出站消息创建一个额外的记录,因为我没有一个couchdb文档,该文档的键是该消息的smsid
(当它被添加到couchdb时,它没有smsid
)
有没有办法解决这个问题或者更好的方法?一个解决办法是,您必须从每条消息中删除,并且忽略Twilio的
smsid
也许将用户id、消息正文和时间戳的一个完整版本(例如,
int(UNIX-timestamp-IN-SECONDS/100)
散列在一起将允许在服务器收到消息和Twilio确认消息之间有100秒的延迟)。感谢您的回复。这是一个艰难的时刻@来自freenode的#couchdb的rnewson非常友好,花了一些时间思考这个问题,并提出了一个解决方案,效果非常好:
- couchdb中的消息文档使用可由服务器或客户端生成的任意
\u id
- 当客户端发送消息时,它会生成一个任意的
,并将其放入数据库。服务器观察到这一点并将其发送给twilio,然后通过向文档添加\u id
属性来更新数据库文档twilio\u id
- 我创建了一个视图,通过
twilio\u id
- 当服务器启动时,它从twilio获取最新消息。为了防止向数据库中添加重复记录,它会在上面的视图中查询每个twilio id。对于每个匹配,它使用匹配的
和\u id
执行更新。对于不匹配的记录,它会生成一个新的任意\u rev
来执行插入\u id
再次感谢您的回复 除了
smsid
和body
,您还从Twilio的/messages
中获得了哪些其他数据?我想不出一个简单的解决方案,除非您实现分布式事务。嘿,fiatjaf,感谢您在这里提供的帮助。我可以送你一件斜纹t恤来表达我们的感激之情吗。发送电子邮件至mspeir@twilio.com详情,谢谢!我很乐意,梅根,但是在我的国家,如果不向州政府支付至少20美元的费用,任何t恤衫都不允许进入,在交货时收取费用。考虑到这一点,我不得不说不。