Skip to content

Commit affe80d

Browse files
authored
Merge branch 'master' into dependabot/maven/org.sonatype.central-central-publishing-maven-plugin-0.11.0
2 parents 7ea288b + c59f17c commit affe80d

18 files changed

Lines changed: 585 additions & 2 deletions

‎.github/workflows/benchmark.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ jobs:
9494
python scripts/generate-graph.py zthread-benchmark/target/benchmark.json
9595
9696
- name: Commit Updated Data
97-
uses: stefanzweifel/git-auto-commit-action@v5
97+
uses: stefanzweifel/git-auto-commit-action@v7
9898
with:
9999
commit_message: "docs(benchmark): auto-update performance charts and README"
100100
file_pattern: "README.md assets/benchmark_graph.svg zthread-benchmark/charts/* zthread-benchmark/benchmark.md"

‎.gitignore‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,7 @@ Thumbs.db
4141

4242
# Logs & Temporary files
4343
logs/
44-
*.tmp
44+
*.tmp
45+
46+
# Agent / Tools
47+
.agents/

‎wiki/API.md‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# API Reference
2+
3+
Because zThread is an event loop library, its API consists of Java interfaces rather than REST endpoints. This page outlines the core public interfaces developers use to interact with the runtime.
4+
5+
## ZRuntime
6+
7+
`ZRuntime` is the primary interface for starting the loop, posting events, and registering handlers.
8+
9+
### `void start()`
10+
* **Purpose:** Starts the background event loop thread.
11+
* **Side effects:** Spawns a new thread that will block in native code (`epoll_wait`) until events occur.
12+
13+
### `void shutdown()`
14+
* **Purpose:** Signals the event loop to stop processing and exit gracefully.
15+
16+
### `<T> void on(Class<T> eventType, Consumer<T> handler)`
17+
* **Purpose:** Registers a callback handler for a specific event class.
18+
* **Parameters:**
19+
* `eventType`: The class type of the event.
20+
* `handler`: The consumer function to execute when the event is processed by the loop.
21+
22+
### `boolean post(Object event)`
23+
* **Purpose:** Inserts an event into the MPSC ring buffer and wakes up the event loop if it is sleeping.
24+
* **Parameters:**
25+
* `event`: The object to pass to the registered handler.
26+
* **Return value:** `true` if the event was successfully queued, `false` if the buffer is full (or throws an exception depending on backpressure configuration).
27+
28+
### `boolean tryPost(Object event)`
29+
* **Purpose:** A non-blocking variant of `post` that returns `false` immediately if the ring buffer is at capacity, allowing the caller to handle backpressure without exceptions.
30+
31+
## ZRuntimeBuilder
32+
33+
A fluent builder accessed via `ZRuntime.builder()`.
34+
35+
* `threadName(String name)`: Sets the name of the background thread.
36+
* `bufferSize(int size)`: Sets the capacity of the MPSC ring buffer (must be a power of two).
37+
* `maxEventsPerPoll(int max)`: Configures how many events `epoll_wait` can retrieve in a single wakeup.
38+
* `metricsEnabled(boolean enabled)`: Toggles internal JMX/micrometer metrics.
39+
* `build()`: Uses `ServiceLoader` to locate the `zthread-linux` implementation and returns a configured `ZRuntime`.
40+
41+
## ZEventFlux (zthread-reactor)
42+
43+
Provides integration with Project Reactor.
44+
45+
### `static <T> Flux<T> fromRuntime(ZRuntime runtime, Class<T> eventType)`
46+
* **Purpose:** Creates a reactive `Flux` that emits items whenever the underlying `ZRuntime` processes an event of `eventType`.

