From 7f60877026347cc5b79bf879bb07cf2f35f9d668 Mon Sep 17 00:00:00 2001 From: noffle Date: Thu, 14 Nov 2019 19:29:17 -0800 Subject: [PATCH] fix: encode now-timestamps to avoid overwrites What was happening was that when a timestamp, which are monotonic-timestamps, included an e.g. ".001" suffix, it would be considered as "in the future" if the indexer was quick enough to pick it up, and then be converted to "new Date().getTime()". So if two messages were written to a channel fast enough, BOTH would get set to "new Date().getTime()" and the second would overwrite the first in leveldb. This change ensures that proper monotonic-timestamps are used throughout. --- views/messages.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/views/messages.js b/views/messages.js index 6e1b0ba..3ab9cba 100644 --- a/views/messages.js +++ b/views/messages.js @@ -1,4 +1,5 @@ var View = require('kappa-view-level') +var timestamp = require('monotonic-timestamp') var through = require('through2') var readonly = require('read-only-stream') var charwise = require('charwise') @@ -15,12 +16,11 @@ module.exports = function (lvl) { if (!msg.value.timestamp) return [] // If the message is from <>, index it at _now_. - var timestamp = msg.value.timestamp - var now = new Date().getTime() - if (timestamp > now) timestamp = now + var ts = msg.value.timestamp + if (isFutureMonotonicTimestamp(ts)) ts = timestamp() if (msg.value.type.startsWith('chat/') && msg.value.content.channel) { - var key = 'msg!' + msg.value.content.channel + '!' + charwise.encode(timestamp) + var key = 'msg!' + msg.value.content.channel + '!' + charwise.encode(ts) return [ [key, msg] ] @@ -89,3 +89,17 @@ function sanitize (msg) { if (typeof msg.value.content.text !== 'string') return null return msg } + +function monotonicTimestampToTimestamp (timestamp) { + if (/^[0-9]+\.[0-9]+$/.test(String(timestamp))) { + return Number(String(timestamp).split('.')[0]) + } else { + return timestamp + } +} + +function isFutureMonotonicTimestamp () { + var timestamp = monotonicTimestampToTimestamp(timestamp) + var now = new Date().getTime() + return timestamp > now +}