mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-05-31 00:34:35 +00:00
distribute upload chunks across multiple servers
This commit is contained in:
@@ -105,10 +105,11 @@ export interface UploadOptions {
|
||||
|
||||
export async function uploadFile(
|
||||
agent: XFTPClientAgent,
|
||||
server: XFTPServer,
|
||||
servers: XFTPServer[],
|
||||
encrypted: EncryptedFileMetadata,
|
||||
options?: UploadOptions
|
||||
): Promise<UploadResult> {
|
||||
if (servers.length === 0) throw new Error("uploadFile: servers list is empty")
|
||||
const {onProgress, redirectThreshold, readChunk: readChunkOpt} = options ?? {}
|
||||
const readChunk: (offset: number, size: number) => Promise<Uint8Array> = readChunkOpt
|
||||
? readChunkOpt
|
||||
@@ -122,6 +123,7 @@ export async function uploadFile(
|
||||
for (let i = 0; i < specs.length; i++) {
|
||||
const spec = specs[i]
|
||||
const chunkNo = i + 1
|
||||
const server = servers[Math.floor(Math.random() * servers.length)]
|
||||
const sndKp = generateEd25519KeyPair()
|
||||
const rcvKp = generateEd25519KeyPair()
|
||||
const chunkData = await readChunk(spec.chunkOffset, spec.chunkSize)
|
||||
@@ -151,7 +153,7 @@ export async function uploadFile(
|
||||
let finalRcvDescription = rcvDescription
|
||||
const threshold = redirectThreshold ?? DEFAULT_REDIRECT_THRESHOLD
|
||||
if (uri.length > threshold && sentChunks.length > 1) {
|
||||
finalRcvDescription = await uploadRedirectDescription(agent, server, rcvDescription)
|
||||
finalRcvDescription = await uploadRedirectDescription(agent, servers, rcvDescription)
|
||||
uri = encodeDescriptionURI(finalRcvDescription)
|
||||
}
|
||||
return {rcvDescription: finalRcvDescription, sndDescription, uri}
|
||||
@@ -186,7 +188,7 @@ function buildDescription(
|
||||
|
||||
async function uploadRedirectDescription(
|
||||
agent: XFTPClientAgent,
|
||||
server: XFTPServer,
|
||||
servers: XFTPServer[],
|
||||
innerFd: FileDescription
|
||||
): Promise<FileDescription> {
|
||||
const yaml = encodeFileDescription(innerFd)
|
||||
@@ -197,6 +199,7 @@ async function uploadRedirectDescription(
|
||||
for (let i = 0; i < specs.length; i++) {
|
||||
const spec = specs[i]
|
||||
const chunkNo = i + 1
|
||||
const server = servers[Math.floor(Math.random() * servers.length)]
|
||||
const sndKp = generateEd25519KeyPair()
|
||||
const rcvKp = generateEd25519KeyPair()
|
||||
const chunkData = enc.encData.subarray(spec.chunkOffset, spec.chunkOffset + spec.chunkSize)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {createCryptoBackend} from './crypto-backend.js'
|
||||
import {getServers, pickRandomServer} from './servers.js'
|
||||
import {getServers} from './servers.js'
|
||||
import {createProgressRing} from './progress.js'
|
||||
import {
|
||||
newXFTPAgent, closeXFTPAgent, uploadFile, encodeDescriptionURI,
|
||||
@@ -131,8 +131,7 @@ export function initUpload(app: HTMLElement) {
|
||||
chunkSizes: encrypted.chunkSizes
|
||||
}
|
||||
const servers = getServers()
|
||||
const server = pickRandomServer(servers)
|
||||
const result = await uploadFile(agent, server, metadata, {
|
||||
const result = await uploadFile(agent, servers, metadata, {
|
||||
readChunk: (off, sz) => backend.readChunk(off, sz),
|
||||
onProgress: (uploaded, total) => {
|
||||
ring.update(0.3 + (uploaded / total) * 0.7)
|
||||
|
||||
Reference in New Issue
Block a user