‎wiki/Architecture.md‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Architecture
2+
3+
zThread uses a layered architecture to isolate the public Java API from the underlying native Linux mechanisms. The framework relies on the Java Foreign Function & Memory (FFM) API to avoid JNI overhead.
4+
5+
## High-level architecture
6+
7+
The system consists of two primary boundaries:
8+
1. **User Space (Java):** Where the developer registers handlers, posts events, and configures the runtime.
9+
2. **Kernel Space (Linux):** Where the event loop thread sleeps (`epoll_wait`) until an event occurs on a file descriptor.
10+
11+
```mermaid
12+
graph TD
13+
subgraph Java Application
14+
A[Producer Thread 1] -->|post| Q(MPSC Ring Buffer)
15+
B[Producer Thread 2] -->|post| Q
16+
H[Event Handlers]
17+
end
18+
19+
subgraph zThread Runtime
20+
Q -->|eventfd signal| EL(Event Loop Thread)
21+
EL -->|dispatch| H
22+
NP(Native Poller) -->|epoll_wait| EL
23+
end
24+
25+
subgraph Linux Kernel
26+
EP[epoll instance]
27+
EF[eventfd]
28+
TF[timerfd]
29+
IF[inotify]
30+
EF --> EP
31+
TF --> EP
32+
IF --> EP
33+
EP -->|wake| NP
34+
end
35+
```
36+
37+
## Layered architecture
38+
39+
### 1. The Core API (`zthread-core`)
40+
Provides interface definitions that application developers interact with. It contains no OS-specific logic.
41+
* `ZRuntime`: The main interface for starting the loop and posting events.
42+
* `ZRuntimeBuilder`: Fluent builder for configuration.
43+
* `ZRuntimeFactory`: SPI interface used by the builder to discover the native implementation at runtime.
44+
45+
### 2. The Linux Implementation (`zthread-linux`)
46+
Implements the core interfaces using native calls.
47+
* `LinuxRuntime`: The concrete implementation of `ZRuntime`.
48+
* `LinuxEventLoop`: A dedicated thread that continuously polls for events and drains the MPSC ring buffer.
49+
* `LinuxNativePoller`: The FFM bridge that links to `libc.so` (or `libc.so.6`). It handles memory segments for `epoll_event` structs and invokes `epoll_create1`, `epoll_ctl`, and `epoll_wait`.
50+
51+
## Request flow
52+
53+
When a producer thread calls `runtime.post(event)`:
54+
55+
1. **Insertion:** The event is written into a lock-free Multi-Producer Single-Consumer (MPSC) Ring Buffer.
56+
2. **Wakeup Signal:** If the event loop thread is currently parked in the kernel (`epoll_wait`), the producer writes an 8-byte integer to an `eventfd`.
57+
3. **Kernel Wakeup:** The kernel detects activity on the `eventfd`, wakes the event loop thread, and returns control to `LinuxNativePoller`.
58+
4. **Drain & Dispatch:** The event loop reads the `eventfd` to clear the signal, then drains the entire MPSC ring buffer, passing each event to its registered handler sequentially.
59+
60+
## Component responsibilities
61+
62+
* **MPSC Ring Buffer:** Handles high-throughput, thread-safe queuing of events from multiple producer threads without locking.
63+
* **Native Poller:** Manages native off-heap memory allocation for Linux structures and executes exact syscalls via FFM.
64+
* **Event Dispatcher:** Maintains a map of event types to `Consumer<T>` handlers and executes them when the loop drains the buffer.

‎wiki/Authentication.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Authentication
2+
3+
*Note: This document is included for structural completeness.*
4+
5+
zThread is a low-level event dispatch and concurrency library. It does not handle user sessions, login flows, OAuth, JWTs, or role-based access control.
6+
7+
Any authentication or authorization middleware must be implemented at the application layer above the zThread runtime.

‎wiki/Configuration.md‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Configuration
2+
3+
Configuration for a zThread instance is handled via the `ZRuntimeBuilder` and stored immutably in `ZRuntimeConfig`. There are no external environment variables or properties files required by the library itself.
4+
5+
## ZRuntimeConfig Options
6+
7+
| Option | Required | Default | Description |
8+
| :--- | :--- | :--- | :--- |
9+
| `threadName` | No | `zthread-event-loop` | The name given to the background event loop thread. |
10+
| `bufferSize` | No | `4096` | The capacity of the MPSC ring buffer. Must be positive; the builder automatically rounds this to a minimum of `64`. |
11+
| `maxEventsPerPoll` | No | `64` | The maximum number of events retrieved from the kernel per `epoll_wait` call. |
12+
| `metricsEnabled` | No | `true` | Whether internal performance metrics collection is enabled. |
13+
| `debugEnabled` | No | `false` | Whether debug-level internal logging is printed. |
14+
15+
### Usage Example
16+
17+
```java
18+
ZRuntime runtime = ZRuntime.builder()
19+
.threadName("my-app-worker")
20+
.bufferSize(8192)
21+
.maxEventsPerPoll(128)
22+
.metricsEnabled(false)
23+
.build();
24+
```
25+
26+
### Security Notes
27+
28+
The configuration options do not manage secrets or sensitive data. However, setting `bufferSize` excessively high in an environment with many concurrent event loops could lead to `OutOfMemoryError` conditions, as the buffer is allocated upfront.

‎wiki/Contributing.md‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Contributing
2+
3+
We welcome contributions to zThread! This guide covers how to submit code, report bugs, and align with our development standards.
4+
5+
## Reporting Bugs
6+
7+
Please use the GitHub Issue tracker to report bugs. Include:
8+
* Your OS version and kernel.
9+
* Your JDK version.
10+
* A clear, reproducible code example if possible.
11+
12+
## Pull Request Process
13+
14+
1. **Fork and Branch:** Create a fork of the repository and create a feature branch (`feature/your-feature` or `fix/issue-description`).
15+
2. **Write Tests:** Ensure your new feature is covered by unit tests. If you modified native interactions, add an integration test.
16+
3. **Format Code:** Run `./mvnw spotless:apply` to ensure your code matches the Google Java Format and includes the Apache 2.0 license header.
17+
4. **Pass Checks:** Run `./mvnw clean verify -Pquality` to verify that Checkstyle, PMD, and SpotBugs pass.
18+
5. **Submit PR:** Open a Pull Request against the `main` branch.
19+
20+
## Commit Conventions
21+
22+
While not strictly enforced via tooling, we appreciate clean, descriptive commit messages.
23+
24+
* Use the imperative mood: "Fix bug in ring buffer" rather than "Fixed bug".
25+
* If your commit resolves an issue, include `Fixes #123` in the description.
26+
27+
## Development Environment Setup
28+
29+
See [Development Workflow](Development) for details on the required JDK, Maven commands, and debugging tools.

