A load balanced threadpool.

Overview

sangfroid

ci-tests rustdoc FOSSA Status

A load balanced thread pool.

How does it work?

We maintain a binary heap of worker threads. Worker threads are ordered by the number of pending tasks associated with it. Whenever a new job is scheduled, we pick up the least loaded worker and dispatch the job to it. We update its pending task count and restore the heap accordingly.

When a worker is done executing a job, it sends its Uid to the done channel. A background balancer thread continuously receives on this channel until it receives a None value. When the balancer thread receives an uid, it looks up the associated worker from the worker pool heap, decrements it's load and restores the heap accordingly.

All communication to and from threads is done via channels. We use locks as sparingly as possible. More specifically, we only lock on the binary heap in the thread pool with a Mutex since it is also used by the balancer thread. We stay true to the concept:

Do not communicate by sharing memory; instead, share memory by communicating.

//! example 0: basic api usage
let thread_pool = ThreadPool::<u8, u8>::new(1);

let (job, result_src) = Job::with_result_sink(|x| x * 2, 2);
thread_pool.schedule(job).expect("job not scheduled");
assert_eq!(result_src.recv().unwrap(), 4);

//! example 1: with shared resource
let shared_hashmap = Arc::new(RwLock::new(HashMap::<u8, u8>::new()));
const PLACE_HOLDER: u8 = 5;

assert_eq!(shared_hashmap.read().unwrap().get(&1), None);

let thread_pool = ThreadPool::<((u8, u8), Arc<RwLock<HashMap<u8, u8>>>), ()>::new(2);

let job = Job::new(
    |((key, value), shared_map)| {
        shared_map.write().unwrap().insert(key, value);
    },
    ((1, 2), Arc::clone(&shared_hashmap)),
);
thread_pool.schedule(job).expect("job not scheduled");

let job = Job::new(
    |((key, _), shared_map)| {
        shared_map.read().unwrap().get(&key);
    },
    ((1, PLACE_HOLDER), Arc::clone(&shared_hashmap)),
);
thread_pool.schedule(job).expect("job not scheduled");

// wait some time for writers to finish
thread::sleep(Duration::from_secs(1));

assert_eq!(shared_hashmap.read().unwrap().get(&1), Some(&2));

Refer to API documentation for more details.

Why did you make this?

This crate was inspired from the load balancer described in the excellent "Concurrency is not Parallelism" talk by Rob Pike.

Well, did you learn anything?

Thread management and synchorization in Rust. I was also able to improve my ownership concepts. This was a great project for applying the knowledge I assimilated from the aforementioned talk and improve my ability to express my ideas in Rust.

Dependencies

This does not depend on any third party crates. The only dependency is the bheap crate, which I wrote for managing the workers.

Usage

This is a library crate. You may include it in your Cargo.toml as follows:

[dependencies]
sangfroid = { git = "https://github.com/arindas/sangfroid" }

Why the weird name?

sangfroid /sɒ̃ˈfrwɑː/ noun; composure or coolness shown in danger or under trying circumstances.

I found it fitting.

LICENSE

sangfroid is licensed under the MIT License. See LICENSE for the full license text.

FOSSA Status

You might also like...
PgBouncer rewritten in Rust, with sharding, load balancing and failover support
PgBouncer rewritten in Rust, with sharding, load balancing and failover support

PgCat Meow. PgBouncer rewritten in Rust, with sharding, load balancing and failover support. Alpha: don't use in production just yet. Local developmen

Handle some lichess.org/tournament load with Rust, while learning Rust

lila-http Take some of the HTTP load away from lila. WIP! Arena tournaments Clients connected to a tournament page request new data about the tourname

Deploy your Solana programs during high load.

solana-deployer IMPORTANT: There is a known bug with the current program that will be fixed soon. In the meantime you should deploy from Solana Playgr

Web3-proxy: a fast caching and load balancing proxy for web3 (Ethereum or similar) JsonRPC servers.

