| Crates.io | app-instance-detector |
| lib.rs | app-instance-detector |
| version | 1.0.0 |
| created_at | 2025-10-10 17:17:17.450845+00 |
| updated_at | 2025-10-10 17:17:17.450845+00 |
| description | A Rust library for detecting 1 or more instances of an app are running locally, that doesn't use lockfiles. |
| homepage | https://github.com/AutonomoDev/app-instance-detector |
| repository | https://github.com/AutonomoDev/app-instance-detector |
| max_upload_size | |
| id | 1877245 |
| size | 14,202 |
A lightweight, lockfile-free Rust library for detecting and communicating with other running instances of an application on the same machine.
It uses a TCP-based handshake mechanism, allowing applications to discover each other, find available ports, and exchange basic information.
This library is used in conjunction with the Autonomo CLI Platform.
GitHub: https://github.com/AutonomoDev/app-instance-detector
To include app-instance-detector in your Rust application, add the following line to your Cargo.toml file:
[dependencies]
app-instance-detector = "0.9.0"
The primary use case is for an application to check for existing instances upon startup. If none are found, it starts its own "handshake server" to become discoverable by future instances.
Here is a complete example demonstrating how to use the library in a typical application.
main.rsuse app_instance_detector::{
find_all_instances, find_next_available_port, start_handshake_server,
};
use std::time::Duration;
use std::{process, thread};
fn main() {
const BASE_PORT: u16 = 9000;
const MAX_SEARCH: u16 = 50;
const HANDSHAKE_MESSAGE: &[u8] = b"ARE_YOU_MY_APP?";
const TIMEOUT: Duration = Duration::from_millis(200);
// 1. Check for other running instances of this application.
let instances = find_all_instances(BASE_PORT, MAX_SEARCH, TIMEOUT, HANDSHAKE_MESSAGE);
if !instances.is_empty() {
println!("Found {} running instance(s):", instances.len());
for (port, response) in instances {
println!(" - Instance on port {} responded: '{}'", port, response);
}
// Optional: Exit if you only want a single instance of your app to run.
println!("\nAnother instance is already running. Exiting.");
return;
}
// 2. No other instances found. Let's start this one.
// Find an available port for our new instance to listen on.
let my_port = find_next_available_port(BASE_PORT, MAX_SEARCH);
println!(
"No running instances found. Starting new instance on port {}.",
my_port
);
// 3. Start a background handshake server for this instance.
// This server will respond to discovery requests from other instances.
// We'll make it respond with this instance's Process ID (PID).
let my_pid = process::id();
start_handshake_server(my_port, move || {
// This closure generates the response string for any handshake request.
format!("MY_APP_INSTANCE_PID:{}", my_pid)
});
// --- Your application's main logic goes here ---
println!(
"\nApplication with PID {} is now running.", my_pid
);
println!("It is discoverable by other instances on port {}.", my_port);
println!("Run this program again in another terminal to see detection in action.");
// Keep the main thread alive to allow the background server to run.
thread::sleep(Duration::from_secs(60));
println!("\nApplication shutting down.");
}
src/main.rs in your project.Cargo.toml includes the dependency.cargo run
cargo run again. The second instance will detect the first one and exit.To compile the library or any application using it, run the build script:
./build.sh
The library exposes a few key functions:
find_all_instances(base_port, max_search, timeout, request_message) -> Vec<(u16, String)>: Scans a port range, sends a handshake request, and returns a list of ports and responses from discovered instances.find_next_available_port(base_port, max_search) -> u16: Finds the first TCP port that is not in use within a given range.start_handshake_server<F>(port, response_generator: F): Spawns a background thread that listens on the specified port and responds to any incoming connection using the provided response_generator closure.is_port_in_use(port) -> bool: A simple utility to check if a specific port is currently in use.send_handshake_request(port, timeout, request_message) -> anyhow::Result<String>: The low-level function for sending a request to a single port and getting a response.This project is licensed under the MIT License.