-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Specification
There's currently an issue of "read-after-write" consistency with sequences of batch operations in the NodeGraph buckets database, as setNode operations rely on the state of the bucket on insertion.
Recall that a bucket has a fixed capacity of
knodes. If we attempt to add a new node to a full bucket, we find the least active node in the bucket and remove it, in favour of the new node.However, we come across an issue if we want to create a batch operation of multiple
setNodeOpswithin the same bucket.Because the
opsare created before any additions, thebucketvalue is statically defined, based on the initial state of the bucket.For example, if I were to batch add 3 nodes (
A,B,C) into the same bucket (that already has some nodeZ, we'd have the following array of ops:[ { type: 'put', domain: this.nodeGraphBucketsDbDomain, key: bucketIndex, value: {'Z':9.9.9.9, 'A':1.1.1.1}, }, { type: 'put', domain: this.nodeGraphBucketsDbDomain, key: bucketIndex, value: {'Z':9.9.9.9, 'B':2.2.2.2}, }, { type: 'put', domain: this.nodeGraphBucketsDbDomain, key: bucketIndex, value: {'Z':9.9.9.9, 'C':3.3.3.3}, }, ]That is, the final
setNodeop would overwrite the entire bucket with only nodesZandCin the bucket.
This problem can be solved by utilising the same system in js-encryptedfs. We'd need to use:
- separate sublevels for each individual bucket index
Transactionsnapshot system
In this process, it would also be worthwhile to change our keys to be buffers.
Additional context
- original thread from MR that brought up this issue https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/209#note_680113619
- mid-sprint meeting has some good discussions of this https://vimeo.com/609500458:
- overall summary at ~1:00:30
Transactionoverview at 11:00
- original nodes claims issue Creating a cryptolink claim from node to node (cross-signing claims) #213
Tasks
- Investigate the snapshot system in the EFS
Transactionclass - Change buckets to use individual sublevels for each bucket index (instead of a single sublevel indexed by bucket indexes - see how RFS)
- Add "higher" metadata level for storing the size of a particular bucket. See INodeManager sublevel vs INodeManager dir sublevel. The INodeManager sublevel is capable of storing metadata.
- Incorporate transaction system into
NodeGraphoperations - Remove
lexicographic-integerdependency from PK (see original comments regarding this here https://gitlab.com/MatrixAI/Engineering/Polykey/js-polykey/-/merge_requests/205#note_707121227)