5cb3e6a0b8
Breaking: YAML config `ip_view_expiration` is renamed `view_expiration` Breaking: Views are taken into account after 10 seconds instead of 30 seconds (can be changed in YAML config) Purpose of this commit is to get closer to other video platforms where some platforms count views on play (mux, vimeo) or others use a very low delay (instagram, tiktok) We also want to improve the viewer identification, where we no longer use the IP but the `sessionId` generated by the web browser. Multiple viewers behind a NAT can now be able to be identified as independent viewers (this method is also used by vimeo or mux)
116 lines
2.7 KiB
TypeScript
116 lines
2.7 KiB
TypeScript
import { wait } from '@peertube/peertube-core-utils'
|
|
import {
|
|
createSingleServer,
|
|
doubleFollow,
|
|
killallServers,
|
|
PeerTubeServer,
|
|
setAccessTokensToServers,
|
|
waitJobs
|
|
} from '@peertube/peertube-server-commands'
|
|
import { isMainThread } from 'worker_threads'
|
|
import Piscina from 'piscina'
|
|
import { fileURLToPath } from 'url'
|
|
import { dirname, join } from 'path'
|
|
|
|
const THOUSAND_VIEWERS = 2
|
|
const TOTAL_THREADS = 20
|
|
|
|
let servers: PeerTubeServer[]
|
|
const viewers: { xForwardedFor: string }[] = []
|
|
let videoId: string
|
|
let pool: Piscina
|
|
|
|
if (isMainThread) {
|
|
run()
|
|
.then(() => process.exit(0))
|
|
.catch(err => console.error(err))
|
|
.finally(() => killallServers(servers))
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
async function run () {
|
|
await prepare()
|
|
|
|
while (true) {
|
|
await runViewers()
|
|
}
|
|
}
|
|
|
|
async function prepare () {
|
|
pool = new Piscina({
|
|
filename: join(dirname(fileURLToPath(import.meta.url)), 'simulate-many-viewers-worker.js'),
|
|
minThreads: 20,
|
|
maxThreads: 20
|
|
})
|
|
|
|
console.log('Preparing servers...')
|
|
|
|
const config = {
|
|
log: {
|
|
level: 'info',
|
|
log_http_requests: false
|
|
},
|
|
rates_limit: {
|
|
api: {
|
|
max: 5_000_000
|
|
}
|
|
},
|
|
views: {
|
|
videos: {
|
|
local_buffer_update_interval: '30 minutes',
|
|
view_expiration: '1 hour'
|
|
}
|
|
}
|
|
}
|
|
|
|
const env = { PRODUCTION_CONSTANTS: 'true' }
|
|
|
|
servers = await Promise.all([
|
|
createSingleServer(1, config, { env, nodeArgs: [ '--inspect' ] }),
|
|
createSingleServer(2, config, { env }),
|
|
createSingleServer(3, config, { env })
|
|
])
|
|
|
|
await setAccessTokensToServers(servers)
|
|
await doubleFollow(servers[0], servers[1])
|
|
await doubleFollow(servers[0], servers[2])
|
|
|
|
const { uuid } = await servers[0].videos.quickUpload({ name: 'video' })
|
|
videoId = uuid
|
|
|
|
await waitJobs(servers)
|
|
|
|
for (let i = 2; i < 252; i++) {
|
|
for (let j = 2; j < 6; j++) {
|
|
for (let k = 2; k < THOUSAND_VIEWERS + 2; k++) {
|
|
viewers.push({ xForwardedFor: `0.${k}.${j}.${i},127.0.0.1` })
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log('Servers preparation finished.')
|
|
}
|
|
|
|
async function runViewers () {
|
|
console.log('Will run views of %d viewers.', viewers.length)
|
|
|
|
const before = new Date().getTime()
|
|
|
|
const promises: Promise<any>[] = []
|
|
|
|
for (let i = 0; i < TOTAL_THREADS; i++) {
|
|
const start = i * THOUSAND_VIEWERS * 1000 / TOTAL_THREADS
|
|
const end = (i + 1) * THOUSAND_VIEWERS * 1000 / TOTAL_THREADS
|
|
|
|
console.log(`Sending viewers ${start} to ${end}`)
|
|
|
|
promises.push(pool.run({ url: servers[0].url, viewers: viewers.slice(start, end), videoId }))
|
|
}
|
|
|
|
await Promise.all(promises)
|
|
|
|
console.log('Finished to run views in %d seconds.', (new Date().getTime() - before) / 1000)
|
|
|
|
await wait(5000)
|
|
}
|