Skip to content

A Rust thread pool implementation like Java's ExecutorService

License

Notifications You must be signed in to change notification settings

yerlibilgin/executor-service

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

executor-service

cargo_build_workflow

Cargo Publish

A Java ExecutorService style thread pool implementation for Rust.

Creating a thread pool

Creating a thread pool with constant size

For many cases you might want to keep a constant sized pool to achieve incoming tasks in parallel. Below is a sample code to achieve that:

use executor_service::Executors;
///...
fn main() {
  let mut executor_service = Executors::new_fixed_thread_pool(10).expect("Failed to create the thread pool");
  //...
}

Creating a cached thread pool

If you don't want to deal with the size and want more threads as needed (e.g the threads are doing long jobs and you don't wanna wait) you can use a cached thread pool. . Below is a sample code to achieve that:

use executor_service::Executors;
///...
fn main() {
  let mut executor_service = Executors::new_cached_thread_pool(Some(5)).expect("Failed to create the thread pool");
  //...
}

The Some(5) is an optional parameter that provides an inital size to the pool. A maximum number of 150 threads can be given. If you set it to None, then the pool will an initial size of 10.

Executing a task without waiting for the result

If you want to post a task and not mind about the result, you can use 'ExecutorService::execute' as below:

use executor_service::Executors;
use std::thread::sleep;
use core::time::Duration;
use std::thread;

fn main() {
  let mut executor_service = Executors::new_fixed_thread_pool(2).expect("Failed to create the thread pool");

  let some_param = "Mr White";
  let res = executor_service.execute(move || {
    sleep(Duration::from_secs(1));
    println!("Hello {:} from thread {:}", some_param, thread::current().name().unwrap());
  }).expect("Failed to execute function");

  sleep(Duration::from_secs(3));
}

Executing a task and waiting for the result

Here is a sample, if you want to run a task on the pool and synchronously wait for the result:

use executor_service::Executors;
use std::thread::sleep;
use core::time::Duration;
fn main() {
  let mut executor_service = Executors::new_cached_thread_pool(None)
    .expect("Failed to create the thread pool");
  let some_param = "Mr White";
  let res = executor_service.submit_sync(move || {
    println!("Long computation started");
    sleep(Duration::from_secs(5));
    println!("Hello {:}", some_param);
    println!("Long computation finished");
    2
  }).expect("Failed to submit function");
  println!("Result: {:#?}", res);
  assert_eq!(res, 2);
}

Executing a task and getting an asynchronous result

Here is a sample, if you want to run a task on the pool and obtain a Future for the result:

use executor_service::Executors;
use std::thread::sleep;
use core::time::Duration;

fn main() {
  let mut executor_service = Executors::new_cached_thread_pool(Some(5)).expect("Failed to create the thread pool");
  let some_param = "Mr White";
  let the_future = executor_service.submit_async(Box::new(move || {
    sleep(Duration::from_secs(3));
    println!("Hello {:}", some_param);
    println!("Long lasting computation finished");
    "Some string result".to_string()
  })).expect("Failed to submit function");
  
  //Wait a bit more to see the future work.
  println!("Main thread wait for 5 seconds");
  sleep(Duration::from_secs(5));
  let res = the_future.get().expect("Couldn't get a result");
  println!("Result is {:}", &res);
  assert_eq!(&res, "Some string result");
}

You can safely send a Future through a channel to allow the result to be used elsewhere

I would appreciate contributions through pull requests. Thanks!

About

A Rust thread pool implementation like Java's ExecutorService

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages