| + |
# `radicle-job`
|
| + |
|
| + |
A crate for all† your automated job needs on the [Radicle
|
| + |
Network](https://radicle.xyz).
|
| + |
|
| + |
†: _well maybe almost all._
|
| + |
|
| + |
## Overview
|
| + |
|
| + |
`radicle-job` provides a collaborative framework for managing automated tasks
|
| + |
across the Radicle peer-to-peer network. Multiple nodes can pick up and execute
|
| + |
jobs (like CI/CD pipelines) for any given Git commit, with results synchronized
|
| + |
across the network using Radicle's Collaborative Objects (COBs).
|
| + |
|
| + |
### Key Features
|
| + |
|
| + |
- **Decentralized Execution**: Any node in the network can pick up and run jobs
|
| + |
- **Collaborative Tracking**: Multiple nodes can contribute runs for the same
|
| + |
job
|
| + |
- **Rich Status Reporting**: Track job lifecycle from start to completion with
|
| + |
success/failure reasons
|
| + |
- **External Log Integration**: Link to external logging services via URLs
|
| + |
- **Git Integration**: Jobs are tied to specific Git commits using OIDs
|
| + |
|
| + |
## Key Concepts
|
| + |
|
| + |
- **Job**: Represents an automated task for a specific Git commit that can be
|
| + |
executed by multiple nodes
|
| + |
- **Run**: A single execution attempt of a job by a particular node, identified
|
| + |
by a UUID
|
| + |
- **Status**: The current state of a run (`Started`, `Finished(Succeeded)`,
|
| + |
`Finished(Failed)`)
|
| + |
- **COB (Collaborative Object)**: The underlying Radicle primitive that enables
|
| + |
decentralized synchronization of job data
|
| + |
|
| + |
## Installation
|
| + |
|
| + |
Add this to your `Cargo.toml`:
|
| + |
|
| + |
```toml
|
| + |
[dependencies]
|
| + |
radicle-job = "0.1"
|
| + |
radicle >= "0.15" # Required for core Radicle functionality
|
| + |
```
|
| + |
|
| + |
This crate is designed to work seamlessly with the
|
| + |
[`radicle`](https://crates.io/crates/radicle) ecosystem.
|
| + |
|
| + |
## Quick Start
|
| + |
|
| + |
### Creating and Managing Jobs
|
| + |
|
| + |
```rust
|
| + |
use radicle_job::{Jobs, Reason};
|
| + |
use radicle::git::Oid;
|
| + |
use url::Url;
|
| + |
use uuid::Uuid;
|
| + |
|
| + |
// Open the jobs store for a repository
|
| + |
let mut jobs = Jobs::open(&repo)?;
|
| + |
|
| + |
// Create a new job for a specific commit
|
| + |
let commit_oid = /* your commit OID */;
|
| + |
let mut job = jobs.create(commit_oid, &signer)?;
|
| + |
|
| + |
// Node starts a run
|
| + |
let run_id = Uuid::new_v4();
|
| + |
let log_url = Url::parse("https://ci.example.com/logs/run-123")?;
|
| + |
job.run(run_id, log_url, &signer)?;
|
| + |
|
| + |
// Node reports completion
|
| + |
job.finish(run_id, Reason::Succeeded, &signer)?;
|
| + |
```
|
| + |
|
| + |
### Querying Job Status
|
| + |
|
| + |
```rust
|
| + |
// Get all runs that are currently in progress
|
| + |
let started_runs = job.started();
|
| + |
|
| + |
// Get successful runs from all nodes
|
| + |
let successful_runs = job.succeeded();
|
| + |
|
| + |
// Get the latest run from a specific node
|
| + |
if let Some((uuid, run)) = job.latest_of(&node_id) {
|
| + |
println!("Latest run: {} - Status: {:?}", uuid, run.status());
|
| + |
println!("Logs available at: {}", run.log());
|
| + |
}
|
| + |
|
| + |
// Partition runs by status
|
| + |
let all_nodes_status = job.partition();
|
| + |
for (node_id, (started, succeeded, failed)) in all_nodes_status {
|
| + |
println!("Node {}: {} started, {} succeeded, {} failed",
|
| + |
node_id, started.len(), succeeded.len(), failed.len());
|
| + |
}
|
| + |
```
|
| + |
|
| + |
## Use Cases
|
| + |
|
| + |
### Continuous Integration
|
| + |
|
| + |
The primary use case is distributed CI execution:
|
| + |
|
| + |
1. A developer creates a patch
|
| + |
2. The job is broadcast to the network
|
| + |
3. Available CI nodes pick up the job and execute tests
|
| + |
4. Results are reported back with logs and status
|
| + |
5. The developer can see which nodes ran CI and their results
|
| + |
|
| + |
### Future Possibilities
|
| + |
|
| + |
- **Continuous Deployment**: Automated deployment pipelines
|
| + |
- **Code Analysis**: Static analysis, security scanning, performance
|
| + |
benchmarking
|
| + |
- **Marketplace**: Nodes could offer specialized compute resources for different
|
| + |
job types
|
| + |
|
| + |
## API Overview
|
| + |
|
| + |
### Core Types
|
| + |
|
| + |
- **`Jobs<R>`**: The main store for managing jobs in a repository
|
| + |
- **`Job`**: A read-only view of a job and its runs across all nodes
|
| + |
- **`JobMut`**: A mutable job handle for adding runs and updating status
|
| + |
- **`Run`**: Represents a single execution attempt with status and log URL
|
| + |
- **`Runs`**: A collection of runs with insertion-order iteration
|
| + |
|
| + |
### Key Methods
|
| + |
|
| + |
- **`Jobs::create()`**: Create a new job for a commit
|
| + |
- **`Jobs::get()`** / **`Jobs::get_mut()`**: Retrieve existing jobs
|
| + |
- **`JobMut::run()`**: Start a new run
|
| + |
- **`JobMut::finish()`**: Mark a run as completed
|
| + |
- **`Job::latest()`**: Get the most recent run
|
| + |
|
| + |
## Collaborative Nature
|
| + |
|
| + |
Jobs in `radicle-job` are inherently collaborative:
|
| + |
|
| + |
- **Multiple Executors**: Many nodes can run the same job independently
|
| + |
- **Decentralized Results**: Each node reports its own results without requiring
|
| + |
coordination
|
| + |
- **Automatic Synchronization**: The Radicle protocol handles data
|
| + |
synchronization across nodes
|
| + |
- **No Consensus Required**: This crate doesn't enforce consensus on results —
|
| + |
that's left to higher-level applications
|
| + |
|
| + |
This design enables resilient, distributed job execution where no single point
|
| + |
of failure can prevent job completion.
|
| + |
|
| + |
## License
|
| + |
|
| + |
This project is licensed under the [MIT License](LICENSE-MIT) or [Apache License
|
| + |
2.0](LICENSE-APACHE) at your option.
|
| + |
|
| + |
## Related Projects
|
| + |
|
| + |
- [`radicle`](https://crates.io/crates/radicle) - Core Radicle protocol
|
| + |
implementation
|
| + |
- [`radicle-ci-broker`](https://crates.io/crates/radicle-ci-broker) - Radicle
|
| + |
library for brokering CI events
|