feat: metadata book (#638)

* feat: metadata book

* chore: address review

* chore: address review
This commit is contained in:
Vasco Santos
2020-05-15 19:39:13 +02:00
committed by Jacob Heun
parent 0fbb59748e
commit 84b935f682
11 changed files with 861 additions and 39 deletions

View File

@ -14,6 +14,7 @@ const {
NAMESPACE_ADDRESS,
NAMESPACE_COMMON,
NAMESPACE_KEYS,
NAMESPACE_METADATA,
NAMESPACE_PROTOCOL
} = require('./consts')
@ -43,6 +44,12 @@ class PersistentPeerStore extends PeerStore {
*/
this._dirtyPeers = new Set()
/**
* Peers metadata changed mapping peer identifers to metadata changed.
* @type {Map<string, Set<string>>}
*/
this._dirtyMetadata = new Map()
this.threshold = threshold
this._addDirtyPeer = this._addDirtyPeer.bind(this)
}
@ -58,6 +65,7 @@ class PersistentPeerStore extends PeerStore {
this.on('change:protocols', this._addDirtyPeer)
this.on('change:multiaddrs', this._addDirtyPeer)
this.on('change:pubkey', this._addDirtyPeer)
this.on('change:metadata', this._addDirtyPeerMetadata)
// Load data
for await (const entry of this._datastore.query({ prefix: NAMESPACE_COMMON })) {
@ -92,6 +100,30 @@ class PersistentPeerStore extends PeerStore {
}
}
/**
* Add modified metadata peer to the set.
* @private
* @param {Object} params
* @param {PeerId} params.peerId
* @param {string} params.metadata
*/
_addDirtyPeerMetadata ({ peerId, metadata }) {
const peerIdstr = peerId.toB58String()
log('add dirty metadata peer', peerIdstr)
this._dirtyPeers.add(peerIdstr)
// Add dirty metadata key
const mData = this._dirtyMetadata.get(peerIdstr) || new Set()
mData.add(metadata)
this._dirtyMetadata.set(peerIdstr, mData)
if (this._dirtyPeers.size >= this.threshold) {
// Commit current data
this._commitData()
}
}
/**
* Add all the peers current data to a datastore batch and commit it.
* @private
@ -120,6 +152,9 @@ class PersistentPeerStore extends PeerStore {
// Key Book
this._batchKeyBook(peerId, batch)
// Metadata Book
this._batchMetadataBook(peerId, batch)
// Proto Book
this._batchProtoBook(peerId, batch)
}
@ -184,6 +219,32 @@ class PersistentPeerStore extends PeerStore {
}
}
/**
* Add metadata book data of the peer to the batch.
* @private
* @param {PeerId} peerId
* @param {Object} batch
*/
_batchMetadataBook (peerId, batch) {
const b32key = peerId.toString()
const dirtyMetada = this._dirtyMetadata.get(peerId.toB58String()) || []
try {
dirtyMetada.forEach((dirtyKey) => {
const key = new Key(`${NAMESPACE_METADATA}${b32key}/${dirtyKey}`)
const dirtyValue = this.metadataBook.getValue(peerId, dirtyKey)
if (dirtyValue) {
batch.put(key, dirtyValue)
} else {
batch.delete(key)
}
})
} catch (err) {
log.error(err)
}
}
/**
* Add proto book data of the peer to the batch.
* @private
@ -244,6 +305,13 @@ class PersistentPeerStore extends PeerStore {
decoded,
{ emit: false })
break
case 'metadata':
this.metadataBook._setValue(
peerId,
keyParts[4],
value,
{ emit: false })
break
case 'protos':
decoded = Protocols.decode(value)