Skip to content

Claude/fix connection leak#152

Open
KamalF wants to merge 6 commits into
rikhuijzer:mainfrom
KamalF:claude/fix-connection-leak-dvvu6
Open

Claude/fix connection leak#152
KamalF wants to merge 6 commits into
rikhuijzer:mainfrom
KamalF:claude/fix-connection-leak-dvvu6

Conversation

@KamalF
Copy link
Copy Markdown

@KamalF KamalF commented Mar 7, 2026

Hi,
I ran into some issues while serving the blog. The connection would hang after a while, and I had to restart the container.
Since I'm not a Rust developer, I used Claude Code to help me find a solution. I tested it for a few days, and the issue stopped occurring. I tried to guide it to make it easy to review.
I understand if you don't want to merge AI-assisted PRs. If not, I hope this helps you understand the issue and find the right fix.
Anyways thank you for this nice tool!
Best regards

claude and others added 6 commits March 7, 2026 16:43
Replace axum::serve with a custom accept loop that sets:
- HTTP header_read_timeout (30s) to close idle connections
- TCP keepalive (60s probe, 10s interval) to detect dead peers

This is the primary fix for connections accumulating indefinitely.

https://claude.ai/code/session_01QdhLbQGvXFd2YVQ7sPKqQQ
Split BlogCache::update into read_feed_urls + apply_downloaded_items so
the mutex is released before downloading RSS feeds. Apply the same
lock-release-download-relock pattern in settings and the scheduler.

Also fix spawn_blocking misuse (was wrapping an async closure) by
switching to tokio::spawn, and remove unnecessary Arc<Mutex<>> around
ServerContext in schedule_jobs since it is Clone.

https://claude.ai/code/session_01QdhLbQGvXFd2YVQ7sPKqQQ
Use r2d2::CustomizeConnection to set busy_timeout and synchronous on
every connection in the pool. Previously only the first connection got
these settings, leaving the other 7 with busy_timeout=0 (immediate
SQLITE_BUSY errors under write contention).

https://claude.ai/code/session_01QdhLbQGvXFd2YVQ7sPKqQQ
Set 10s request timeout and 5s connect timeout on all reqwest clients
(RSS fetcher, health check, GitHub/Forgejo trigger) to prevent the
process from hanging indefinitely on unresponsive external services.

https://claude.ai/code/session_01QdhLbQGvXFd2YVQ7sPKqQQ
Add 5 integration tests covering concurrent request handling, burst
recovery, blogroll under load, and real TCP connections. The TCP tests
use axum::serve (not the production serve_with_timeouts) and are
documented accordingly.

https://claude.ai/code/session_01QdhLbQGvXFd2YVQ7sPKqQQ
@rikhuijzer
Copy link
Copy Markdown
Owner

You are right. I have also seen it. It is an issue. Thanks for making a PR. I don't have time now but hope I can review the PR soon.

For now, if you want to be absolutely sure that your server stays online, look into the health check that was recently added:

    healthcheck:
      test: ['CMD', '/fx', 'check-health']

If you add this line, don't forget to also spawn an autoheal container, because Docker does not automatically restart containers even when the health check fails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants