@cryptotaxi247 / kubo / commits / 90b989a71

AddCloserChild + net ctxcloser

Juan Batiz-Benet committed Oct 25, 2014 at 05:21 UTC 90b989a7186ffdb83d3e52110199fcbb5295d665
2 files changed +34 -26
net/net.go
+10 -26
@@ -1,12 +1,11 @@
1 package net
2
3 import (
4 - "errors"
5 -
4 msg "github.com/jbenet/go-ipfs/net/message"
5 mux "github.com/jbenet/go-ipfs/net/mux"
6 swarm "github.com/jbenet/go-ipfs/net/swarm"
7 peer "github.com/jbenet/go-ipfs/peer"
8 + ctxc "github.com/jbenet/go-ipfs/util/ctxcloser"
9
10 context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
11 )
@@ -23,31 +22,30 @@ type IpfsNetwork struct {
22 // peer connection multiplexing
23 swarm *swarm.Swarm
24
26 - // network context
27 - ctx context.Context
28 - cancel context.CancelFunc
25 + // network context closer
26 + ctxc.ContextCloser
27 }
28
29 // NewIpfsNetwork is the structure that implements the network interface
30 func NewIpfsNetwork(ctx context.Context, local peer.Peer,
31 peers peer.Peerstore, pmap *mux.ProtocolMap) (*IpfsNetwork, error) {
32
35 - ctx, cancel := context.WithCancel(ctx)
36 -
33 in := &IpfsNetwork{
38 - local: local,
39 - muxer: mux.NewMuxer(ctx, *pmap),
40 - ctx: ctx,
41 - cancel: cancel,
34 + local: local,
35 + muxer: mux.NewMuxer(ctx, *pmap),
36 + ContextCloser: ctxc.NewContextCloser(ctx, nil),
37 }
38
39 var err error
40 in.swarm, err = swarm.NewSwarm(ctx, local, peers)
41 if err != nil {
47 - cancel()
42 + in.Close()
43 return nil, err
44 }
45
46 + in.AddCloserChild(in.swarm)
47 + in.AddCloserChild(in.muxer)
48 +
49 // remember to wire components together.
50 in.muxer.Pipe.ConnectTo(in.swarm.Pipe)
51
@@ -89,20 +87,6 @@ func (n *IpfsNetwork) SendMessage(m msg.NetMessage) error {
87 return nil
88 }
89
92 -// Close terminates all network operation
93 -func (n *IpfsNetwork) Close() error {
94 - if n.cancel == nil {
95 - return errors.New("Network already closed.")
96 - }
97 -
98 - n.swarm.Close()
99 - n.muxer.Close()
100 -
101 - n.cancel()
102 - n.cancel = nil
103 - return nil
104 -}
105 -
90 // GetPeerList returns the networks list of connected peers
91 func (n *IpfsNetwork) GetPeerList() []peer.Peer {
92 return n.swarm.GetPeerList()
util/ctxcloser/closer.go
+24
@@ -50,10 +50,25 @@ type ContextCloser interface {
50 // Children is a sync.Waitgroup for all children goroutines that should
51 // shut down completely before this service is said to be "closed".
52 // Follows the semantics of WaitGroup:
53 + //
54 // Children().Add(1) // add one more dependent child
55 // Children().Done() // child signals it is done
56 + //
57 Children() *sync.WaitGroup
58
59 + // AddCloserChild registers a dependent ContextCloser child. The child will
60 + // be closed when this parent is closed, and waited upon to finish. It is
61 + // the functional equivalent of the following:
62 + //
63 + // go func(parent, child ContextCloser) {
64 + // parent.Children().Add(1) // add one more dependent child
65 + // <-parent.Closing() // wait until parent is closing
66 + // child.Close() // signal child to close
67 + // parent.Children().Done() // child signals it is done
68 + // }(a, b)
69 + //
70 + AddCloserChild(c ContextCloser)
71 +
72 // Close is a method to call when you wish to stop this ContextCloser
73 Close() error
74
@@ -117,6 +132,15 @@ func (c *contextCloser) Children() *sync.WaitGroup {
132 return &c.children
133 }
134
135 +func (c *contextCloser) AddCloserChild(child ContextCloser) {
136 + c.children.Add(1)
137 + go func(parent, child ContextCloser) {
138 + <-parent.Closing() // wait until parent is closing
139 + child.Close() // signal child to close
140 + parent.Children().Done() // child signals it is done
141 + }(c, child)
142 +}
143 +
144 // Close is the external close function. it's a wrapper around internalClose
145 // that waits on Closed()
146 func (c *contextCloser) Close() error {