Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: CI

on:
push:
branches: [main, master, fixrace]
pull_request:
branches: [main, master]

env:
ZIG_VERSION: "0.16.0-dev.1657+985a3565c"
ZIG_URL: "https://ziglang.org/builds/zig-x86_64-linux-0.16.0-dev.1657+985a3565c.tar.xz"

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Cache Zig
uses: actions/cache@v4
with:
path: ~/zig
key: zig-${{ env.ZIG_VERSION }}

- name: Install Zig
run: |
if [ ! -d ~/zig ]; then
mkdir -p ~/zig
curl -L ${{ env.ZIG_URL }} | tar -xJ -C ~/zig --strip-components=1
fi
echo "$HOME/zig" >> $GITHUB_PATH

- name: Verify Zig version
run: zig version

- name: Patch ecdsa.zig for API compatibility
run: sed -i 's/mem\.trimLeft/mem.trimStart/g' ~/zig/lib/std/crypto/ecdsa.zig

- name: Build
run: zig build

- name: Run unit tests
run: zig build test

release-build:
runs-on: ubuntu-latest
if: github.event_name == 'push'
needs: build
strategy:
matrix:
include:
- target: x86_64-linux
artifact: load_balancer-x86_64-linux
- target: aarch64-linux
artifact: load_balancer-aarch64-linux
- target: x86_64-macos
artifact: load_balancer-x86_64-macos
- target: aarch64-macos
artifact: load_balancer-aarch64-macos

steps:
- uses: actions/checkout@v4

- name: Cache Zig
uses: actions/cache@v4
with:
path: ~/zig
key: zig-${{ env.ZIG_VERSION }}

- name: Install Zig
run: |
if [ ! -d ~/zig ]; then
mkdir -p ~/zig
curl -L ${{ env.ZIG_URL }} | tar -xJ -C ~/zig --strip-components=1
fi
echo "$HOME/zig" >> $GITHUB_PATH

- name: Patch ecdsa.zig for API compatibility
run: sed -i 's/mem\.trimLeft/mem.trimStart/g' ~/zig/lib/std/crypto/ecdsa.zig

- name: Build release binary
run: |
zig build -Doptimize=ReleaseFast -Dtarget=${{ matrix.target }}
mv zig-out/bin/load_balancer ${{ matrix.artifact }}

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: ${{ matrix.artifact }}
80 changes: 80 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: Release

on:
push:
tags:
- 'v*'

env:
ZIG_VERSION: "0.16.0-dev.1657+985a3565c"
ZIG_URL: "https://ziglang.org/builds/zig-x86_64-linux-0.16.0-dev.1657+985a3565c.tar.xz"

jobs:
build-release:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- target: x86_64-linux
artifact: load_balancer-x86_64-linux
- target: aarch64-linux
artifact: load_balancer-aarch64-linux
- target: x86_64-macos
artifact: load_balancer-x86_64-macos
- target: aarch64-macos
artifact: load_balancer-aarch64-macos

steps:
- uses: actions/checkout@v4

- name: Cache Zig
uses: actions/cache@v4
with:
path: ~/zig
key: zig-${{ env.ZIG_VERSION }}

- name: Install Zig
run: |
if [ ! -d ~/zig ]; then
mkdir -p ~/zig
curl -L ${{ env.ZIG_URL }} | tar -xJ -C ~/zig --strip-components=1
fi
echo "$HOME/zig" >> $GITHUB_PATH

- name: Build release binary
run: |
zig build -Doptimize=ReleaseFast -Dtarget=${{ matrix.target }}
mv zig-out/bin/load_balancer ${{ matrix.artifact }}

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: ${{ matrix.artifact }}

create-release:
runs-on: ubuntu-latest
needs: build-release
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts

- name: Prepare release assets
run: |
cd artifacts
for dir in */; do
name="${dir%/}"
chmod +x "$dir/$name"
tar -czvf "$name.tar.gz" -C "$dir" "$name"
done
ls -la *.tar.gz

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: artifacts/*.tar.gz
Empty file removed 1
Empty file.
Binary file removed __pycache__/h2_backend.cpython-314.pyc
Binary file not shown.
12 changes: 12 additions & 0 deletions main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,14 @@ fn workerMain(
defer threaded.deinit();
const io = threaded.io();

// CRITICAL: Increase async_limit to prevent synchronous fallback deadlock
// Default is CPU cores - 1. With HTTP/2 multiplexing, each connection spawns
// a reader task. If async_limit is exceeded, Io.async runs synchronously,
// blocking the request coroutine forever (reader waits for data, request
// never gets to wait on its condition).
// Set to unlimited so reader tasks always spawn asynchronously.
threaded.setAsyncLimit(.unlimited);

// Set CPU affinity after Io.Threaded.init
setCpuAffinity(worker_id) catch {};

Expand Down Expand Up @@ -780,6 +788,10 @@ fn runSingleProcess(parent_allocator: std.mem.Allocator, config: Config) !void {
defer threaded.deinit();
const io = threaded.io();

// CRITICAL: Increase async_limit to prevent synchronous fallback deadlock
// See comment in workerMain for details.
threaded.setAsyncLimit(.unlimited);

// Router
var router = switch (lb_config.strategy) {
inline else => |s| try createRouter(allocator, &worker_state, s),
Expand Down
2 changes: 1 addition & 1 deletion src/config/config_watcher.zig
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub const FileWatcher = struct {

/// Initialize inotify-based watcher (Linux)
fn initInotify(path: []const u8) !Self {
const inotify_fd = try posix.inotify_init1(.{ .CLOEXEC = true });
const inotify_fd = try posix.inotify_init1(std.os.linux.IN.CLOEXEC);
errdefer posix.close(inotify_fd);

const mask: u32 = std.os.linux.IN.MODIFY | std.os.linux.IN.MOVE_SELF | std.os.linux.IN.DELETE_SELF;
Expand Down
Loading