Узнайте, что прерывает немедленный выход

LinuxBeginner
Практиковаться сейчас

Введение

Общественный пункт загрузки раздаёт полевые заметки North Pier и памятку для волонтёров сада. Перед закрытием волонтёр хочет дать уже принятой загрузке завершиться. Первая реализация немедленно закрывает соединения. Сначала вы получите полный полезный документ, затем точно увидите, что прерывает немедленная остановка.

Нужны знания функций, обработчиков и значений ошибок Go, а также распределения ответственности между goroutine и channel из предыдущих двух проектов либо равноценный опыт. Идентификация процессов и SIGTERM объясняются здесь. Два именованных терминала — сеансы одной машины. Подготовленные средства наблюдения записывают только собранный сервер курса и дочерние процессы curl; изучать формат нативных трасс не требуется. На чтение и обычные ошибки отведено около 45 минут по оценке автора. Каждый модуль начинается независимо.

Загрузите один полный документ

На этом шаге получите полный полезный документ и проверьте его фактические байты.

Начните в Downloads. Обе точки входа в терминалы только переходят в существующую рабочую папку; открытие вкладки не создаёт сценарий заново. При обычной ошибке каталога эта явная команда вернёт вас в нужное место:

cd /home/labex/project/download-desk

Прочитайте два исходных текстовых файла. Они содержат разные практические материалы, а не одно содержимое под разными именами. cat показывает содержимое, не изменяя файлы.

cat documents/north-pier.txt documents/garden-route.txt

Сохраняйте оригиналы и все подготовленные файлы неизменными в течение модуля. Разрешается собрать desk, запускать именованные наблюдаемые попытки и создавать загрузки. Код Go здесь не меняется. Каждый следующий модуль предоставляет собственную новую копию.

Переключитесь в Server. Исполняемый файл Go подготовлен по абсолютному пути. build компилирует пакет; . означает текущий пакет, а -o desk задаёт имя полученного исполняемого файла. Собранный бинарный файл позволяет точно определить процесс, в отличие от отправки сигнала обёртке go run.

cd /home/labex/project/download-desk
/usr/local/go/bin/go build -o desk .

Запустите именованную попытку. Предоставленный наблюдатель запускает ваш бинарный файл и записывает реальный процесс, HTTP-запросы, сигналы и нативный результат завершения; он не реализует корректное выключение. first — имя попытки. Существующее имя отклоняется, чтобы прошлые свидетельства не были незаметно перезаписаны.

python3 desk.py serve first

Дождитесь Ready. Use Downloads for client requests.. Этот терминал занят до завершения исходного процесса. Напечатанный PID относится к собранному дочернему Go-процессу, а не наблюдателю. Оставьте Server работать и перейдите в Downloads.

Подготовленный клиент запускает настоящий curl, записывает его нативный результат и сохраняет фактический вывод. Четыре аргумента выбирают попытку, новую метку вывода, подготовленный документ и задержку в миллисекундах на каждые 32 байта. Задержка 0 — обычный быстрый пример. Метка normal создаёт downloads/normal.txt.

python3 desk.py download first normal north-pier.txt 0

Ожидается Original curl native exit: 0. Ноль означает завершение передачи, но сам по себе не доказывает её содержимое. cmp сравнивает реальные файлы побайтно и ничего не выводит при равенстве. Прочитайте и сохранённый полезный документ:

cmp documents/north-pier.txt downloads/normal.txt
cat downloads/normal.txt

Если клиент сообщает об отказе в соединении, вернитесь в Server и прочитайте имеющийся вывод. Не запускайте многократно другой процесс на том же порту. При ошибке сборки Go исправьте каталог или сравните подготовленный файл, прежде чем собирать снова. Новая оболочка не наследует переменные другой оболочки, но файлы и наблюдаемая попытка общие для двух сеансов.

Остановите исходный сервер во время принятой загрузки

На этом шаге прервите действительно принятую передачу и отличите сбой клиента от завершения сервера.

Начните в Downloads, пока Server ещё выполняет first. Идентификатор процесса, PID, обозначает работающий процесс, но после его завершения ОС может использовать номер повторно. Наблюдатель также проверяет путь исполняемого файла, ID текущего пользователя и такты запуска Linux из /proc, отличая исходный процесс. Отправляйте сигнал только собранному процессу этого курса. Не используйте pkill, не выбирайте наблюдатель целью и не меняйте процессы платформы или настройки оболочки.

SIGTERM — обычная просьба завершить процесс. kill -TERM PID отправляет её одному точному PID. Команда сама не ждёт загрузок и не доказывает завершения процесса. Подготовленная программа Go получает сигнал, немедленно вызывает Close и возвращается из main. Именно это поведение предстоит наблюдать, а не сетевую аварию.

