you can use uds already. I didn't test though
https://actix.github.io/actix-web/actix_web/struct.HttpServer.html#method.start_incoming
Would be nice to be able to do
use actix_web::*;
fn main() {
HttpServer::new(
|| Application::new()
.resource("/", |r| r.h(httpcodes::HttpOk)))
.bind("/tmp/myserver.socket").expect("Can not bind")
.run();
}
or something like .bind_uds(path: AsRef<Path>)
sounds reasonable. would you provide PR?
Sure, I'll give it a try.
Turns out it's much more involved than I thought. To add unix domain socket support, I have to modify the HttpServer struct
I think we have two options, first we can add a new field unix_sockets: HashMap<net::SocketAddr, std::os::unix::net::UnixListener>, second we can modify the existing sockets field to make the HashMap value an enum, for example:
enum SocketListener {
Tcp(net::TcpListener),
Unix(std::os::unix::net::UnixListener),
}
For the first option we may need to copy the start_accept_thread code to something like start_accept_thread_unix_socket to add unix socket specific code and push to self.accept in HttpServer::start method and etc.
For the second option, we can modify the start_accept_thread signature to
fn start_accept_thread(
sock: SocketListener, addr: net::SocketAddr, backlog: i32,
srv: mpsc::UnboundedSender<ServerCommand>, info: Info,
mut workers: Vec<(usize, mpsc::UnboundedSender<Conn<net::TcpStream>>)>)
-> (mio::SetReadiness, sync_mpsc::Sender<Command>)
Turns out this will get much more complicated since it needs to be able to register/deregister mio TcpListener and mio_uds UnixListener to Poll and support the accept_std API.
I think enum SocketListener is better approach, it is simpler to extend in the future.
one note, you don't really need to reuse start_accept_thread method, you can develop separate function and you can use tokio instead of mio
actually, maybe start_accept_thread should be switched to tokio as well
Just found out I was assuming TcpListener::local_addr() and UnixListener::local_addr() are the same type, turns out they are not.
I am now also considering trying the socket2 crate.
Why do you need socket2? I鈥檇 prefer to use one lib net2
I am only considering because it has an concrete SockAddr impl.
I don鈥檛 see how this can help
Would like to support this cause as it's fairly useful. For instance, nginx in front of actix connected via Unix sockets are much faster (https://stackoverflow.com/questions/14973942/tcp-loopback-connection-vs-unix-domain-socket-performance/29436429#29436429) than TCP loopbacks.
This involves some changes to the public API though, particularly:
rust
pub fn addrs(&self) -> Vec<SocketAddr>;
pub fn addrs_with_scheme(&self) -> Vec<(SocketAddr, &str)>;
The SocketAddr type is specific to net:: and not compatible? with Unix domain socket addresses (which are fs paths). I feel we should adjust the Socket struct to accomodate generic address, and listeners:
rust
struct Socket {
lst: net::TcpListener,
addr: net::SocketAddr,
tp: StreamHandlerType,
}
Would introducing SocketAddrType and ListenerType make sense? Any ideas on the cleanest way to get this going with rust type magic? Also, not sure how breaking such change is but I would be willing to take a shot at it.
@rmanoka I have an outdated WIP branch, unfortunately I don't have any time to work on it recently.
After some source-code browsing, I feel we should define a trait Transport to abstract out all the transport layer functionality (have seen similar Connect in hyper). Then the server simply spawns this Transport possibly using a factory and configured using many strategies (one per cpu, exactly 42, etc). This is also helping to eventually splitting server code to separate crate as suggested in another issue.
To the best of my understanding the changes should be contained in essentially server/{channel, srv, worker}.rs but the public API would also change.
@rmanoka I feel the same.
Adding Unix Domain socket support to Rocket which is powered by sync hyper is quite straightforward.
@messense Neat work on the Rocket UDS support! But, sync is the main disadvantage with it. Hyper itself seems fairly easy to use with UDS (eg. hyperlocal, but apparently not maintained?)
Supported with uds feature
Does this actually work to create UDS servers? There is no documentation of this, I see no tests for it in the code base, and I am unable to get it to work in my application. Is there a different bind function or address format that should be used when setting up the server? Calling server.bind("/path") reports invalid socket address.
Ok, I misunderstood it, it it for client only for now
1.0 has removed UDS support, so currently there's no way to listen on an unix domain socket.
UDS support is important for integration with nginx and systemd.
implemented in master will be available in 1.0.5
Most helpful comment
implemented in master will be available in 1.0.5