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 {