До запуска медленной передачи прочитайте остаток шага, включая ожидаемые ошибки и восстановление. Затем выполняйте блоки по порядку; не изучайте следующий новый термин, пока идёт этот запрос конечной длительности. Для документа окно составляет примерно полминуты, а не бесконечное ожидание.

Запустите конечную медленную загрузку в фоне. & позволяет оболочке принять следующую команду, пока клиент работает; $! — PID последнего фонового задания. Присваивание сохраняет это задание наблюдателя, чтобы wait позже прочитал его нативный результат. Открыто заданная задержка 300ms действует между записями по 32 байта и даёт время читать и переключать вкладки; это управляемая учебная передача, не измерение производительности.

python3 desk.py download first interrupted north-pier.txt 300 & download_job=$!

Перед остановкой попросите наблюдатель прочитать уже записанный нативный запрос. Команда не отправляет подменный запрос или сигнал. Она должна сообщить, что исходный сервер принял именно этого реального клиента и обе идентичности ещё присутствуют. Обычный curl может буферизовать небольшие записи, поэтому временно пустой файл не означает, что запрос не начался.

python3 desk.py accepted first interrupted

Получите и проверьте исходную идентичность. $(...) сохраняет напечатанный командой PID в переменную оболочки; заключённое в кавычки "$server_pid" затем передаст его одним аргументом. Помощник отклоняет устаревшее сочетание PID/времени запуска/исполняемого файла/UID.

server_pid=$(python3 desk.py pid first)
python3 desk.py identity first

Отправляйте точный сигнал только после наблюдения принятого запроса:

kill -TERM "$server_pid"

Прочитайте результат исходного клиента. wait ждёт фоновое задание этой оболочки. Следующая команда должна вернуть 18 вместе с сообщением curl о недостающих байтах. Это завершённое наблюдение неудачной передачи, а не ошибка команды, которую нужно скрыть отметкой успеха.

wait "$download_job"

echo $? сразу показывает предыдущий нативный статус, ожидается 18. Последующий успешный cat заменит статус оболочки, поэтому читайте его немедленно:

echo $?
cat downloads/interrupted.txt

Сравните с оригиналом:

cmp documents/north-pier.txt downloads/interrupted.txt

Сравнение должно вернуть 1 и сообщить о преждевременном конце частичного файла. Полученный текст начинается с настоящего материала North Pier, но неполон. Совпадающее имя или непустой файл поэтому не доказывают полную полезную загрузку. Перейдите в Server и прочитайте Original server native exit: 0. Нормально завершившийся сервер тоже мог прервать клиентов.

Вернитесь в Downloads и сохраните оба результата. Проверка курса только читает существующие наблюдения и реальные файлы; она не останавливает работающий процесс и не создаёт недостающую операцию прерывания за вас.

Если медленная передача завершилась до сигнала из-за долгого ожидания, не называйте её прерванной. Прочитайте нативный 0, сравните все байты и сохраните файл. Если first ещё работает, запустите ту же медленную команду с новой меткой, например interrupted2, сохраните новое фоновое задание и используйте эту метку в accepted до сигнала. Если исходный сервер уже вышел, переключитесь в Server и явно начните новую попытку вроде retry1, сохранив старую; затем используйте новое имя и метку вывода в download, accepted, pid и identity. Проверка принимает новые имена. Повторяйте реальное наблюдение, а не копируйте частичный файл. Закончившаяся или неизвестная передача не разрешает повторный сигнал повторно использованному PID.

Вот полный повтор на том же ещё работающем first. Используйте его только после фактического завершения старого клиента; сохраните downloads/interrupted.txt. Перед началом прочитайте все блоки. Новая метка создаёт отдельный вывод:

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"

Следующий wait снова должен вернуть 18; сразу прочитайте статус, затем сравните новый реальный частичный файл (ожидается 1):

wait "$download_job"
echo $?
cmp documents/north-pier.txt downloads/interrupted2.txt

Если first уже вышел, начните отдельную попытку в Server:

python3 desk.py serve retry1

После сообщения готовности выполните эту полную последовательность в Downloads с третьей новой меткой вывода:

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 должен вернуть 18. Сохраните фактический вывод и убедитесь в его неполноте (сравнение должно вернуть 1):

cmp documents/north-pier.txt downloads/interrupted3.txt

В конце оставьте исходный пункт остановленным, а результаты сохранёнными. Обычная загрузка уже полная и доступна для чтения; не оставляйте подменный слушатель работать перед проверкой. Следующий независимый модуль учит сохранять активные передачи.

Резюме

Вы наблюдали настоящую полную загрузку и связали прерванную передачу с точной остановкой исходного сервера. Отказ в соединении, частичная передача и нормальное завершение процесса описывают разные факты.