‎wiki/Database.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Database
2+
3+
*Note: This document is included for structural completeness.*
4+
5+
zThread is an in-memory, native event loop library. It does not interact with databases, contain a schema, or manage persistent entities.
6+
7+
If you are using zThread to build a database driver or an application that connects to a database, you must manage your own connection pools (e.g., HikariCP) and ensure that blocking database I/O operations are offloaded to a separate thread pool.
8+
9+
Because the zThread event loop (`ZRuntime`) runs on a single thread, performing synchronous database calls inside a zThread event handler will stall the entire event loop and prevent other events from being processed.

‎wiki/Deployment.md‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Deployment
2+
3+
*Note: As zThread is a library, "deployment" refers to publishing artifacts to Maven Central, not deploying a service to a cloud provider like Kubernetes.*
4+
5+
## Release Process
6+
7+
Artifacts are published to the Sonatype OSSRH (Open Source Software Repository Hosting) and synced to Maven Central.
8+
9+
The project uses the Maven Release Profile and the Sonatype Central Publishing Plugin to automate this process.
10+
11+
### Build and Deploy Command
12+
13+
To release a new version to Maven Central, project maintainers run:
14+
15+
```bash
16+
./mvnw clean deploy -Prelease --batch-mode --no-transfer-progress
17+
```
18+
19+
### The `release` Profile
20+
21+
The `-Prelease` flag activates the `release` Maven profile defined in the root `pom.xml`. This profile attaches the following plugins to the build lifecycle:
22+
23+
1. **`maven-source-plugin`:** Generates `-sources.jar`.
24+
2. **`maven-javadoc-plugin`:** Generates `-javadoc.jar`.
25+
3. **`maven-gpg-plugin`:** Cryptographically signs all artifacts (JARs, POMs) with the maintainer's GPG key.
26+
4. **`central-publishing-maven-plugin`:** Uploads the signed artifacts and automates the release process on Sonatype.
27+
28+
### CI/CD
29+
30+
Release processes are handled manually or via the `Release` GitHub Action (`.github/workflows/release.yml`), which requires the `MAVEN_USERNAME`, `MAVEN_PASSWORD`, and GPG secret keys to be configured as repository secrets.

‎wiki/Development.md‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Development Workflow
2+
3+
This page outlines the local development setup, coding standards, and common tasks for contributors working on the zThread codebase.
4+
5+
## Prerequisites
6+
* **OS:** A Linux environment (natively or via WSL2) is required because the library depends on kernel-specific features (`epoll`, `eventfd`).
7+
* **Java:** JDK 25.
8+
* **Maven:** Included via the Maven Wrapper (`./mvnw`).
9+
10+
## Coding Standards
11+
12+
The project enforces strict code quality and formatting rules. Before submitting a pull request, ensure your code passes the quality profile.
13+
14+
### Linting and Formatting
15+
16+
Run the quality check profile:
17+
```bash
18+
./mvnw clean verify -Pquality
19+
```
20+
21+
This runs the following plugins:
22+
1. **Spotless:** Enforces Google Java Format and prepends the Apache 2.0 license header.
23+
2. **Checkstyle:** Validates naming conventions, import ordering, and Javadoc presence.
24+
3. **PMD:** Scans for potential bugs, dead code, and suboptimal performance patterns.
25+
4. **SpotBugs:** Analyzes bytecode for common bug patterns.
26+
27+
If Spotless fails due to formatting, you can automatically fix it with:
28+
```bash
29+
./mvnw spotless:apply
30+
```
31+
32+
## Local Workflow
33+
34+
1. **Build and test:**
35+
```bash
36+
./mvnw clean verify --enable-native-access=ALL-UNNAMED
37+
```
38+
39+
2. **Run benchmarks:**
40+
```bash
41+
cd zthread-benchmark
42+
../mvnw clean package
43+
java --enable-native-access=ALL-UNNAMED -jar target/benchmarks.jar
44+
```
45+
46+
## Debugging
47+
48+
Because zThread utilizes the FFM API, segmentation faults can occur if off-heap memory is mismanaged or accessed after it has been freed.
49+
50+
To debug native memory issues, you can run the JVM with:
51+
```bash
52+
java -XX:NativeMemoryTracking=detail --enable-native-access=ALL-UNNAMED ...
53+
```
54+
For deep native stack traces, attach `gdb` to the Java process.

0 commit comments

Comments
 (0)