← Voltar para Home
#Frontend#Performance#Web Workers#Upload#Arquitetura

Arquitetura de Upload de Vídeos: Web Workers e Multipart Upload

0
0

Introdução

O upload de arquivos grandes, especialmente vídeos, é um desafio em aplicações web. Se processado e enviado diretamente pela "Main Thread" (a thread principal do navegador), arquivos grandes podem travar a interface do usuário, causando uma má experiência (a famosa "tela congelada").

Para resolver isso, nossa arquitetura utiliza Web Workers para processar o upload em background, mantendo a interface do usuário totalmente responsiva.

[!NOTE] Embora muitas vezes confundido com Service Workers (que interceptam requisições de rede e funcionam como proxy), neste caso utilizamos Web Workers. A diferença crucial é que o Web Worker é focado em executar scripts em background para processamento pesado, enquanto o Service Worker é mais focado em cache e capacidades offline.

A Solução: upload.worker.js

Nossa solução reside no arquivo assets/js/upload.worker.js. Ele implementa uma estratégia robusta de Multipart Upload.

Como Funciona

Em vez de enviar o arquivo inteiro de uma só vez, o worker divide o arquivo em pequenos pedaços ("chunks" ou "parts") e os envia em paralelo. Isso traz várias vantagens:

  1. Concorrência Controlada: Podemos enviar várias partes ao mesmo tempo.
  2. Resiliência: Se uma parte falhar, precisamos reenviar apenas ela, não o arquivo todo.
  3. Não Bloqueante: Todo o processamento de "fatiar" o arquivo (slicing) acontece no worker, fora da thread principal.

O Fluxo do Processo

O processo é orquestrado em três etapas principais:

  1. Start: O worker solicita ao backend a iniciação do upload multipart e recebe um uploadId.
  2. Upload Part: O worker divide o arquivo e envia as partes. Aqui usamos um "limiter" para não sobrecarregar a rede, mantendo um número máximo de uploads simultâneos (atualmente configurado para 5).
  3. Complete: Após todas as partes serem enviadas com sucesso, o worker avisa o backend para remontar o arquivo final.

Diagrama da Arquitetura

Abaixo, um diagrama de sequência ilustrando a comunicação entre a UI (Main Thread), o Web Worker e a API Backend.

Detalhe Técnico: O uploadPromiseLimiter

Um ponto alto da implementação é a função uploadPromiseLimiter. Ela gerencia a fila de uploads das partes.

// Exemplo simplificado da lógica no worker
async function uploadPromiseLimiter(promises, limit) {
  const executing = []
  
  for (const promise of promises) {
    // Inicia a promise e remove da lista de execução quando terminar
    const p = promise().then(() => executing.splice(executing.indexOf(p), 1))
    executing.push(p)

    // Se atingiu o limite, espera alguma terminar antes de iniciar a próxima
    if (executing.length >= limit) {
      await Promise.race(executing)
    }
  }
}

Isso garante que, mesmo para um vídeo de 1GB dividido em centenas de partes, nunca teremos mais que 5 requisições ativas simultaneamente, evitando sobrecarga do navegador e do servidor.

Conclusão

O uso de Web Workers para essa tarefa transformou a experiência de upload. Conseguimos processar gigabytes de dados sem que o usuário perceba qualquer lentidão na interface, fornecendo feedback de progresso em tempo real e garantindo confiabilidade na transferência dos dados.

Comentarios (0)

Carregando comentarios...