Files
cpp-httplib/docs-src/pages/ja/cookbook/s19-graceful-shutdown.md
T
yhirose c95d799180 Polish the wording of the updated docs pages
Reword the Japanese sentences so they read naturally, and correct the
size of the llama.cpp server sources in the code reading chapter.
2026-10-08 20:39:13 -04:00

2.5 KiB
Raw Blame History

title, order, status
title order status
S19. グレースフルシャットダウンする 38 draft

サーバーを止めるにはServer::stop()を呼びます。処理中のリクエストがある状態でも安全に呼べるので、SIGINTやSIGTERMを受け取ったときにこれを呼べば、グレースフルなシャットダウンが実現できます。

基本の使い方

httplib::Server svr;

svr.Get("/", [](const auto &, auto &res) { res.set_content("ok", "text/plain"); });

std::thread t([&] { svr.listen("0.0.0.0", 8080); });

// メインスレッドで入力を待つなど
std::cin.get();

svr.stop();
t.join();

listen()はブロックするので、別スレッドで動かして、メインスレッドからstop()を呼ぶのが典型的なパターンです。stop()後はlisten()が戻ってくるので、join()できます。

シグナルでシャットダウンする

SIGINT(Ctrl+C)やSIGTERMを受け取ったときに停止させる例です。

#include <csignal>

httplib::Server svr;

// グローバル領域に置いてシグナルハンドラからアクセス
httplib::Server *g_svr = nullptr;

int main() {
  svr.Get("/", [](const auto &, auto &res) { res.set_content("ok", "text/plain"); });

  g_svr = &svr;
  std::signal(SIGINT,  [](int) { if (g_svr) g_svr->stop(); });
  std::signal(SIGTERM, [](int) { if (g_svr) g_svr->stop(); });

  svr.listen("0.0.0.0", 8080);
  std::cout << "server stopped" << std::endl;
}

stop()はスレッドセーフで、シグナルハンドラの中から呼んでも安全です。listen()がメインスレッドで動いていても、シグナルを受けたら抜けてきます。

処理中のリクエストの扱い

stop()を呼ぶと、新しい接続は受け付けなくなりますが、すでに動いているハンドラは最後まで実行されます。ただし、ストリーミングのようにコンテンツプロバイダで送っている途中のレスポンスは、その場で打ち切られます。その後、スレッドプールのワーカーが順次終了し、listen()から戻ってきます。これがグレースフルシャットダウンと呼ばれる理由です。

Warning: stop()を呼んでからlisten()が戻るまでには、処理中のリクエストが終わるのを待つ時間がかかります。タイムアウトを強制したい場合は、シャットダウン用のタイマーを別途用意するなど、アプリケーション側の工夫が必要です。