pldubouilh / live-torrent

Simple proof-of-concept for a live streaming solution based on webtorrent
MIT License
168 stars 39 forks source link

How to make sure you remove the oldest magnet in wtManifest.js #12

Closed Er-rchydy closed 6 years ago

Er-rchydy commented 6 years ago

I found an issue in wtManifest.js, how to make sure we always remove the oldest magnet ? because of every chunk takes different time to get it's magnet, the magnetsOrder array is not always in a good order.

wtManifest.prototype.makeMagnet = async function (f) {
  const self = this
  const cn = chunkName(f)
  console.log('working on:  '+cn)
  if (self.fileToMagnet[cn]) return
  const url = isUrl(f) ? f : self.chunksLoc + removeDanglingSlash(f)
  const payload = self.isLocalStream ? await fs.readFile(self.localPath + f) : await request(url, { encoding: null })
  const magnet = await self.computeMagnet(payload, cn)
  console.log('got magnet of :  '+cn)  
  self.fileToMagnet[cn] = '###' + magnet + '\n' + url
  self.magnetsOrder.push(cn)
  if (self.magnetsOrder.length > 10) {
    const oldMagnet = self.magnetsOrder.shift()
    delete self.fileToMagnet[oldMagnet]
  }
}
wtManifest.prototype.makeAllMagnets = async function (files) {
  return Promise.all(files.map(this.makeMagnet, this))
}

if we have a manifest that has 5 chunks, we got :

working on: 1.ts
working on: 2.ts
working on: 3.ts
working on: 4.ts
working on: 5.ts

got magnet of : 4.ts
got magnet of : 2.ts
got magnet of : 1.ts
got magnet of : 5.ts
got magnet of : 3.ts

so instead of

magnetsOrder=[1.ts,2.ts,3.ts,4.ts,5.ts]

we got

magnetsOrder=[4.ts,2.ts,1.ts,5.ts,3.ts]

and that causes removing newest chunks that we need instead of removing the oldest one. how can we prevent this issue. thanks

pldubouilh commented 6 years ago

So basically it's because the Promise.all is taking care of setting the items in the right place. The array push does it in the order at which it arrives, which is why it's non-sequential. Although Promise.all has its output array matching the input promises :)

Have a look at that example

const arr = []
const p0 = new Promise((resolve, reject) => setTimeout(() => { 
    arr.push('foo1')
    resolve('foo1')
}, 1000))

const p1 = new Promise((resolve, reject) => setTimeout(() => { 
    arr.push('foo2')
    resolve('foo2')
}, 100))

Promise.all([p0, p1]).then(values => { 
  console.log('yay in the right order!', values) 
  console.log('oh noes', arr) 
})