Skip to main content
Voltar para Projetos

Microsserviço de Captura de Transcrição em Tempo Real

Contribuidor principal em microsserviço Ruby de produção: captura ao vivo de transcrições Zoom via RTMS dual-WebSocket, sinalização IVar thread-safe, persistência assíncrona no S3.

RubyWebSocketsZoom RTMSSidekiqAWS S3Concurrent Ruby

Overview

Este é um microsserviço de produção, de-identificado. Ingressei em uma arquitetura existente e contribuí intensamente na implementação: gerenciamento de conexões WebSocket, monitoramento de keep-alive, uploads periódicos para S3, e a suite RSpec cobrindo todos os estados de conexão e os adaptadores de arquivo. O serviço conecta à API RTMS (Real-Time Media Streaming) do Zoom para capturar transcrições ao vivo de chamadas de vídeo entre provedores e pacientes. O protocolo RTMS do Zoom exige duas conexões WebSocket simultâneas: um canal de sinalização (autenticação, heartbeats de keep-alive, mensagens de controle de stream) e um canal separado de dados de transcrição cuja URL só é conhecida após o handshake de sinalização. O runner coordena essas conexões usando `Concurrent::IVar` — callbacks de eventos WebSocket disparam em threads em background, e o thread principal do job Sidekiq bloqueia no valor do IVar com timeout configurável. Uma `Concurrent::TimerTask` gerencia uploads periódicos da transcrição em andamento para o S3 para que nenhum dado seja perdido em caso de interrupção. Na reinicialização, o runner baixa qualquer conteúdo S3 existente antes de reconectar, retomando de onde a tentativa anterior parou. Eventos de estado do job (processando, concluído, falhou) são reportados de volta à aplicação web principal via HTTP após cada resultado terminal. O desafio de engenharia é robustez em um processo stateful com tempo limitado: uma consulta médica de até três horas que não pode ser reiniciada, onde perda de dados da transcrição tem consequências clínicas. A arquitetura separa os modos de falha claramente — exceções com retry são levantadas para que o Sidekiq as tente novamente; estados terminais não retentáveis (ex: URL de servidor inválida) sinalizam falha sem lançar exceção, encerrando o job graciosamente. O monitoramento de keep-alive detecta desconexões silenciosas que a biblioteca WebSocket não exporia. *Os exemplos de código nesta página são ilustrações representativas dos padrões arquiteturais utilizados — não são código-fonte proprietário real do sistema em produção.*

Technical Stack

Runtime e Jobs

  • ▸Ruby
  • ▸Rack
  • ▸Sidekiq
  • ▸Einhorn
  • ▸concurrent-ruby

Rede

  • ▸Zoom RTMS API
  • ▸websocket-client-simple
  • ▸WebSocket de Sinalização
  • ▸WebSocket de Transcrição

Armazenamento e Operações

  • ▸AWS S3
  • ▸RSpec
  • ▸CircleCI
  • ▸Docker

Key Features

✓

Gerenciamento de duas conexões WebSocket: canal de sinalização (auth + keep-alive) e canal de dados abertos em sequência

✓

Sinalização IVar entre threads — callbacks WebSocket em threads background comunicam a URL de transcrição e resultados terminais ao thread principal do job

✓

Concurrent::TimerTask para uploads periódicos da transcrição em andamento para o S3 durante sessões ao vivo

✓

Retomada na reinicialização: baixa qualquer transcrição existente do S3 antes de reconectar para que jobs interrompidos continuem de onde pararam

✓

Monitoramento de keep-alive com timeout configurável — detecta desconexões silenciosas do Zoom que a biblioteca WebSocket não exporia

✓

Derivação determinística de chave S3 a partir de job ID + meeting UUID, garantindo boa distribuição no bucket e retries sem colisão

✓

Taxonomia limpa de falhas: lança exceções para erros com retry (Sidekiq tenta novamente), retorna objetos Failure para estados terminais (sem lançamento, sem retry)

✓

Reporte de eventos de estado do job à aplicação web principal após cada transição (processando, concluído, falhou)

Code Examples

Technical Challenges

▪

Coordenar duas conexões WebSocket sequenciais onde a URL da segunda é desconhecida até o handshake da primeira ser concluído

▪

Gerenciar estado entre threads com segurança entre o thread de eventos WebSocket e o thread do job Sidekiq usando IVar

▪

Detectar desconexões silenciosas WebSocket durante a sessão sem depender do evento de fechamento da biblioteca subjacente

▪

Projetar uma estratégia de retry que preserve dados de transcrição entre reinicializações do job sem duplicar conteúdo

▪

Distinguir modos de falha com retry dos terminais em um processo stateful e de longa duração onde lançar incorretamente causa perda de dados

Project Outcomes

Em produção — ambiente real de saúde
Deploy
Contribuidor principal na implementação, testes e hardening em produção
Função