{"id":30677636,"url":"https://github.com/jamesgober/proc-daemon","last_synced_at":"2025-09-01T12:19:58.806Z","repository":{"id":310671954,"uuid":"1040708369","full_name":"jamesgober/proc-daemon","owner":"jamesgober","description":"A high-performance, cross-platform daemon framework for Rust. Built with an async-native architecture and robust graceful shutdown for creating resilient, production-grade services.","archived":false,"fork":false,"pushed_at":"2025-08-26T16:18:00.000Z","size":167,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-26T21:48:19.747Z","etag":null,"topics":["async","cross-platform","daemon","high-performance","pm2","resilience","rhpl","rust","systemd","tokio"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jamesgober.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-19T11:44:07.000Z","updated_at":"2025-08-26T19:45:19.000Z","dependencies_parsed_at":"2025-08-25T04:46:44.831Z","dependency_job_id":null,"html_url":"https://github.com/jamesgober/proc-daemon","commit_stats":null,"previous_names":["jamesgober/proc-daemon"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/jamesgober/proc-daemon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesgober%2Fproc-daemon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesgober%2Fproc-daemon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesgober%2Fproc-daemon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesgober%2Fproc-daemon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jamesgober","download_url":"https://codeload.github.com/jamesgober/proc-daemon/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamesgober%2Fproc-daemon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273122142,"owners_count":25049539,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-01T02:00:09.058Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","cross-platform","daemon","high-performance","pm2","resilience","rhpl","rust","systemd","tokio"],"created_at":"2025-09-01T12:19:58.013Z","updated_at":"2025-09-01T12:19:58.782Z","avatar_url":"https://github.com/jamesgober.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n    \u003cimg width=\"72xpx\" src=\"./media/proc-rs-orange.svg\" alt=\"High-Performance Process EcoSystem for Rust\"\u003e\n    \u003ch1\u003e\n        \u003cstrong\u003eProcess Daemon\u003c/strong\u003e\n        \u003csup\u003e\u003cbr\u003e\u003csub\u003eRUST DAEMON FRAMEWORK\u003c/sub\u003e\u003c/sup\u003e\n    \u003c/h1\u003e\n        \u003ca href=\"https://crates.io/crates/proc-daemon\" alt=\"Error-Protocol on Crates.io\"\u003e\u003cimg alt=\"Crates.io\" src=\"https://img.shields.io/crates/v/proc-daemon\"\u003e\u003c/a\u003e\n        \u003cspan\u003e\u0026nbsp;\u003c/span\u003e\n        \u003ca href=\"https://crates.io/crates/proc-daemon\" alt=\"Download proc-daemon\"\u003e\u003cimg alt=\"Crates.io Downloads\" src=\"https://img.shields.io/crates/d/proc-daemon?color=%230099ff\"\u003e\u003c/a\u003e\n        \u003cspan\u003e\u0026nbsp;\u003c/span\u003e\n        \u003ca href=\"./LICENSE\" title=\"License\"\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-Apache--2.0-blue.svg\"\u003e\u003c/a\u003e\n        \u003cspan\u003e\u0026nbsp;\u003c/span\u003e\n        \u003ca href=\"https://docs.rs/proc-daemon\" title=\"proc-daemon Documentation\"\u003e\u003cimg alt=\"docs.rs\" src=\"https://img.shields.io/docsrs/proc-daemon\"\u003e\u003c/a\u003e\n        \u003cspan\u003e\u0026nbsp;\u003c/span\u003e\n        \u003ca href=\"https://github.com/jamesgober/proc-daemon/actions\"\u003e\u003cimg alt=\"GitHub CI\" src=\"https://github.com/jamesgober/proc-daemon/actions/workflows/ci.yml/badge.svg\"\u003e\u003c/a\u003e\n\u003c/div\u003e\n\u003cbr\u003e\n\u003cp\u003e\n    A foundational framework for building high-performance, resilient daemon services in Rust. Designed for enterprise applications requiring nanosecond-level performance, bulletproof reliability, and extreme concurrency.\n\u003c/p\u003e\n\n## Features\n\n### Core Capabilities\n- **Zero-Copy Architecture**: Minimal allocations with memory pooling for maximum performance\n- **Runtime Agnostic**: First-class support for both Tokio and async-std via feature flags\n- **Cross-Platform**: Native support for Linux, macOS, and Windows with platform-specific optimizations\n- **Graceful Shutdown**: Coordinated shutdown with configurable timeouts and subsystem awareness\n- **Signal Handling**: Robust cross-platform signal management (SIGTERM, SIGINT, SIGQUIT, SIGHUP, Windows console events)\n\n### Advanced Features\n- **Subsystem Management**: Concurrent subsystem lifecycle management with health checks and auto-restart\n- **Configuration Hot-Reload**: Dynamic configuration updates without service interruption\n- **Structured Logging**: High-performance tracing with JSON support and log rotation\n- **Metrics Collection**: Built-in performance monitoring and resource tracking\n- **Memory Safety**: 100% safe Rust with `#![deny(unsafe_code)]`\n\n### Enterprise Ready\n- **High Concurrency**: Built for 100,000+ concurrent operations\n- **Resource Management**: Intelligent memory pooling and NUMA awareness\n- **Health Monitoring**: Comprehensive subsystem health checks and diagnostics\n- **Production Tested**: Battle-tested patterns from high-scale deployments\n\n\u003cbr\u003e\n\u003chr\u003e\n\u003cbr\u003e\n\n## Installation\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nproc-daemon = \"0.9.0\"\n\n# Optional features\nproc-daemon = { version = \"0.9.0\", features = [\"full\"] }\n```\n\n### Feature Flags\n\n| Feature | Description | Default |\n|---------|-------------|---------|\n| `tokio` | Tokio runtime support | ✅ |\n| `async-std` | async-std runtime support | ❌ |\n| `metrics` | Performance metrics collection | ❌ |\n| `console` | Enhanced console output | ❌ |\n| `json-logs` | JSON structured logging | ❌ |\n| `config-watch` | Configuration hot-reloading | ❌ |\n| `mmap-config` | Memory-mapped config file loading (TOML fast-path, safe fallback) | ❌ |\n| `mimalloc` | Use mimalloc as global allocator | ❌ |\n| `high-res-timing` | High-resolution timing via `quanta` | ❌ |\n| `scheduler-hints` | Enable scheduler tuning hooks (no-op by default) | ❌ |\n| `scheduler-hints-unix` | Best-effort Unix niceness adjustment (uses `renice`; no-op without privileges) | ❌ |\n| `lockfree-coordination` | Lock-free coordination/events via crossbeam-channel | ❌ |\n| `profiling` | Optional CPU profiling via `pprof` | ❌ |\n| `heap-profiling` | Optional heap profiling via `dhat` | ❌ |\n| `full` | All features enabled | ❌ |\n\n## Quick Start\n\n### Simple Daemon\n\n```rust\nuse proc_daemon::{Daemon, Config};\nuse std::time::Duration;\n\nasync fn my_service(mut shutdown: proc_daemon::ShutdownHandle) -\u003e proc_daemon::Result\u003c()\u003e {\n    let mut counter = 0;\n    \n    loop {\n        tokio::select! {\n            _ = shutdown.cancelled() =\u003e {\n                tracing::info!(\"Service shutting down gracefully after {} iterations\", counter);\n                break;\n            }\n            _ = tokio::time::sleep(Duration::from_secs(1)) =\u003e {\n                counter += 1;\n                tracing::info!(\"Service running: iteration {}\", counter);\n            }\n        }\n    }\n    \n    Ok(())\n}\n\n#[tokio::main]\nasync fn main() -\u003e proc_daemon::Result\u003c()\u003e {\n    let config = Config::new()?;\n    \n    Daemon::builder(config)\n        .with_task(\"my_service\", my_service)\n        .run()\n        .await\n}\n```\n\n### High-Resolution Timing (optional)\n\nEnable the `high-res-timing` feature to access a fast, monotonic clock backed by `quanta`:\n\n```toml\n[dependencies]\nproc-daemon = { version = \"0.9.0\", features = [\"high-res-timing\"] }\n```\n\n```rust\n#[cfg(feature = \"high-res-timing\")]\n{\n    let t0 = proc_daemon::timing::now();\n    // ... work ...\n    let t1 = proc_daemon::timing::now();\n    let dt = t1.duration_since(t0);\n    println!(\"elapsed: {:?}\", dt);\n}\n```\n\n### Mimalloc Global Allocator (optional)\n\nEnable the `mimalloc` feature to switch the global allocator for potential performance wins in allocation-heavy workloads:\n\n```toml\n[dependencies]\nproc-daemon = { version = \"0.9.0\", features = [\"mimalloc\"] }\n```\n\nNo code changes are required—`proc-daemon` sets the global allocator when the feature is enabled.\n\n### Lock-free Coordination (optional)\n\nEnable the `lockfree-coordination` feature to use a lock-free MPMC channel for coordination. This exposes a small channel facade and optional subsystem events for state changes.\n\n```toml\n[dependencies]\nproc-daemon = { version = \"0.9.0\", features = [\"lockfree-coordination\"] }\n```\n\nAPIs:\n\n- `proc_daemon::coord::chan::{unbounded, try_recv}` — Uniform API over `crossbeam-channel` (enabled) or `std::sync::mpsc` (fallback).\n- `SubsystemManager::enable_events()` and `SubsystemManager::try_next_event()` — non-blocking event polling.\n- `SubsystemManager::subscribe_events()` — get a `Receiver\u003cSubsystemEvent\u003e` to poll from another task when events are enabled.\n\nEvent type:\n\n```text\nSubsystemEvent::StateChanged { id, name, state, at }\n```\n\n### Multi-Subsystem Daemon\n\n```rust\nuse proc_daemon::{Daemon, Config, Subsystem, ShutdownHandle, RestartPolicy};\nuse std::pin::Pin;\nuse std::future::Future;\nuse std::time::Duration;\n\n// Define a custom subsystem\nstruct HttpServer {\n    port: u16,\n}\n\nimpl Subsystem for HttpServer {\n    fn run(\u0026self, mut shutdown: ShutdownHandle) -\u003e Pin\u003cBox\u003cdyn Future\u003cOutput = proc_daemon::Result\u003c()\u003e\u003e + Send\u003e\u003e {\n        let port = self.port;\n        Box::pin(async move {\n            tracing::info!(\"HTTP server starting on port {}\", port);\n            \n            loop {\n                tokio::select! {\n                    _ = shutdown.cancelled() =\u003e {\n                        tracing::info!(\"HTTP server shutting down\");\n                        break;\n                    }\n                    _ = tokio::time::sleep(Duration::from_millis(100)) =\u003e {\n                        // Handle HTTP requests here\n                    }\n                }\n            }\n            \n            Ok(())\n        })\n    }\n\n    fn name(\u0026self) -\u003e \u0026str {\n        \"http_server\"\n    }\n\n    fn restart_policy(\u0026self) -\u003e RestartPolicy {\n        RestartPolicy::ExponentialBackoff {\n            initial_delay: Duration::from_secs(1),\n            max_delay: Duration::from_secs(60),\n            max_attempts: 5,\n        }\n    }\n}\n\nasync fn background_worker(mut shutdown: ShutdownHandle) -\u003e proc_daemon::Result\u003c()\u003e {\n    while !shutdown.is_shutdown() {\n        tokio::select! {\n            _ = shutdown.cancelled() =\u003e break,\n            _ = tokio::time::sleep(Duration::from_secs(5)) =\u003e {\n                tracing::info!(\"Background work completed\");\n            }\n        }\n    }\n    Ok(())\n}\n\n#[tokio::main]\nasync fn main() -\u003e proc_daemon::Result\u003c()\u003e {\n    let config = Config::builder()\n        .name(\"multi-subsystem-daemon\")\n        .shutdown_timeout(Duration::from_secs(30))\n        .worker_threads(4)\n        .build()?;\n\n    Daemon::builder(config)\n        .with_subsystem(HttpServer { port: 8080 })\n        .with_task(\"background_worker\", background_worker)\n        .run()\n        .await\n}\n```\n\n## Configuration\n\n### Programmatic Configuration\n\n```rust\nuse proc_daemon::{Config, LogLevel};\nuse std::time::Duration;\n\nlet config = Config::builder()\n    .name(\"my-daemon\")\n    .log_level(LogLevel::Info)\n    .json_logging(true)\n    .shutdown_timeout(Duration::from_secs(30))\n    .worker_threads(8)\n    .enable_metrics(true)\n    .hot_reload(true)\n    .build()?;\n```\n\n### File Configuration (TOML)\n\nCreate a `daemon.toml` file:\n\n```toml\nname = \"my-production-daemon\"\n\n[logging]\nlevel = \"info\"\njson = false\ncolor = true\nfile = \"/var/log/my-daemon.log\"\n\n[shutdown]\ntimeout_ms = 30000\nforce_timeout_ms = 45000\nkill_timeout_ms = 60000\n\n[performance]\nworker_threads = 0  # auto-detect\nthread_pinning = false\nmemory_pool_size = 1048576\nnuma_aware = false\nlock_free = true\n\n[monitoring]\nenable_metrics = true\nmetrics_interval_ms = 1000\nhealth_checks = true\n```\n\nLoad the configuration:\n\n```rust\nlet config = Config::load_from_file(\"daemon.toml\")?;\n```\n\n### Environment Variables\n\nAll configuration options can be overridden with environment variables using the `DAEMON_` prefix:\n\n```bash\nexport DAEMON_NAME=\"env-daemon\"\nexport DAEMON_LOGGING_LEVEL=\"debug\"\nexport DAEMON_SHUTDOWN_TIMEOUT_MS=\"60000\"\nexport DAEMON_PERFORMANCE_WORKER_THREADS=\"16\"\n```\n\n## Advanced Usage\n\n### Custom Subsystems with Health Checks\n\n```rust\nstruct DatabasePool {\n    connections: Arc\u003cAtomicUsize\u003e,\n}\n\nimpl Subsystem for DatabasePool {\n    fn run(\u0026self, mut shutdown: ShutdownHandle) -\u003e Pin\u003cBox\u003cdyn Future\u003cOutput = proc_daemon::Result\u003c()\u003e\u003e + Send\u003e\u003e {\n        let connections = Arc::clone(\u0026self.connections);\n        Box::pin(async move {\n            // Database pool management logic\n            Ok(())\n        })\n    }\n\n    fn name(\u0026self) -\u003e \u0026str {\n        \"database_pool\"\n    }\n\n    fn health_check(\u0026self) -\u003e Option\u003cBox\u003cdyn Fn() -\u003e bool + Send + Sync\u003e\u003e {\n        let connections = Arc::clone(\u0026self.connections);\n        Some(Box::new(move || {\n            connections.load(Ordering::Acquire) \u003e 0\n        }))\n    }\n}\n```\n\n### Metrics Collection\n\n```rust\n#[cfg(feature = \"metrics\")]\nuse proc_daemon::metrics::MetricsCollector;\n\nlet collector = MetricsCollector::new();\n\n// Increment counters\ncollector.increment_counter(\"requests_total\", 1);\n\n// Set gauge values\ncollector.set_gauge(\"active_connections\", 42);\n\n// Record timing histograms\ncollector.record_histogram(\"request_duration\", Duration::from_millis(150));\n\n// Get metrics snapshot\nlet snapshot = collector.get_metrics();\nprintln!(\"Uptime: {:?}\", snapshot.uptime);\n```\n\n### Signal Handling Configuration\n\n```rust\nuse proc_daemon::signal::SignalConfig;\n\nlet signal_config = SignalConfig::new()\n    .with_sighup()  // Enable SIGHUP handling\n    .without_sigint()  // Disable SIGINT\n    .with_custom_handler(12, \"Custom signal\");\n\nDaemon::builder(config)\n    .with_signal_config(signal_config)\n    .run()\n    .await\n```\n\n## Architecture\n\n### Zero-Copy Design\n\nproc-daemon is built around zero-copy principles:\n\n- **Arc-based sharing**: Configuration and state shared via `Arc` to avoid cloning\n- **Lock-free coordination**: Uses atomic operations and lock-free data structures\n- **Memory pooling**: Pre-allocated memory pools for high-frequency operations\n- **Efficient serialization**: Direct memory mapping for configuration loading\n\n### Subsystem Lifecycle\n\n```mermaid\ngraph TD\n    A[Register] --\u003e B[Starting]\n    B --\u003e C[Running]\n    C --\u003e D[Health Check]\n    D --\u003e C\n    C --\u003e E[Stopping]\n    E --\u003e F[Stopped]\n    F --\u003e G[Restart?]\n    G --\u003e|Yes| B\n    G --\u003e|No| H[Removed]\n    C --\u003e I[Failed]\n    I --\u003e G\n```\n\n### Shutdown Coordination\n\nproc-daemon implements a sophisticated shutdown coordination system:\n\n1. **Signal Reception**: Cross-platform signal handling\n2. **Graceful Notification**: All subsystems notified simultaneously\n3. **Coordinated Shutdown**: Subsystems shut down in dependency order\n4. **Timeout Management**: Configurable graceful and force timeouts\n5. **Resource Cleanup**: Automatic cleanup of resources and handles\n\n## Testing\n\nRun the test suite:\n\n```bash\n# Run all tests\ncargo test\n\n# Run tests with all features\ncargo test --all-features\n\n# Run integration tests\ncargo test --test integration\n\n# Run benchmarks\ncargo bench\n```\n\n\n\u003chr\u003e\n\u003cbr\u003e\n\n\n### Hot-Reload (optional)\n\nEnable `config-watch` to live-reload `daemon.toml` at runtime (optionally combine with `mmap-config` for fast TOML loading). The daemon maintains a live snapshot accessible via `Daemon::config_snapshot()`.\n\nRun the example:\n\n```bash\ncargo run --example hot_reload --features \"tokio config-watch toml mmap-config\"\n```\n\nNotes:\n\n- Place `daemon.toml` in the working directory.\n- The watcher starts automatically when `Config.hot_reload = true`.\n\n\u003chr\u003e\n\u003cbr\u003e\n\n## PERFORMANCE\nproc-daemon is designed for extreme performance:\n\n\n### Running Benchmarks\n```bash\ncargo bench\n```\n\n### Typical performance:\n- **Daemon Creation**: ~1-5μs\n- **Subsystem Registration**: ~500ns per subsystem\n- **Shutdown Coordination**: ~10-50μs for 100 subsystems\n- **Signal Handling**: ~100ns latency\n- **Metrics Collection**: ~10ns per operation\n\n\n### Memory Usage\n- **Base daemon**: ~1-2MB\n- **Per subsystem**: ~4-8KB\n- **Configuration**: ~1-4KB\n- **Signal handling**: ~512B\n \n\u003c/br\u003e\n\u003c/br\u003e\n\n**🔗 See [`PERFORMANCE.md`](./docs/PERFORMANCE.md) for up-to-date benchmarks, metrics, and version-over-version improvements.**\n\n\n\u003cbr\u003e\n\u003chr\u003e\n\u003cbr\u003e\n\n## Security\n- **Memory Safety**: 100% safe Rust with no unsafe code\n- **Signal Safety**: Async signal handling prevents race conditions  \n- **Resource Limits**: Configurable limits prevent resource exhaustion\n- **Graceful Degradation**: Continues operating even when subsystems fail\n\n### Development Setup\n\n```bash\ngit clone https://github.com/jamesgober/proc-daemon.git\ncd proc-daemon\ncargo build --all-features\ncargo test --all-features\n```\n\n\n\u003c!-- API REFERENCE\n############################################# --\u003e\n\u003chr\u003e\n\u003cbr\u003e\n\u003ch3\u003eDocumentation:\u003c/h3\u003e\n\u003cul\u003e\n    \u003cli\u003e\u003ca href=\"./docs/API.md\"\u003e\u003cb\u003eAPI Reference\u003c/b\u003e\u003c/a\u003e Complete documentation and examples.\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"./docs/PRINCIPLES.md\"\u003e\u003cb\u003eCode Principles\u003c/b\u003e\u003c/a\u003e guidelines for contribution \u0026amp; development.\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003cbr\u003e\n\u003chr\u003e\n\n\n\u003c!-- API REFERENCE\n############################################# --\u003e\n\n### Acknowledgments\n- Inspired by production daemon patterns from high-scale deployments\n- Built on the excellent Rust async ecosystem (Tokio, async-std)\n- Configuration management powered by [Figment](https://github.com/SergioBenitez/Figment)\n- Logging via the [tracing](https://github.com/tokio-rs/tracing) ecosystem\n\n\u003chr\u003e\n\u003cbr\u003e\n\u003cbr\u003e\n\n\u003ch2 align=\"center\"\u003e\n    DEVELOPMENT \u0026amp; CONTRIBUTION\n\u003c/h2\u003e\n\nWe welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg width=\"72px\" src=\"./media/rust.svg\" alt=\"Rust Logo\"\u003e\n    \u003cbr\u003e\u003csup\u003e\u003cb\u003eBuilt with Rust.\u003c/b\u003e\u003c/sup\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n\n\u003c!-- LICENSE\n############################################# --\u003e\n\u003cdiv id=\"license\"\u003e\n    \u003ch2\u003e⚖️ License\u003c/h2\u003e\n    \u003cp\u003eLicensed under the \u003cb\u003eApache License\u003c/b\u003e, version 2.0 (the \u003cb\u003e\"License\"\u003c/b\u003e); you may not use this software, including, but not limited to the source code, media files, ideas, techniques, or any other associated property or concept belonging to, associated with, or otherwise packaged with this software except in compliance with the \u003cb\u003eLicense\u003c/b\u003e.\u003c/p\u003e\n    \u003cp\u003eYou may obtain a copy of the \u003cb\u003eLicense\u003c/b\u003e at: \u003ca href=\"http://www.apache.org/licenses/LICENSE-2.0\" title=\"Apache-2.0 License\" target=\"_blank\"\u003ehttp://www.apache.org/licenses/LICENSE-2.0\u003c/a\u003e.\u003c/p\u003e\n    \u003cp\u003eUnless required by applicable law or agreed to in writing, software distributed under the \u003cb\u003eLicense\u003c/b\u003e is distributed on an \"\u003cb\u003eAS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND\u003c/b\u003e, either express or implied.\u003c/p\u003e\n    \u003cp\u003eSee the \u003ca href=\"./LICENSE\" title=\"Software License file\"\u003eLICENSE\u003c/a\u003e file included with this project for the specific language governing permissions and limitations under the \u003cb\u003eLicense\u003c/b\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\n\u003c!-- COPYRIGHT\n############################################# --\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ch2\u003e\u003c/h2\u003e\n  \u003csup\u003eCOPYRIGHT \u003csmall\u003e\u0026copy;\u003c/small\u003e 2025 \u003cstrong\u003eJAMES GOBER.\u003c/strong\u003e\u003c/sup\u003e\n\u003c/div\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamesgober%2Fproc-daemon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjamesgober%2Fproc-daemon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamesgober%2Fproc-daemon/lists"}