Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Way to share all parent connections #2

Closed
bm0 opened this issue Oct 16, 2018 · 12 comments
Closed

Way to share all parent connections #2

bm0 opened this issue Oct 16, 2018 · 12 comments

Comments

@bm0
Copy link

bm0 commented Oct 16, 2018

Hello everyone!
Is there a way to share all the active connections between processes?
I see only one way, use Fds.Conn() method, but i must know addr in parent process for this.
It may be worth adding methods that will return all parent connections and listeners?
It would be amazing.

@lmb
Copy link
Contributor

lmb commented Oct 16, 2018

Is there a way to share all the active connections between processes?
If you mean client connections (think established TCP sockets) then no. Migrating these between processes usually involves migrating application state as well, which is complicated and error prone.

If you mean listeners, there might be a possibility to support this. Can you describe your use case some more? Not sure I understand you correctly.

@bm0
Copy link
Author

bm0 commented Oct 16, 2018

I have a program that create some tcp listeners that accepts connections (net.Conn).
Now i can use parent listeners in child process, but how i can use connections that accepted in parent process?

@bm0
Copy link
Author

bm0 commented Oct 16, 2018

I wrote a small snippet, most likely it does not work, but I hope that this will help to understand
https://gist.github.com/bm0/e645392b7274964bf23dcf4ee7fd56a5

@bm0
Copy link
Author

bm0 commented Oct 16, 2018

In other words, can you give an example of how to properly use a AddConn and Conn functions?

@lmb
Copy link
Contributor

lmb commented Oct 16, 2018

Ok, I think I know what you want now. Unfortunately, AddConn and Conn don't work the way you'd like them to. The idea is to use them for https://golang.org/pkg/net/#UnixConn and similar.

Making this work for stream based connections is actually quite tricky, because the parent and the child have to coordinate. Example: you have a HTTP connection, first the parent reads from it, then the child, then the parent again. Now both processes have pieces of the data, and its impossible to continue using the connection in either process.

What would you do with this if it worked? I imagine you want to avoid closing client connections outright?

@bm0
Copy link
Author

bm0 commented Oct 16, 2018

Yes, I wrapped tcp connection in bufio.Reader to reduce the number of system calls and read packages with fixed length over tcp connection. Then I wrote the logic that allows handle all data from buffer before upgrade, therefore, the child process can start reading a new package from the connection without problems.

There are several methods for transferring active sockets (connections), one of which is to pack the connection and its state, and send it to a new process. But I choose a simpler way.

Thank you for answers, Lorenz.

@bm0
Copy link
Author

bm0 commented Oct 16, 2018

It's so strange, but I got what I wanted!
I wrote two helper functions to add and get connections.
https://gist.github.com/bm0/fbd8285e3319af9efe83c3193ac17acf

Now when I accept new connection in parent process I call appendConnAddr
After update I call getInheritConns in child process and handle inherited connections.

It looks like it works well. At the same time, I understand that these functions helpers are "crutches".

What do you think, is it possible to implement something like that in this library?

@lmb
Copy link
Contributor

lmb commented Oct 16, 2018

Ha, that's a a very cool hack! Have you tried hammering this a bit, to make sure that this works? I'm worried that there is a race condition in the old process:

  1. call ln.Accept()
  2. other go routine: call upg.Upgrade()
  3. call upg.Fds.AddConn() <- this does not add conn from 1 to upgrade from 2

There is a good chance you will not pass the connection to the new process. It's possible to make this safe, but it would require changing the API quite a bit which I'd rather not do.

@bm0
Copy link
Author

bm0 commented Oct 16, 2018

Yes, I made simple program on Python that send many packages over tcp to my server.
I would like to pass all connections, but I don't have such a task, instead I try to pass everything that is possible to the child process.
Of course, it would be very nice to have such an opportunity, but I'm not yet familiar enough with the library's code to implement it.

Maybe you could tell me how to do it better, I would love to do a fork if you don't want to change the architecture of the library.

@lmb
Copy link
Contributor

lmb commented Oct 18, 2018 via email

@lmb
Copy link
Contributor

lmb commented Oct 22, 2018

Closing this, sorry I don't have a better answer.

@lmb lmb closed this as completed Oct 22, 2018
@bm0
Copy link
Author

bm0 commented Oct 22, 2018

Ok, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants