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

Proposal: Closable Transport #999

Closed
Jorropo opened this issue Aug 26, 2020 · 7 comments · Fixed by libp2p/go-libp2p-swarm#227 or libp2p/go-libp2p-core#188
Closed

Proposal: Closable Transport #999

Jorropo opened this issue Aug 26, 2020 · 7 comments · Fixed by libp2p/go-libp2p-swarm#227 or libp2p/go-libp2p-core#188
Labels
kind/enhancement A net-new feature or improvement to an existing feature

Comments

@Jorropo
Copy link
Contributor

Jorropo commented Aug 26, 2020

Use Case

While writing a tor transport I noticed that some transports runs some node beyond the listener (mainly overlay networks).
For example my tor transport runs a tor node and I need to close it at one point. I can't rely on the listeners to close it because it's not because a node stop listening on an address it will not then dial someone.

Additions

I propose to add this in go-libp2p-core/transport :

type ClosableTransport interface {
  Transport

  // Close is called when the libp2p node doesn't need the transport anymore (the is node closing).
  // After that the transport can safely assume no more Listen() or Dial() are gonna be done.
  // This is usefull for transport running overlay network.
  Close() error
}

Then in host.Close() the host would use reflection to terminate the transport when closing (after closing all listeners) :

// Not actual working code, just an idea
var wg sync.WaitGroup
for _, v := range h.transports {
  ct, ok := v.(tpt.ClosableTransport)
  if ok {
    wg.Add(1)
    go func (t tpt.ClosableTransport){ // Needed because range is not thread safe
      defer wg.Done()
      t.Close()
    }(ct)
  }
}
wg.Wait()

(Also I can't rely on the garbage collector to do this work because I have some CGO code (or a system fork) and the garbage collector doesn't deal with that.)

In the Future

If in the future a method to unhook transport from a libp2p is added the transport will be closable that way.

@Jorropo Jorropo added the kind/enhancement A net-new feature or improvement to an existing feature label Aug 26, 2020
@aschmahmann
Copy link
Collaborator

Looks like this is related to #992. WDYT @Stebalien @vyzo @raulk

Stebalien added a commit to libp2p/go-libp2p-swarm that referenced this issue Aug 28, 2020
This way, transports with shared resources (e.g., reused sockets) can clean them
up.

fixes libp2p/go-libp2p#999
@Stebalien
Copy link
Member

It seems reasonable, but I'm not sure if we even need an interface change for this. We can probably just add a io.Closer. See libp2p/go-libp2p-swarm#227.

@vyzo
Copy link
Contributor

vyzo commented Aug 28, 2020

I don't think we need an interface change for this; we can soft check if the transport implements io.Closer and just call it.

@Jorropo
Copy link
Contributor Author

Jorropo commented Aug 28, 2020

@vyzo @Stebalien yes thx, I didn't even though of that, that certainly prettier.
With a small comment aside of go-libp2p-core/transport#Transport this would be perfect (this shouldn't stay an hidded feature it must be in the doc somewhere).

Jorropo added a commit to Jorropo/go-libp2p-core that referenced this issue Aug 28, 2020
Stebalien added a commit to libp2p/go-libp2p-swarm that referenced this issue Aug 28, 2020
This way, transports with shared resources (e.g., reused sockets) can clean them
up.

fixes libp2p/go-libp2p#999
Stebalien added a commit to libp2p/go-libp2p-swarm that referenced this issue Aug 28, 2020
This way, transports with shared resources (e.g., reused sockets) can clean them
up.

fixes libp2p/go-libp2p#999
@Jorropo
Copy link
Contributor Author

Jorropo commented Oct 8, 2020

Unexpected close (I was merging this in my repo for some mod replace rules and this somehow closed this).
I guess Closes #xxx works cross repo.

@Jorropo Jorropo reopened this Oct 8, 2020
@marten-seemann
Copy link
Contributor

Should the libp2p-quic-transport implement this?

@Jorropo
Copy link
Contributor Author

Jorropo commented Oct 8, 2020

Should the libp2p-quic-transport implement this?

@marten-seemann
That up to the transport, for quic yes it must :),
That would solve the issue of quic not closing the shared socket when libp2p close (#992).

Jorropo pushed a commit to Jorropo/go-libp2p-swarm that referenced this issue Oct 8, 2020
This way, transports with shared resources (e.g., reused sockets) can clean them
up.

fixes libp2p/go-libp2p#999
Stebalien added a commit to libp2p/go-libp2p-core that referenced this issue Mar 29, 2021
Stebalien added a commit to libp2p/go-libp2p-core that referenced this issue Mar 29, 2021
Stebalien added a commit to libp2p/go-libp2p-swarm that referenced this issue Mar 29, 2021
This way, transports with shared resources (e.g., reused sockets) can clean them
up.

fixes libp2p/go-libp2p#999
marten-seemann pushed a commit that referenced this issue Apr 21, 2022
This way, transports with shared resources (e.g., reused sockets) can clean them
up.

fixes #999
marten-seemann pushed a commit that referenced this issue Aug 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement A net-new feature or improvement to an existing feature
Projects
None yet
5 participants