Skip to content

Commit ab6734c

Browse files
committed
Add peer.remoteContiguousLength
1 parent ef96761 commit ab6734c

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

lib/replicator.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ class Peer {
308308

309309
this.remoteFork = 0
310310
this.remoteLength = 0
311+
this.remoteContiguousLength = 0
311312
this.remoteCanUpgrade = false
312313
this.remoteUploading = true
313314
this.remoteDownloading = true
@@ -679,6 +680,11 @@ class Peer {
679680
}
680681

681682
onrange ({ drop, start, length }) {
683+
// console.log(this.stream.publicKey.slice(0, 3).toString('hex'), this.stream.remotePublicKey.slice(0, 3).toString('hex'), this.$id, 'onrange', { drop, start, length })
684+
685+
if (start === 0) this.remoteContiguousLength = length
686+
if (drop) this.remoteContiguousLength = Math.min(this.remoteContiguousLength, start)
687+
682688
const has = drop === false
683689

684690
this.remoteBitfield.setRange(start, length, has)

test/remote-length.js

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
const test = require('brittle')
2+
const { create, replicate } = require('./helpers')
3+
4+
test('peer with partial remote contig length', async function (t) {
5+
const core = await create()
6+
const a = await create(core.key)
7+
const b = await create(core.key)
8+
9+
await core.append(['a', 'b', 'c', 'd', 'e', 'f'])
10+
11+
replicate(core, a, t)
12+
replicate(a, b, t)
13+
14+
// "A" has all the blocks
15+
await a.download({ start: 0, end: core.length }).done()
16+
t.is(a.contiguousLength, core.length)
17+
18+
// "B" gets them blocks from "A"
19+
await b.get(0)
20+
await b.get(1)
21+
await b.get(2)
22+
// await b.get(3)
23+
// await b.get(4)
24+
// await b.get(5)
25+
26+
await new Promise(resolve => setTimeout(resolve, 100))
27+
28+
// For example, "A" wants to know if "B" is finished syncing
29+
const peer = a.replicator.peers.find(peer => peer.remotePublicKey.equals(b.replicator.peers[0].stream.publicKey)) // (unsure if this peers[0] is precise)
30+
console.log('B remote contig length', peer.remoteContiguousLength) // => 1
31+
console.log('B local contig length ', b.contiguousLength) // => 3
32+
t.is(b.contiguousLength, peer.remoteContiguousLength)
33+
34+
// One of them always shows "1" which is "B"
35+
console.log(a.replicator.peers.map(peer => peer.remoteContiguousLength))
36+
console.log(b.replicator.peers.map(peer => peer.remoteContiguousLength))
37+
})
38+
39+
test('peer with complete remote contig length', async function (t) {
40+
const core = await create()
41+
const a = await create(core.key)
42+
const b = await create(core.key)
43+
44+
await core.append(['a', 'b', 'c', 'd', 'e', 'f'])
45+
46+
replicate(core, a, t)
47+
replicate(a, b, t)
48+
49+
await a.download({ start: 0, end: core.length }).done()
50+
t.is(a.contiguousLength, core.length)
51+
52+
await b.get(0)
53+
await b.get(1)
54+
await b.get(2)
55+
await b.get(3)
56+
await b.get(4)
57+
await b.get(5)
58+
59+
await new Promise(resolve => setTimeout(resolve, 100))
60+
61+
const peer = a.replicator.peers.find(peer => peer.remotePublicKey.equals(b.replicator.peers[0].stream.publicKey))
62+
t.is(b.contiguousLength, peer.remoteContiguousLength)
63+
})
64+
65+
/* test.skip('basic replication', async function (t) {
66+
const core = await create()
67+
const a = await create(core.key)
68+
const b = await create(core.key)
69+
const c = await create(core.key)
70+
71+
await core.append(['a', 'b', 'c', 'd', 'e', 'f'])
72+
73+
// core.core.$id = 'w'
74+
a.core.$id = 'a'
75+
// b.core.$id = 'b'
76+
// c.core.$id = 'c'
77+
78+
const ra = replicate(core, a, t)
79+
const ab = replicate(a, b, t)
80+
const bc = replicate(b, c, t)
81+
82+
console.log(ra[0].publicKey.slice(0, 3).toString('hex'), '=> core')
83+
console.log(ra[1].publicKey.slice(0, 3).toString('hex'), '=> a')
84+
console.log()
85+
86+
console.log(ab[0].publicKey.slice(0, 3).toString('hex'), '=> a')
87+
console.log(ab[1].publicKey.slice(0, 3).toString('hex'), '=> b')
88+
console.log()
89+
90+
console.log(bc[0].publicKey.slice(0, 3).toString('hex'), '=> b')
91+
console.log(bc[1].publicKey.slice(0, 3).toString('hex'), '=> c')
92+
console.log()
93+
94+
await a.update({ wait: true })
95+
await b.update({ wait: true })
96+
await c.update({ wait: true })
97+
98+
const peer = a.replicator.peers.find(peer => peer.remotePublicKey.equals(b.replicator.peers[0].stream.publicKey))
99+
peer.$id = 'b'
100+
101+
// "A" has all the blocks
102+
await a.download({ start: 0, end: core.length }).done()
103+
104+
// "B" is getting them from "A"
105+
await b.get(1)
106+
await b.get(2)
107+
await b.get(0)
108+
109+
await new Promise(resolve => setTimeout(resolve, 100))
110+
111+
console.log('writer length', core.contiguousLength, core.length) // 5 / 5 ()
112+
console.log('a core length', a.contiguousLength, a.length) // 5 / 5 ()
113+
console.log('b core length', b.contiguousLength, b.length) // 3 / 5 ()
114+
console.log('c core length', c.contiguousLength, c.length) // 0 / 5 ()
115+
116+
// console.log(core.replicator.peers[0])
117+
118+
// From "a" perspective, this is "b" peer which it should have a remote contig length of 3
119+
// console.log(a.replicator.peers[0])
120+
121+
await new Promise(resolve => setTimeout(resolve, 100))
122+
})
123+
124+
test.skip('basic replication', async function (t) {
125+
const core = await create()
126+
const a = await create(core.key)
127+
const b = await create(core.key)
128+
const c = await create(core.key)
129+
130+
core.core.$id = 'w'
131+
a.core.$id = 'a'
132+
b.core.$id = 'b'
133+
c.core.$id = 'c'
134+
135+
const ra = replicate(core, a, t)
136+
const ab = replicate(a, b, t)
137+
const bc = replicate(b, c, t)
138+
139+
await a.update({ wait: true })
140+
await b.update({ wait: true })
141+
142+
// const peer = a.replicator.peers.find(peer => peer.remotePublicKey.equals(b.replicator.peers[0].stream.publicKey)) // Or just peers[1]
143+
// peer.$id = 'b'
144+
145+
const peer = b.replicator.peers.find(peer => peer.remotePublicKey.equals(c.replicator.peers[0].stream.publicKey)) // Or just peers[1]
146+
peer.$id = 'c'
147+
148+
await core.append('a')
149+
await a.get(0)
150+
await b.get(0)
151+
152+
await core.append('b')
153+
await a.get(1)
154+
await b.get(1)
155+
156+
await core.append('c')
157+
await a.get(2)
158+
await b.get(2)
159+
160+
await core.append('d')
161+
await a.get(3)
162+
await b.get(3)
163+
await c.get(3)
164+
165+
await core.append('e')
166+
await a.get(4)
167+
168+
await core.append('f')
169+
await a.get(5)
170+
171+
// await c.get(1)
172+
await c.get(0)
173+
174+
await new Promise(resolve => setTimeout(resolve, 100))
175+
176+
console.log('writer length', core.contiguousLength, core.length) // 5 / 5 ()
177+
console.log('a core length', a.contiguousLength, a.length) // 5 / 5 ()
178+
console.log('b core length', b.contiguousLength, b.length) // 3 / 5 ()
179+
console.log('c core length', c.contiguousLength, c.length) // 0 / 5 ()
180+
181+
// console.log(core.replicator.peers[0])
182+
183+
// From "a" perspective, this is "b" peer which it should have a remote contig length of 3
184+
// console.log(a.replicator.peers[0])
185+
186+
await new Promise(resolve => setTimeout(resolve, 100))
187+
}) */

0 commit comments

Comments
 (0)