Skip to content

Commit 68c9986

Browse files
author
Brian Tiger Chow
committed
refactor(core) Close in teardown
This declarative style is simpler to compose than the imperative wiring up of objects. + pass context to StartOnlineServices as parameter. one by one, trying to remove dependencies on node state so these initialization steps can be broken down.
1 parent f303f41 commit 68c9986

File tree

1 file changed

+40
-23
lines changed

1 file changed

+40
-23
lines changed

core/core.go

+40-23
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package core
22

33
import (
44
"fmt"
5+
"io"
56

67
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
78
b58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
@@ -97,11 +98,22 @@ type Mounts struct {
9798

9899
type ConfigOption func(ctx context.Context) (*IpfsNode, error)
99100

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+
101111
node, err := option(ctx)
102112
if err != nil {
103113
return nil, err
104114
}
115+
node.ContextGroup = ctxg
116+
ctxg.SetTeardown(node.teardown)
105117

106118
// Need to make sure it's perfectly clear 1) which variables are expected
107119
// 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) {
120132
node.Pinning = pin.NewPinner(node.Repo.Datastore(), node.DAG)
121133
}
122134
node.Resolver = &path.Resolver{DAG: node.DAG}
135+
success = true
123136
return node, nil
124137
}
125138

@@ -135,13 +148,6 @@ func Online(r repo.Repo) ConfigOption {
135148
func Standard(r repo.Repo, online bool) ConfigOption {
136149
return func(ctx context.Context) (n *IpfsNode, err error) {
137150

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-
145151
if r == nil {
146152
return nil, debugerror.Errorf("repo required")
147153
}
@@ -155,9 +161,6 @@ func Standard(r repo.Repo, online bool) ConfigOption {
155161
Repo: r,
156162
}
157163

158-
n.ContextGroup = ctxgroup.WithContextAndTeardown(ctx, n.teardown)
159-
ctx = n.ContextGroup.Context()
160-
161164
// setup Peerstore
162165
n.Peerstore = peer.NewPeerstore()
163166

@@ -173,20 +176,18 @@ func Standard(r repo.Repo, online bool) ConfigOption {
173176

174177
// setup online services
175178
if online {
176-
if err := n.StartOnlineServices(); err != nil {
179+
if err := n.StartOnlineServices(ctx); err != nil {
177180
return nil, err // debugerror.Wraps.
178181
}
179182
} else {
180183
n.Exchange = offline.Exchange(n.Blockstore)
181184
}
182185

183-
success = true
184186
return n, nil
185187
}
186188
}
187189

188-
func (n *IpfsNode) StartOnlineServices() error {
189-
ctx := n.Context()
190+
func (n *IpfsNode) StartOnlineServices(ctx context.Context) error {
190191

191192
if n.PeerHost != nil { // already online.
192193
return debugerror.New("node already online")
@@ -197,7 +198,7 @@ func (n *IpfsNode) StartOnlineServices() error {
197198
return err
198199
}
199200

200-
peerhost, err := constructPeerHost(ctx, n.ContextGroup, n.Repo.Config(), n.Identity, n.Peerstore)
201+
peerhost, err := constructPeerHost(ctx, n.Repo.Config(), n.Identity, n.Peerstore)
201202
if err != nil {
202203
return debugerror.Wrap(err)
203204
}
@@ -207,7 +208,7 @@ func (n *IpfsNode) StartOnlineServices() error {
207208
n.Diagnostics = diag.NewDiagnostics(n.Identity, n.PeerHost)
208209

209210
// setup routing service
210-
dhtRouting, err := constructDHTRouting(ctx, n.ContextGroup, n.PeerHost, n.Repo.Datastore())
211+
dhtRouting, err := constructDHTRouting(ctx, n.PeerHost, n.Repo.Datastore())
211212
if err != nil {
212213
return debugerror.Wrap(err)
213214
}
@@ -243,9 +244,27 @@ func (n *IpfsNode) StartOnlineServices() error {
243244
return nil
244245
}
245246

247+
// teardown closes children
246248
func (n *IpfsNode) teardown() error {
247-
if err := n.Repo.Close(); err != nil {
248-
return err
249+
var errs []error
250+
closers := []io.Closer{
251+
n.Repo,
252+
}
253+
if n.DHT != nil {
254+
closers = append(closers, n.DHT)
255+
}
256+
if n.PeerHost != nil {
257+
closers = append(closers, n.PeerHost)
258+
}
259+
for _, closer := range closers {
260+
if closer != nil {
261+
if err := closer.Close(); err != nil {
262+
errs = append(errs, err)
263+
}
264+
}
265+
}
266+
if len(errs) > 0 {
267+
return errs[0]
249268
}
250269
return nil
251270
}
@@ -344,7 +363,7 @@ func listenAddresses(cfg *config.Config) ([]ma.Multiaddr, error) {
344363
}
345364

346365
// 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) {
366+
func constructPeerHost(ctx context.Context, cfg *config.Config, id peer.ID, ps peer.Peerstore) (p2phost.Host, error) {
348367
listenAddrs, err := listenAddresses(cfg)
349368
if err != nil {
350369
return nil, debugerror.Wrap(err)
@@ -362,7 +381,6 @@ func constructPeerHost(ctx context.Context, ctxg ctxgroup.ContextGroup, cfg *con
362381
if err != nil {
363382
return nil, debugerror.Wrap(err)
364383
}
365-
ctxg.AddChildGroup(network.CtxGroup())
366384

367385
peerhost := p2pbhost.New(network)
368386
// explicitly set these as our listen addrs.
@@ -377,9 +395,8 @@ func constructPeerHost(ctx context.Context, ctxg ctxgroup.ContextGroup, cfg *con
377395
return peerhost, nil
378396
}
379397

380-
func constructDHTRouting(ctx context.Context, ctxg ctxgroup.ContextGroup, host p2phost.Host, ds datastore.ThreadSafeDatastore) (*dht.IpfsDHT, error) {
398+
func constructDHTRouting(ctx context.Context, host p2phost.Host, ds datastore.ThreadSafeDatastore) (*dht.IpfsDHT, error) {
381399
dhtRouting := dht.NewDHT(ctx, host, ds)
382400
dhtRouting.Validators[IpnsValidatorTag] = namesys.ValidateIpnsRecord
383-
ctxg.AddChildGroup(dhtRouting)
384401
return dhtRouting, nil
385402
}

0 commit comments

Comments
 (0)