alex1
June 25, 2024, 11:43am
1
HI.
I have adopted layer4-proxy from great Jacob
Now I think to implement a "max concurrent clients".
A Internet search shows some examples with Thread pool or semaphores but it's not clear for me what's the best solution in production environment with 5,50 or even 10k concurrent clients.
Thanks for any feedback.
alice
June 25, 2024, 12:04pm
2
1 Like
alex1
June 25, 2024, 12:23pm
3
Thank you for your fast and reliable answer.
alex1
June 25, 2024, 9:04pm
4
I have now tried to implement the semaphore but I'm not sure in which block I should add the drop.
loop {
let thread_proxy = config.clone();
//let permit = config.maxclients.clone().acquire_owned().await.unwrap();
//debug!("permit.num_permits {:?}",permit.num_permits());
match listener.accept().await {
Err(err) => {
error!("Failed to accept connection: {}", err);
return Err(Box::new(err));
}
Ok((stream, _)) => {
tokio::spawn(async move {
match accept(stream, thread_proxy).await {
Ok(_) => {
//debug!("Accepted permit {:?}", permit);
}
I hope that anybody can give me a hint here, thank you.
The semaphore is defined here
#[derive(Debug, Clone)]
pub(crate) struct Proxy {
pub name: String,
pub listen: SocketAddr,
pub protocol: String,
pub tls: bool,
pub sni: Option<HashMap<String, String>>,
pub default_action: String,
pub upstream: HashMap<String, Upstream>,
pub via: ViaUpstream,
//pub maxclients: Arc<Semaphore<>>,
pub maxclients: usize,
}
impl Server {
pub fn new_from_v1_config(config: ParsedConfigV1) -> Self {
let mut new_server = Server {
proxies: Vec::new(),
};
for (name, proxy) in config.servers.iter() {
and created here
let proxy = Proxy {
name: name.clone(),
listen: listen_addr,
protocol: protocol.clone(),
tls,
sni: sni.clone(),
default_action: default.clone(),
upstream: upstream.clone(),
via: proxy.via.clone(),
//maxclients: Arc::new(Semaphore::new(proxy.maxclients)),
maxclients: proxy.maxclients,
};
new_server.proxies.push(Arc::new(proxy));
}
}
new_server
}
#[tokio::main]
alice
June 26, 2024, 11:05am
5
Put the drop
inside the tokio::spawn
after the call to accept
.
1 Like
alex1
June 26, 2024, 7:40pm
6
Thank you soooom much.
With this statement was I now able to create a connection limit which looks now like this.
let permit = config.maxclients.clone().acquire_owned().await.unwrap();
match listener.accept().await {
Err(err) => {
error!("Failed to accept connection: {}", err);
return Err(Box::new(err));
}
Ok((stream, _)) => {
tokio::spawn(async move {
match accept(stream, thread_proxy).await {
Ok(_) => {
debug!("Accepted permit {:?}", permit);
}
Err(err) => {
error!("Relay thread returned an error: {}", err);
}
};
drop(permit);
1 Like
system
Closed
September 24, 2024, 7:41pm
7
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.