Skip to content

Commit 2147285

Browse files
author
Ben
committed
Initialization with UDP emission
0 parents  commit 2147285

File tree

5 files changed

+151
-0
lines changed

5 files changed

+151
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target

Cargo.lock

+75
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "pulsar"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
rand = "0.8.4"

README.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Pulsar
2+
3+
## Overview
4+
Pulsar is a simple, multi-threaded metrics emitter for testing UDP listeners. When paired with [Neith](https://github.com/dblclik/neith) it represents a valuable tool for load and integration testing.
5+
6+
## Developing
7+
To re-use for your own purposes, change the `emit()` function to behave as you would like.
8+
9+
## TODOs
10+
- Add Clap integration for CLI args
11+
- Support mutliple emit functions
12+
- Persistent (until SIGTERM) emissions

src/main.rs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use std::net::UdpSocket;
2+
use std::{thread};
3+
use std::time::{SystemTime, UNIX_EPOCH, Duration};
4+
use rand::Rng;
5+
6+
fn main() -> std::io::Result<()> {
7+
{
8+
let mut used_ports = Vec::new();
9+
let mut thread_handles = Vec::new();
10+
for i in 0..15 {
11+
let mut got_new_port = false;
12+
let mut port = 0;
13+
println!("Searching for an unused port...");
14+
while !got_new_port {
15+
port = rand::thread_rng().gen_range(34000..35000);
16+
if !used_ports.contains(&port) {
17+
got_new_port = true;
18+
used_ports.push(port);
19+
}
20+
}
21+
println!("Thread {} starting...", i);
22+
let handle = thread::spawn( move || {
23+
let socket = UdpSocket::bind(format!("127.0.0.1:{port}")).expect(format!("could not bind to port {}", &port).as_str());
24+
emit(50, &socket).expect("Could not emit from pulsar");
25+
});
26+
thread_handles.push(handle);
27+
}
28+
println!("Waiting for threads to finish");
29+
for h in thread_handles {
30+
h.join().expect("thread failed");
31+
}
32+
} // the socket is closed here
33+
Ok(())
34+
}
35+
36+
fn emit(iters: usize, socket: &std::net::UdpSocket) -> std::io::Result<()> {
37+
let instance_id = rand::thread_rng().gen_range(u128::MAX/2..u128::MAX);
38+
let mut iters_remaining = iters;
39+
while iters_remaining > 0 {
40+
let start = SystemTime::now();
41+
let since_the_epoch = start
42+
.duration_since(UNIX_EPOCH)
43+
.expect("Time went backwards");
44+
let in_ms = since_the_epoch.as_millis();
45+
let message = format!("{} {} {}", instance_id, in_ms, rand::thread_rng().gen_range(1..=100));
46+
println!("{message}");
47+
thread::sleep(Duration::from_millis(rand::thread_rng().gen_range(1..50)));
48+
49+
let message_bytes = message.as_bytes();
50+
socket.send_to(message_bytes, "127.0.0.1:8080")?;
51+
iters_remaining -= 1;
52+
}
53+
Ok(())
54+
}

0 commit comments

Comments
 (0)