Introdução
O balcão comunitário de downloads distribui notas de campo de North Pier e um informe para voluntários do jardim. Antes de fechar, um voluntário quer permitir que um download já aceito termine. A primeira implementação fecha suas conexões imediatamente. Você primeiro obterá um documento completo e útil e depois observará exatamente o que uma parada imediata interrompe.
É preciso conhecer funções, handlers e valores de erro de Go, além das responsabilidades de goroutines e canais dos dois projetos anteriores, ou ter experiência equivalente. Identidade de processos e SIGTERM são apresentados aqui. Os dois terminais nomeados são sessões na mesma máquina. As ferramentas preparadas registram apenas o servidor compilado do curso e seus processos filhos curl; você não precisa aprender o formato dos rastreamentos nativos. Reserve cerca de 45 minutos, incluindo leitura e erros comuns; essa é uma estimativa do autor. Cada unidade começa de forma independente.
Baixe um documento completo
Nesta etapa, obtenha um documento completo e útil e confira seus bytes reais.
Comece em Downloads. As duas entradas de terminal apenas acessam o espaço de trabalho existente; abrir uma aba nunca recria o cenário. Se ocorrer um erro comum de diretório, este comando visível leva você de volta ao local correto:
cd /home/labex/project/download-desk
Leia os dois arquivos de texto originais. Eles contêm materiais práticos diferentes, não nomes alternativos para a mesma amostra. cat mostra o conteúdo sem alterar os arquivos.
cat documents/north-pier.txt documents/garden-route.txt
Mantenha esses originais e todos os arquivos preparados inalterados durante a unidade. Você pode compilar desk, iniciar tentativas observadas com nome e criar downloads. Esta unidade não muda código Go. Cada unidade seguinte fornece sua própria cópia nova.
Mude para Server. O executável Go está preparado no caminho absoluto. build compila este pacote; . significa o pacote atual e -o desk dá nome ao executável gerado. Um binário compilado torna explícita a identidade do processo, ao contrário de enviar sinais a um wrapper go run.
cd /home/labex/project/download-desk
/usr/local/go/bin/go build -o desk .
Inicie uma tentativa com nome. O observador fornecido inicia seu binário e registra o processo real, as requisições HTTP, os sinais e o resultado nativo de saída; ele não implementa o encerramento gracioso. first é um nome de tentativa. Nomes existentes são recusados para não sobrescrever silenciosamente evidências anteriores.
python3 desk.py serve first
Aguarde Ready. Use Downloads for client requests.. Este terminal permanece ocupado até o processo original sair. O PID exibido é o filho Go compilado, não o observador. Deixe Server funcionando e mude para Downloads.
O cliente preparado executa curl real, registra seu resultado nativo e salva sua saída efetiva. Os quatro argumentos selecionam a tentativa, um novo rótulo de saída, um documento preparado e um atraso em milissegundos por 32 bytes. O atraso 0 é a amostra rápida normal. O rótulo normal produz downloads/normal.txt.
python3 desk.py download first normal north-pier.txt 0
Espere Original curl native exit: 0. Zero significa que a transferência terminou, mas sozinho não comprova o conteúdo. cmp compara os arquivos reais byte a byte e não imprime nada quando são iguais. Leia também o documento útil salvo:
cmp documents/north-pier.txt downloads/normal.txt
cat downloads/normal.txt
Se o cliente informar conexão recusada, volte a Server e leia a saída existente. Não inicie repetidamente outro processo na mesma porta. Se Go informar erro de compilação, corrija o diretório ou compare o arquivo preparado antes de compilar novamente. Um novo shell não herda as variáveis de outro, mas os arquivos e a tentativa observada são compartilhados entre essas duas sessões.
Pare o servidor original durante um download aceito
Nesta etapa, interrompa uma transferência realmente aceita e diferencie a falha do cliente da saída do servidor.
Comece em Downloads enquanto Server ainda executa first. Um identificador de processo, ou PID, identifica um processo em execução, mas o sistema operacional pode reutilizá-lo depois da saída. O observador também verifica o caminho do executável, o ID do usuário atual e os ticks de início Linux de /proc para distinguir o processo original. Envie sinais apenas ao processo compilado deste curso. Não use pkill, não escolha o observador como alvo nem altere processos da plataforma ou a configuração do shell.
SIGTERM é um pedido comum de término de processo. kill -TERM PID envia esse pedido a um PID exato. O comando não espera downloads nem comprova por si só que o processo terminou. O programa Go preparado recebe o sinal, chama Close imediatamente e retorna de main. É esse comportamento que você observará, não uma falha de rede.
Leia o restante da etapa, incluindo as falhas esperadas e a recuperação, antes de iniciar a transferência lenta. Depois execute os blocos em ordem; não pare para aprender o próximo conceito enquanto essa requisição de duração finita estiver em andamento. Para este documento, a janela é de aproximadamente meio minuto, não uma espera ilimitada.
Inicie um download lento finito em segundo plano. & permite que este shell aceite o próximo comando enquanto o cliente trabalha; $! é o PID do último trabalho em segundo plano. A atribuição salva esse trabalho observador para que wait leia depois seu resultado nativo. O atraso público de 300ms ocorre entre gravações de 32 bytes e deixa tempo para ler e mudar de aba; é uma transferência controlada de treinamento, não uma medição de desempenho.
python3 desk.py download first interrupted north-pier.txt 300 & download_job=$!
Antes de parar qualquer coisa, peça ao observador que leia a requisição nativa já registrada. O comando não envia requisição substituta nem sinal. Deve informar que o servidor original aceitou esse cliente real e que ambas as identidades ainda estão presentes. O curl padrão pode armazenar pequenas gravações em buffer; um arquivo temporariamente vazio não significa que a requisição nunca começou.
python3 desk.py accepted first interrupted
Obtenha e inspecione a identidade original. $(...) guarda em uma variável do shell o PID impresso pelo comando; depois "$server_pid", entre aspas, fornece esse valor como um único argumento. O auxiliar recusa combinações antigas de PID/início/executável/UID.
server_pid=$(python3 desk.py pid first)
python3 desk.py identity first
Envie o sinal exato somente após observar a requisição aceita:
kill -TERM "$server_pid"
Leia o resultado do cliente original. wait espera o trabalho em segundo plano deste shell. O próximo comando deve retornar 18, acompanhado da mensagem curl sobre bytes ausentes. É uma observação concluída de uma transferência que falhou, não uma falha de comando que deva ser escondida com um marcador de sucesso.
wait "$download_job"
echo $? exibe imediatamente o status nativo anterior, esperado como 18. Um cat posterior bem-sucedido substituiria esse status do shell; por isso leia-o imediatamente:
echo $?
cat downloads/interrupted.txt
Compare com o original:
cmp documents/north-pier.txt downloads/interrupted.txt
Esta comparação deve retornar 1 e informar que o arquivo parcial terminou antes da hora. O texto recebido começa com conteúdo real de North Pier, mas está incompleto. Um nome igual ou um arquivo não vazio não comprovam um download completo e útil. Mude para Server e leia Original server native exit: 0. Um servidor que saiu normalmente ainda pode ter interrompido seus clientes.
Volte a Downloads e preserve os dois resultados. A verificação apenas lê observações existentes e arquivos reais; nunca para um processo em execução nem cria a interrupção ausente por você.
Se você esperou tanto que a transferência terminou antes do sinal, não a chame de interrupção. Leia seu resultado nativo 0, compare todos os bytes e preserve o arquivo. Se first ainda estiver funcionando, inicie o mesmo comando lento com novo rótulo, como interrupted2, salve o novo trabalho e use o mesmo rótulo em accepted antes do sinal. Se o servidor original já saiu, mude para Server e inicie explicitamente outra tentativa, como retry1, mantendo a antiga; use depois o novo nome e rótulo de saída nos comandos download, accepted, pid e identity. A verificação aceita esses nomes novos. Repita uma observação real em vez de copiar um arquivo parcial. Uma transferência concluída ou desconhecida não autoriza outro sinal a um PID reciclado.
Aqui está uma repetição completa na mesma tentativa first ainda em execução. Use-a somente depois que o cliente antigo realmente terminar; preserve downloads/interrupted.txt. Leia todos os blocos antes de começar. O novo rótulo produz uma saída separada:
python3 desk.py download first interrupted2 north-pier.txt 300 & download_job=$!
python3 desk.py accepted first interrupted2
server_pid=$(python3 desk.py pid first)
python3 desk.py identity first
kill -TERM "$server_pid"
O próximo wait também deve retornar 18; leia-o imediatamente e compare o novo arquivo parcial real (comparação esperada como 1):
wait "$download_job"
echo $?
cmp documents/north-pier.txt downloads/interrupted2.txt
Se first já saiu, inicie outra tentativa em Server:
python3 desk.py serve retry1
Após a mensagem de prontidão, execute esta sequência completa em Downloads, com um terceiro rótulo novo:
python3 desk.py download retry1 interrupted3 north-pier.txt 300 & download_job=$!
python3 desk.py accepted retry1 interrupted3
server_pid=$(python3 desk.py pid retry1)
python3 desk.py identity retry1
kill -TERM "$server_pid"
wait "$download_job"
echo $?
wait deve retornar 18. Preserve a saída real e verifique que está incompleta (comparação esperada como 1):
cmp documents/north-pier.txt downloads/interrupted3.txt
Termine com o balcão original parado e os resultados preservados. O download normal já está completo e continua disponível para leitura; não deixe um listener substituto executando antes da verificação. A próxima unidade independente ensina a preservar transferências ativas.
Resumo
Você observou um download real completo e depois relacionou uma transferência interrompida à parada precisa do servidor original. Uma conexão recusada, uma transferência parcial e o encerramento normal de um processo descrevem fatos diferentes.



