Closed michelson closed 2 weeks ago
Firstly, you should stop using async-io
as it's legacy - instead use io-endpoint
which has a similar interface.
Regarding your program, you need to have multiple Async
blocks, e.g.
#!/usr/bin/env ruby
require 'async'
require 'io/endpoint/unix_endpoint'
require 'io/endpoint/bound_endpoint'
Async do
endpoint = IO::Endpoint.unix("server.ipc")
bound_endpoint = endpoint.bound
server_task = Async do
bound_endpoint.accept do |client|
Console.logger.info(client, "Accepted connection")
while line = client.gets
client.puts line
end
end
end
sleep 1
10.times do
UNIXSocket.open(endpoint.path) do |server|
server.puts "Hello World"
p server.gets
server.close
end
end
ensure
server_task&.stop
bound_endpoint&.close
end
In this case we have the server running in a nested task which allows our client to make connections to it, concurrently.
Hi @ioquatix, Thanks for the quick reply. If I understand correctly, I should wrap all the code in an async block. While this works, the main async is also blocking, and it is only released because we stopped the server at some point, right? Could async be achieved with a use case in which we want many workers running forever and processing messages or sending messages to each other in a single process program? Is it similar to how goroutines work on Golang? Or even like Thread.new in ruby which runs in background and do not block?
Thanks in advance, tremendous work on the Async
If I understand correctly, I should wrap all the code in an async block
In general, if you want those parts of the code to run concurrently, then yes.
While this works, the main async is also blocking, and it is only released because we stopped the server at some point, right?
Yes, at some level all programs must wait for the work to be completed.
Could async be achieved with a use case in which we want many workers running forever and processing messages or sending messages to each other in a single process program?
Yes, and there are different strategies for how you achieve this, e.g.
Is it similar to how goroutines work on Golang? Or even like Thread.new in ruby which runs in background and do not block?
This is unstructured concurrency. I don't think it's a good model.
https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/
Hi Samuel, thanks for the detailed answer.
Would it make sense if I used both? For instance, could I have a multi-process container with async-containe
r that spawns hundreds of actors with async-actor
?
I'm trying to implement some sort of OTP framework with gen_servers, tcp_server, supervisors, etc. I've implemented a gen_server with Ractor, but I find some of the safety safeguards a little bit limiting and challenging to debug. Async suite seems to be better suited for this use case!
Sorry for the noob question here, but something that I do not understand is that Async is blocking the code execution; I'm assuming that Async should not block and run concurrently, but I am not sure if I understand this correctly.
Example 1, a running server:
now, If I put a Thread new on the Async, it will not block.
how can I achieve the non block only with async gems?