Skip to content

Commit bdfdf84

Browse files
1 parent 3eb2718 commit bdfdf84

10 files changed

Lines changed: 6 additions & 168 deletions

File tree

Source/Library.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
1-
// @module Echo Crate
2-
// @description A high-performance, structured concurrency and task scheduling
3-
// library for Rust, built on top of `tokio` and a work-stealing queue. Echo is
4-
// designed to natively execute `Future`s, providing a robust runtime for
5-
// complex, asynchronous applications.
6-
//
7-
81
#![allow(non_snake_case, non_camel_case_types)]
92

10-
// --- Public API ---
3+
pub mod Queue;
114
pub mod Scheduler;
125
pub mod Task;
13-
14-
// --- Internal Implementation ---
15-
pub mod Queue;

Source/Queue/StealingQueue.rs

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
1-
// @module StealingQueue
2-
// @description A generic, priority-aware, work-stealing queue implementation.
3-
// This module is self-contained and can be used by any scheduler or application
4-
// to manage and distribute tasks of any type `T`.
5-
61
#![allow(non_snake_case, non_camel_case_types)]
72

83
use std::sync::Arc;
94

105
use crossbeam_deque::{Injector, Stealer, Worker};
116
use rand::seq::SliceRandom;
127

13-
// The task must have a way to specify its priority. We define a trait for this.
148
pub trait Prioritized {
159
type P: PartialEq + Eq + Copy;
1610

1711
fn GetPriority(&self) -> Self::P;
1812
}
1913