web3-proxy Web3-proxy is a fast caching and load balancing proxy for web3 (Ethereum or similar) JsonRPC servers. Signed transactions (eth_sendRawTrans

Layer 4 load balancer with dynamic configuration loading
Layer 4 load balancer with dynamic configuration loading

Convey Layer 4 load balancer with dynamic configuration loading featuring proxy, passthrough and direct server return modes Features Stats page (at /s

A demo app covering building an eBPF load-balancer in Rust

eBPF Rust UDP LoadBalancer Demo This is an example of creating a UDP load-balancer in Rust as an eXpress Data Path (XDP) type eBPF program using the a

📮 load, write, and copy remote and local assets

axoasset This library offers read, write, and copy functions, for local and remote assets given a string that contains a relative or absolute local pa

Load and resolve Cargo configuration.

cargo-config2 Load and resolve Cargo configuration. This library is intended to accurately emulate the actual behavior of Cargo configuration, for exa

An atomic save/load system for Bevy Game Engine.

☢️ Bevy Atomic Save An atomic save/load system for Bevy. Features Save and load a World into a RON file on disk Control which entities should particip

A save/load framework for Bevy game engine.

💾 Moonshine Save A save/load framework for Bevy game engine. Overview In Bevy, it is possible to serialize and deserialize a World using a DynamicSce

The High Performance Proxy/Load Balancer
The High Performance Proxy/Load Balancer

Silverwind-The Next Generation High-Performance Proxy English 简体中文 The Silverwind is a high-performance reverse proxy/load balancer. And it could be a

The true next-gen L7 minecraft proxy and load balancer. Built in Rust.

Lure The true next-gen L7 minecraft proxy and load balancer. Built in Rust, Tokio and Valence. Why? Rust is a powerful programming language and a grea

A simple code that will load a shellcode directly into RAM memory in a new process
A simple code that will load a shellcode directly into RAM memory in a new process

「 🔄 」About RustSCLoader RustSCLoader is a simple code that has the intention of loading a shellcode directly into RAM memory in a new process that wi

A secure and efficient gateway for interacting with OpenAI's API, featuring load balancing, user request handling without individual API keys, and global access control.

OpenAI Hub OpenAI Hub is a comprehensive and robust tool designed to streamline and enhance your interaction with OpenAI's API. It features an innovat

Server load testing CLI tool 🏋️

🔥 Rhea A Server Load Testing Tool Rhea is a powerful and easy-to-use command-line tool written in Rust for load testing servers. It allows you to sim

Comments
Releases(v0.1.0)
Owner
Arindam Das
Specializes in Deep Learning model serving and AI SaaS at scale. Experienced in distributed system design, architecture, and deployment.
Arindam Das
A balanced unbounded interval-tree in Rust with associated values in the nodes

store-interval-tree A balanced unbounded interval-tree in Rust with associated values in the nodes. Based on rudac and bio. Example use store_interval

Andrea Fioraldi 3 Nov 22, 2022
Drill is a HTTP load testing application written in Rust inspired by Ansible syntax

Drill Drill is a HTTP load testing application written in Rust. The main goal for this project is to build a really lightweight tool as alternative to

Ferran Basora 1.5k Dec 28, 2022
An experimental HTTP load testing application written in Rust.

Herd Herd was a small side project in building a HTTP load testing application in Rust with a main focus on being easy to use and low on OS level depe

Jacob Clark 100 Dec 27, 2022
ConnectorX - Fastest library to load data from DB to DataFrames in Rust and Python

ConnectorX enables you to load data from databases into Python in the fastest and most memory efficient way.

SFU Database Group 939 Jan 5, 2023
Drill is an HTTP load testing application written in Rust inspired by Ansible syntax

Drill is an HTTP load testing application written in Rust inspired by Ansible syntax

Ferran Basora 1.5k Jan 1, 2023
Rust I18n is use Rust codegen for load YAML file storage translations on compile time, and give you a t! macro for simply get translation texts.

Rust I18n Rust I18n is use Rust codegen for load YAML file storage translations on compile time, and give you a t! macro for simply get translation te

Longbridge 73 Dec 27, 2022
A Rust crate to load a shared library into a target process without using ptrace.

Intruducer A Rust crate to load a shared library into a target process without using ptrace. This is a portable rewrite of dlinject. Compatibility It

null 90 Jan 3, 2023
handle some lichess.org/tournament load with rust, while learning rust

lila-http Take some of the HTTP load away from lila. WIP! Arena tournaments Clients connected to a tournament page request new data about the tourname

Thibault Duplessis 22 Jan 2, 2023
Bevy plugin for an AssetServer that can load embedded resources, or use other AssetServers based on the path.

Bevy-Embasset Embed your asset folder inside your binary. bevy-embasset adds support for loading assets embedded into the binary. Furthermore, it can

Johnny Tidemand Vestergaard 9 Aug 4, 2022
hb is an endpoint focused HTTP load testing / benchmark tool.

hb hb is an endpoint focused HTTP load testing / benchmark tool. Description The goal of hb is to provide a simple, robust tool to apply load against

Mark Pritchard 2 Aug 23, 2022