@@ -2,6 +2,7 @@ package core
2
2
3
3
import (
4
4
"fmt"
5
+ "io"
5
6
6
7
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
7
8
b58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
@@ -97,11 +98,22 @@ type Mounts struct {
97
98
98
99
type ConfigOption func (ctx context.Context ) (* IpfsNode , error )
99
100
100
- func NewIPFSNode (ctx context.Context , option ConfigOption ) (* IpfsNode , error ) {
101
+ func NewIPFSNode (parent context.Context , option ConfigOption ) (* IpfsNode , error ) {
102
+ ctxg := ctxgroup .WithContext (parent )
103
+ ctx := ctxg .Context ()
104
+ success := false // flip to true after all sub-system inits succeed
105
+ defer func () {
106
+ if ! success {
107
+ ctxg .Close ()
108
+ }
109
+ }()
110
+
101
111
node , err := option (ctx )
102
112
if err != nil {
103
113
return nil , err
104
114
}
115
+ node .ContextGroup = ctxg
116
+ ctxg .SetTeardown (node .teardown )
105
117
106
118
// Need to make sure it's perfectly clear 1) which variables are expected
107
119
// to be initialized at this point, and 2) which variables will be
@@ -120,6 +132,7 @@ func NewIPFSNode(ctx context.Context, option ConfigOption) (*IpfsNode, error) {
120
132
node .Pinning = pin .NewPinner (node .Repo .Datastore (), node .DAG )
121
133
}
122
134
node .Resolver = & path.Resolver {DAG : node .DAG }
135
+ success = true
123
136
return node , nil
124
137
}
125
138
@@ -135,13 +148,6 @@ func Online(r repo.Repo) ConfigOption {
135
148
func Standard (r repo.Repo , online bool ) ConfigOption {
136
149
return func (ctx context.Context ) (n * IpfsNode , err error ) {
137
150
138
- success := false // flip to true after all sub-system inits succeed
139
- defer func () {
140
- if ! success && n != nil {
141
- n .Close ()
142
- }
143
- }()
144
-
145
151
if r == nil {
146
152
return nil , debugerror .Errorf ("repo required" )
147
153
}
@@ -155,9 +161,6 @@ func Standard(r repo.Repo, online bool) ConfigOption {
155
161
Repo : r ,
156
162
}
157
163
158
- n .ContextGroup = ctxgroup .WithContextAndTeardown (ctx , n .teardown )
159
- ctx = n .ContextGroup .Context ()
160
-
161
164
// setup Peerstore
162
165
n .Peerstore = peer .NewPeerstore ()
163
166
@@ -180,7 +183,6 @@ func Standard(r repo.Repo, online bool) ConfigOption {
180
183
n .Exchange = offline .Exchange (n .Blockstore )
181
184
}
182
185
183
- success = true
184
186
return n , nil
185
187
}
186
188
}
@@ -197,7 +199,7 @@ func (n *IpfsNode) StartOnlineServices() error {
197
199
return err
198
200
}
199
201
200
- peerhost , err := constructPeerHost (ctx , n .ContextGroup , n . Repo .Config (), n .Identity , n .Peerstore )
202
+ peerhost , err := constructPeerHost (ctx , n .Repo .Config (), n .Identity , n .Peerstore )
201
203
if err != nil {
202
204
return debugerror .Wrap (err )
203
205
}
@@ -207,7 +209,7 @@ func (n *IpfsNode) StartOnlineServices() error {
207
209
n .Diagnostics = diag .NewDiagnostics (n .Identity , n .PeerHost )
208
210
209
211
// setup routing service
210
- dhtRouting , err := constructDHTRouting (ctx , n .ContextGroup , n . PeerHost , n .Repo .Datastore ())
212
+ dhtRouting , err := constructDHTRouting (ctx , n .PeerHost , n .Repo .Datastore ())
211
213
if err != nil {
212
214
return debugerror .Wrap (err )
213
215
}
@@ -243,9 +245,27 @@ func (n *IpfsNode) StartOnlineServices() error {
243
245
return nil
244
246
}
245
247
248
+ // teardown closes children
246
249
func (n * IpfsNode ) teardown () error {
247
- if err := n .Repo .Close (); err != nil {
248
- return err
250
+ var errs []error
251
+ closers := []io.Closer {
252
+ n .Repo ,
253
+ }
254
+ if n .DHT != nil {
255
+ closers = append (closers , n .DHT )
256
+ }
257
+ if n .PeerHost != nil {
258
+ closers = append (closers , n .PeerHost )
259
+ }
260
+ for _ , closer := range closers {
261
+ if closer != nil {
262
+ if err := closer .Close (); err != nil {
263
+ errs = append (errs , err )
264
+ }
265
+ }
266
+ }
267
+ if len (errs ) > 0 {
268
+ return errs [0 ]
249
269
}
250
270
return nil
251
271
}
@@ -344,7 +364,7 @@ func listenAddresses(cfg *config.Config) ([]ma.Multiaddr, error) {
344
364
}
345
365
346
366
// isolates the complex initialization steps
347
- func constructPeerHost (ctx context.Context , ctxg ctxgroup. ContextGroup , cfg * config.Config , id peer.ID , ps peer.Peerstore ) (p2phost.Host , error ) {
367
+ func constructPeerHost (ctx context.Context , cfg * config.Config , id peer.ID , ps peer.Peerstore ) (p2phost.Host , error ) {
348
368
listenAddrs , err := listenAddresses (cfg )
349
369
if err != nil {
350
370
return nil , debugerror .Wrap (err )
@@ -362,7 +382,6 @@ func constructPeerHost(ctx context.Context, ctxg ctxgroup.ContextGroup, cfg *con
362
382
if err != nil {
363
383
return nil , debugerror .Wrap (err )
364
384
}
365
- ctxg .AddChildGroup (network .CtxGroup ())
366
385
367
386
peerhost := p2pbhost .New (network )
368
387
// explicitly set these as our listen addrs.
@@ -377,9 +396,8 @@ func constructPeerHost(ctx context.Context, ctxg ctxgroup.ContextGroup, cfg *con
377
396
return peerhost , nil
378
397
}
379
398
380
- func constructDHTRouting (ctx context.Context , ctxg ctxgroup. ContextGroup , host p2phost.Host , ds datastore.ThreadSafeDatastore ) (* dht.IpfsDHT , error ) {
399
+ func constructDHTRouting (ctx context.Context , host p2phost.Host , ds datastore.ThreadSafeDatastore ) (* dht.IpfsDHT , error ) {
381
400
dhtRouting := dht .NewDHT (ctx , host , ds )
382
401
dhtRouting .Validators [IpnsValidatorTag ] = namesys .ValidateIpnsRecord
383
- ctxg .AddChildGroup (dhtRouting )
384
402
return dhtRouting , nil
385
403
}
0 commit comments