20-
// A simple enum for the library to use. The consumer's task must map to this.
2114
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2215
pub enum Priority {
2316
High,
@@ -27,58 +20,40 @@ pub enum Priority {
2720
Low,
2821
}
2922

30-
// The parts of the queue that can be safely shared across all threads.
3123
struct Share<T> {
32-
// High, Normal, Low
3324
Injector:(Injector<T>, Injector<T>, Injector<T>),
3425

35-
// High, Normal, Low
3626
Stealer:(Vec<Stealer<T>>, Vec<Stealer<T>>, Vec<Stealer<T>>),
3727
}
3828

39-
/// The public-facing work-stealing queue. It is generic over the task type `T`.
40-
/// This object is held by the task submitter.
4129
pub struct StealingQueue<T:Prioritized<P = Priority>> {
4230
Share:Arc<Share<T>>,
4331
}
4432

45-
/// A context object that contains everything a single worker thread needs to
46-
/// operate. This includes its own private, thread-local deques.
4733
pub struct Context<T> {
4834
pub Identifier:usize,
4935

50-
// High, Normal, Low
5136
Local:(Worker<T>, Worker<T>, Worker<T>),
5237

5338
Share:Arc<Share<T>>,
5439
}
5540

5641
impl<T:Prioritized<P = Priority>> StealingQueue<T> {
57-
/// Creates a new work-stealing queue system.
58-
///
59-
/// Returns a tuple containing:
60-
/// 1. The `StealingQueue` for submitting tasks.
61-
/// 2. A `Vec` of `WorkerContext`s, one for each worker to be spawned.
6242
pub fn New(Count:usize) -> (Self, Vec<Context<T>>) {
6343
let mut High:Vec<Worker<T>> = Vec::with_capacity(Count);
6444

6545
let mut Normal:Vec<Worker<T>> = Vec::with_capacity(Count);
6646

6747
let mut Low:Vec<Worker<T>> = Vec::with_capacity(Count);
6848

69-
// --- FIX: Use the documented API for creating Worker/Stealer pairs ---
7049
let StealerHigh:Vec<Stealer<T>> = (0..Count)
7150
.map(|_| {
72-
// 1. Create the Worker.
7351
let Worker = Worker::new_fifo();
7452

75-
// 2. Get its Stealer.
7653
let Stealer = Worker.stealer();
7754

78-
// 3. Store the Worker part.
7955
High.push(Worker);
8056

81-
// 4. Return the Stealer part.
8257
Stealer
8358
})
8459
.collect();
@@ -116,7 +91,6 @@ impl<T:Prioritized<P = Priority>> StealingQueue<T> {
11691
let mut Context = Vec::with_capacity(Count);
11792

11893
for Id in 0..Count {
119-
// We use remove(0) because we built the Vecs in order and need to consume them.
12094
Context.push(Context {
12195
Identifier:Id,
12296

@@ -131,8 +105,6 @@ impl<T:Prioritized<P = Priority>> StealingQueue<T> {
131105
(Queue, Context)
132106
}
133107

134-
/// Submits a new task to the queue.
135-
/// This is thread-safe and can be called from anywhere.
136108
pub fn Submit(&self, Task:T) {
137109
match Task.GetPriority() {
138110
Priority::High => self.Share.Injector.0.push(Task),
@@ -145,20 +117,14 @@ impl<T:Prioritized<P = Priority>> StealingQueue<T> {
145117
}
146118

147119
impl<T> Context<T> {
148-
/// Finds the next available task for this worker.
149-
/// Implements the full priority-aware, work-stealing logic.
150120
pub fn NextTask(&self) -> Option<T> {
151-
// Pop from local High
152-
self.Local.0.pop()
153-
// Pop from local Normal
121+
self.Local
122+
.0
123+
.pop()
154124
.or_else(|| self.Local.1.pop())
155-
// Pop from local Low
156125
.or_else(|| self.Local.2.pop())
157-
// Steal High
158126
.or_else(|| self.Steal(&self.Share.Injector.0, &self.Share.Stealer.0, &self.Local.0))
159-
// Steal Normal
160127
.or_else(|| self.Steal(&self.Share.Injector.1, &self.Share.Stealer.1, &self.Local.1))
161-
// Steal Low
162128
.or_else(|| self.Steal(&self.Share.Injector.2, &self.Share.Stealer.2, &self.Local.2))
163129
}
164130

Source/Queue/mod.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,3 @@
1-
// @module queue
2-
// @description This module provides the high-performance, concurrent queueing
3-
// implementations used by the Echo scheduler. These are internal components
4-
// of the library.
5-
//
6-
71
#![allow(non_snake_case, non_camel_case_types)]
82

93
pub mod StealingQueue;
10-
11-
// Re-exports the `StealingQueue` for use within the `Echo` crate, but keeps it
12-
// private from external consumers.
13-
// @see StealingQueue
14-
//
15-
// pub use self::StealingQueue::StealingQueue;

Source/Scheduler/Scheduler.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ use crate::{
1717
Task::{Priority::Enum as PriorityEnum, Task::Struct as TaskStruct},
1818
};
1919

20-
/// Manages a pool of worker threads and a work-stealing queue to execute tasks
21-
/// efficiently. This struct is the public-facing API of the Echo scheduler.
2220
pub struct Scheduler {
2321
Queue:StealingQueueStruct<TaskStruct>,
2422

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,29 @@
1-
// Defines the fluent builder for creating and configuring a `Scheduler`
2-
// instance.
3-
41
use std::collections::HashMap;
52

63
use log::warn;
74

85
use super::Scheduler::Scheduler;
96

10-
/// An enum to define concurrency limits for named queues.
117
#[derive(Debug, Clone, Copy)]
128
pub enum Concurrency {
13-
/// Specifies a maximum number of concurrent tasks for a queue.
149
Limit(usize),
1510

16-
/// Allows an unlimited number of concurrent tasks for a queue.
1711
Unlimited,
1812
}
1913

20-
/// A fluent builder for creating a `Scheduler`.
21-
///
22-
/// This pattern provides a clear and readable API for configuring complex
23-
/// objects, such as a multi-queue, multi-threaded scheduler, before they are
24-
/// constructed.
2514
pub struct SchedulerBuilder {
2615
WorkerCount:usize,
2716

28-
/// Stores the configuration for named queues.
2917
QueueConfiguration:HashMap<String, Concurrency>,
3018
}
3119

3220
impl SchedulerBuilder {
33-
/// Creates a new `SchedulerBuilder` with default settings.
34-
///
35-
/// By default, the worker count is set to the number of logical CPUs on the
36-
/// system, with a minimum of 2.
3721
pub fn New() -> Self {
3822
let DefaultWorkerCount = num_cpus::get().max(2);
3923

4024
Self { WorkerCount:DefaultWorkerCount, QueueConfiguration:HashMap::new() }
4125
}
4226

43-
/// Sets the total number of worker threads for the scheduler's pool.
44-
///
45-
/// # Arguments
46-
/// * `WorkerCount` - The desired number of workers. If `0`, it defaults
47-
/// to the number of logical CPUs on the system.
4827
pub fn WithWorkerCount(mut self, WorkerCount:usize) -> Self {
4928
if WorkerCount == 0 {
5029
warn!("[SchedulerBuilder] Worker count of 0 is invalid. Defaulting to number of logical CPUs.");
@@ -57,31 +36,15 @@ impl SchedulerBuilder {
5736
self
5837
}
5938

60-
/// Configures a named queue with a specific concurrency limit.
61-
/// Tasks can later be submitted to this specific queue.
62-
///
63-
/// # Arguments
64-
/// * `QueueName` - The name of the queue (e.g., "DiskIO", "Network").
65-
/// * `ConcurrencyLimit` - The concurrency configuration for this queue.
6639
pub fn WithQueue(mut self, QueueName:&str, ConcurrencyLimit:Concurrency) -> Self {
6740
self.QueueConfiguration.insert(QueueName.to_string(), ConcurrencyLimit);
6841

6942
self
7043
}
7144

72-
/// Builds and starts the `Scheduler` with the specified configuration.
73-
/// This consumes the builder.
74-
///
75-
/// # Returns
76-
/// A new, running `Scheduler` instance.
77-
pub fn Build(self) -> Scheduler {
78-
// The Scheduler's internal `Start` method will receive this
79-
// configuration and set up the corresponding queues and worker logic.
80-
Scheduler::Start(self.WorkerCount, self.QueueConfiguration)
81-
}
45+
pub fn Build(self) -> Scheduler { Scheduler::Start(self.WorkerCount, self.QueueConfiguration) }
8246
}
8347

8448
impl Default for SchedulerBuilder {
85-
/// Provides a default `SchedulerBuilder` instance.
8649
fn default() -> Self { Self::New() }
8750
}

Source/Scheduler/Worker.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ pub struct Worker {
1717
impl Worker {
1818
pub fn New(Context:Context<TaskStruct>, IsRunning:Arc<AtomicBool>) -> Self { Self { Context, Running:IsRunning } }
1919

20-
/// The main execution loop for the worker.
21-
pub async fn Run(&self) {
20+
pub async fn Run(self) {
2221
trace!("[Worker {}] Starting execution loop.", self.Context.Identifier);
2322

2423
while self.Running.load(Ordering::Relaxed) {

Source/Scheduler/mod.rs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,5 @@
1-
// @module scheduler
2-
// @description This module defines the core public API for the Echo task
3-
// scheduler. It provides the `SchedulerBuilder` for configuration and the
4-
// `Scheduler` itself for managing the worker pool and submitting tasks.
5-
//
6-
71
#![allow(non_snake_case, non_camel_case_types)]
82

9-
// --- Sub-modules (Internal Implementation) ---
103
pub mod Scheduler;
114
pub mod SchedulerBuilder;
125
pub mod Worker;
13-
14-
// --- Public Re-exports ---
15-
16-
// The main scheduler struct that manages the worker pool and task execution.
17-
// @see Scheduler
18-
//
19-
// pub use self::Scheduler::Scheduler;
20-
// The fluent builder for creating and configuring a `Scheduler` instance.
21-
// This is the primary entry point for using the Echo library.
22-
// @see SchedulerBuilder
23-
// pub use self::SchedulerBuilder::SchedulerBuilder;

Source/Task/Priority.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,8 @@
1-
/// @module Priority
2-
/// @description Defines the `Priority` enum for task scheduling within the Echo
3-
/// system.
4-
5-
/// Represents the priority of a task to be executed by the scheduler.
6-
/// This enum implements `Ord`, allowing tasks to be sorted by priority.
7-
/// Schedulers and workers can use this to ensure that high-priority,
8-
/// user-facing tasks are executed before long-running background tasks.
91
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
102
pub enum Enum {
11-
/// For background tasks that are not time-sensitive, such as logging,
12-
/// telemetry, or non-critical file indexing.
133
Low,
144

15-
/// The default priority for most standard operations.
165
Normal,
176

18-
/// For tasks that directly impact perceived performance or are critical to
19-
/// responsiveness, such as handling user input, providing code completions,
20-
/// or responding to a "Go to Definition" request.
217
High,
228
}

Source/Task/Task.rs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,17 @@
11
use std::{future::Future, pin::Pin};
22

3-
/// @module Task
4-
/// @description Defines the `Task` struct, which is the internal unit of work
5-
/// for the Echo scheduler.
63
use super::Priority::Enum;
74
use crate::Queue::StealingQueue::{Prioritized, Priority};
85

9-
/// A type alias for a boxed, send-able, pinned future that returns no value.
10-
/// This is the standard way to handle dynamic, async operations in Rust.
116
type BoxedFuture = Pin<Box<dyn Future<Output = ()> + Send>>;
127

13-
/// Represents a single, schedulable unit of work.
14-
///
15-
/// It encapsulates an asynchronous operation (`Future`) along with metadata,
16-
///
17-
/// such as its `Priority`, that the scheduler can use to determine execution
18-
/// order.
198
pub struct Struct {
20-
/// The asynchronous operation to be executed by a worker.
219
pub Future:BoxedFuture,
2210

23-
/// The priority level of this task, used by the scheduler's queue.
2411
pub Priority:Enum,
2512
}
2613

2714
impl Struct {
28-
/// Creates a new `Task` from a given future and priority level.
29-
///
30-
/// @param FutureInstance - Any `Future` that is `Send` and has a `'static`
31-
/// lifetime. The future is automatically boxed and pinned.
32-
/// @param PriorityValue - The `Priority` of the task.
3315
pub fn New<F>(FutureInstance:F, PriorityValue:Enum) -> Self
3416
where
3517
F: Future<Output = ()> + Send + 'static, {

Source/Task/mod.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,4 @@
1-
// @module task
2-
// @description This module defines the core data structures for the Echo
3-
// scheduler, including the `Task` itself and its `Priority`.
4-
//
5-
61
#![allow(non_snake_case, non_camel_case_types)]
72

8-
// --- Sub-modules ---
93
pub mod Priority;
104
pub mod Task;
11-
12-
// --- Public Re-exports ---
13-
14-
// The enum representing the priority of a task.
15-
// @see Priority
16-
//
17-
// pub use self::Priority::Priority;
18-
// The struct representing a single unit of work for the scheduler.
19-
// @see Task
20-
// pub use self::Task::Task;

0 commit comments

Comments
 (0)