Files
cpp-httplib/docs-src/pages/ja/cookbook/s19-graceful-shutdown.md
T
yhirose 9bfd2ddf1c Fix README and docs pages that no longer match the code
Bring the READMEs and the docs pages (en and ja) in line with the
current header:

- Fix the client sample that does not compile, the Transfer-Encoding
  statement for default headers, the verifier callback comment, the
  thread pool spawn rule, the sanitize_filename description, and the
  inverted Accept-Encoding sentence.
- Describe recent behaviour: TLS errors behind Read/Write failures,
  Host validation, Connection: close for a body without length,
  content_reader rules, refused CONNECT, WebSocketClient proxies,
  CPPHTTPLIB_INTERIM_RESPONSE_MAX_COUNT, the SSE event size limit, and
  the payload limit of the Stream API.
- Complete the API references of WebSocket, WebSocketClient and the
  stream:: helpers, and the SSE reconnect rules.
- Fix cookbook pages: keychain loading on every backend, received Close
  status, a multipart sample that trusted the client's file name, an
  echo sample that sent binary as text, SNI, pre-request handler scope,
  stop() with WebSocket handlers, and the thread pool notes.
- Restore the mutex in the LLM app's Chapter 5 code.
2026-10-18 10:13:57 -04:00

60 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "S19. グレースフルシャットダウンする"
order: 38
status: "draft"
---
サーバーを止めるには`Server::stop()`を呼びます。処理中のリクエストがある状態でも安全に呼べるので、SIGINTやSIGTERMを受け取ったときにこれを呼べば、グレースフルなシャットダウンが実現できます。
## 基本の使い方
```cpp
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を受け取ったときに停止させる例です。
```cpp
#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()`が戻るまでには、処理中のリクエストが終わるのを待つ時間がかかります。タイムアウトを強制したい場合は、シャットダウン用のタイマーを別途用意するなど、アプリケーション側の工夫が必要です。
> **Note:** `stop()`はWebSocketハンドラを中断しません。`read()`をループで回しているハンドラは相手がつながっている限り動き続け、それが終わるまで`listen()`も戻りません。開いているWebSocket接続を記録しておき、シャットダウン時に`close()`(`CloseStatus::GoingAway`など)で閉じてください。