Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit cd3d6df

Browse files
committedAug 13, 2015
replace nodebuilder with a nicer interface
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
1 parent ace06b4 commit cd3d6df

File tree

3 files changed

+107
-60
lines changed

3 files changed

+107
-60
lines changed
 

‎cmd/ipfs/daemon.go

+8-5
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,11 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
192192
return
193193
}
194194

195-
// Start assembling corebuilder
196-
nb := core.NewNodeBuilder().Online()
197-
nb.SetRepo(repo)
195+
// Start assembling node config
196+
ncfg := &core.BuildCfg{
197+
Online: true,
198+
Repo: repo,
199+
}
198200

199201
routingOption, _, err := req.Option(routingOptionKwd).String()
200202
if err != nil {
@@ -215,10 +217,11 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
215217
Addrs: []ma.Multiaddr{addr.Transport()},
216218
})
217219
}
218-
nb.SetRouting(corerouting.SupernodeClient(infos...))
220+
221+
ncfg.Routing = corerouting.SupernodeClient(infos...)
219222
}
220223

221-
node, err := nb.Build(req.Context())
224+
node, err := core.NewNode(req.Context(), ncfg)
222225
if err != nil {
223226
log.Error("error from node construction: ", err)
224227
res.SetError(err, cmds.ErrNormal)

‎core/builder.go

+96-54
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,59 @@ package core
33
import (
44
"crypto/rand"
55
"encoding/base64"
6-
"errors"
76

87
ds "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
98
dsync "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/sync"
9+
goprocessctx "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess/context"
1010
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
11+
bstore "github.com/ipfs/go-ipfs/blocks/blockstore"
1112
key "github.com/ipfs/go-ipfs/blocks/key"
13+
bserv "github.com/ipfs/go-ipfs/blockservice"
14+
offline "github.com/ipfs/go-ipfs/exchange/offline"
15+
dag "github.com/ipfs/go-ipfs/merkledag"
1216
ci "github.com/ipfs/go-ipfs/p2p/crypto"
17+
peer "github.com/ipfs/go-ipfs/p2p/peer"
18+
path "github.com/ipfs/go-ipfs/path"
19+
pin "github.com/ipfs/go-ipfs/pin"
1320
repo "github.com/ipfs/go-ipfs/repo"
1421
cfg "github.com/ipfs/go-ipfs/repo/config"
1522
)
1623

17-
var ErrAlreadyBuilt = errors.New("this builder has already been used")
24+
type BuildCfg struct {
25+
// If online is set, the node will have networking enabled
26+
Online bool
1827

19-
// NodeBuilder is an object used to generate an IpfsNode
20-
type NodeBuilder struct {
21-
online bool
22-
routing RoutingOption
23-
peerhost HostOption
24-
repo repo.Repo
25-
built bool
26-
nilrepo bool
28+
// If NilRepo is set, a repo backed by a nil datastore will be constructed
29+
NilRepo bool
30+
31+
Routing RoutingOption
32+
Host HostOption
33+
Repo repo.Repo
2734
}
2835

29-
func NewNodeBuilder() *NodeBuilder {
30-
return &NodeBuilder{
31-
online: false,
32-
routing: DHTOption,
33-
peerhost: DefaultHostOption,
36+
func (cfg *BuildCfg) fillDefaults() error {
37+
if cfg.Repo == nil {
38+
var d ds.Datastore
39+
d = ds.NewMapDatastore()
40+
if cfg.NilRepo {
41+
d = ds.NewNullDatastore()
42+
}
43+
r, err := defaultRepo(dsync.MutexWrap(d))
44+
if err != nil {
45+
return err
46+
}
47+
cfg.Repo = r
48+
}
49+
50+
if cfg.Routing == nil {
51+
cfg.Routing = DHTOption
52+
}
53+
54+
if cfg.Host == nil {
55+
cfg.Host = DefaultHostOption
3456
}
57+
58+
return nil
3559
}
3660

3761
func defaultRepo(dstore ds.ThreadSafeDatastore) (repo.Repo, error) {
@@ -62,53 +86,71 @@ func defaultRepo(dstore ds.ThreadSafeDatastore) (repo.Repo, error) {
6286
}, nil
6387
}
6488

65-
func (nb *NodeBuilder) Online() *NodeBuilder {
66-
nb.online = true
67-
return nb
68-
}
89+
func NewNode(ctx context.Context, cfg *BuildCfg) (*IpfsNode, error) {
90+
if cfg == nil {
91+
cfg = new(BuildCfg)
92+
}
6993

70-
func (nb *NodeBuilder) Offline() *NodeBuilder {
71-
nb.online = false
72-
return nb
73-
}
94+
err := cfg.fillDefaults()
95+
if err != nil {
96+
return nil, err
97+
}
7498

75-
func (nb *NodeBuilder) SetRouting(ro RoutingOption) *NodeBuilder {
76-
nb.routing = ro
77-
return nb
78-
}
99+
n := &IpfsNode{
100+
mode: offlineMode,
101+
Repo: cfg.Repo,
102+
ctx: ctx,
103+
Peerstore: peer.NewPeerstore(),
104+
}
105+
if cfg.Online {
106+
n.mode = onlineMode
107+
}
79108

80-
func (nb *NodeBuilder) SetHost(ho HostOption) *NodeBuilder {
81-
nb.peerhost = ho
82-
return nb
83-
}
109+
// TODO: this is a weird circular-ish dependency, rework it
110+
n.proc = goprocessctx.WithContextAndTeardown(ctx, n.teardown)
84111

85-
func (nb *NodeBuilder) SetRepo(r repo.Repo) *NodeBuilder {
86-
nb.repo = r
87-
return nb
88-
}
112+
success := false
113+
defer func() {
114+
if !success {
115+
n.teardown()
116+
}
117+
}()
89118

90-
func (nb *NodeBuilder) NilRepo() *NodeBuilder {
91-
nb.nilrepo = true
92-
return nb
93-
}
119+
// setup local peer ID (private key is loaded in online setup)
120+
if err := n.loadID(); err != nil {
121+
return nil, err
122+
}
94123

95-
func (nb *NodeBuilder) Build(ctx context.Context) (*IpfsNode, error) {
96-
if nb.built {
97-
return nil, ErrAlreadyBuilt
124+
n.Blockstore, err = bstore.WriteCached(bstore.NewBlockstore(n.Repo.Datastore()), kSizeBlockstoreWriteCache)
125+
if err != nil {
126+
return nil, err
98127
}
99-
nb.built = true
100-
if nb.repo == nil {
101-
var d ds.Datastore
102-
d = ds.NewMapDatastore()
103-
if nb.nilrepo {
104-
d = ds.NewNullDatastore()
105-
}
106-
r, err := defaultRepo(dsync.MutexWrap(d))
107-
if err != nil {
128+
129+
if cfg.Online {
130+
do := setupDiscoveryOption(n.Repo.Config().Discovery)
131+
if err := n.startOnlineServices(ctx, cfg.Routing, cfg.Host, do); err != nil {
108132
return nil, err
109133
}
110-
nb.repo = r
134+
} else {
135+
n.Exchange = offline.Exchange(n.Blockstore)
111136
}
112-
conf := standardWithRouting(nb.repo, nb.online, nb.routing, nb.peerhost)
113-
return NewIPFSNode(ctx, conf)
137+
138+
n.Blocks, err = bserv.New(n.Blockstore, n.Exchange)
139+
if err != nil {
140+
return nil, err
141+
}
142+
143+
n.DAG = dag.NewDAGService(n.Blocks)
144+
n.Pinning, err = pin.LoadPinner(n.Repo.Datastore(), n.DAG)
145+
if err != nil {
146+
// TODO: we should move towards only running 'NewPinner' explicity on
147+
// node init instead of implicitly here as a result of the pinner keys
148+
// not being found in the datastore.
149+
// this is kinda sketchy and could cause data loss
150+
n.Pinning = pin.NewPinner(n.Repo.Datastore(), n.DAG)
151+
}
152+
n.Resolver = &path.Resolver{DAG: n.DAG}
153+
154+
success = true
155+
return n, nil
114156
}

‎core/commands/add.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ remains to be implemented.
104104
chunker, _, _ := req.Option(chunkerOptionName).String()
105105

106106
if hash {
107-
nilnode, err := core.NewNodeBuilder().Build(n.Context())
107+
nilnode, err := core.NewNode(n.Context(), &core.BuildCfg{
108+
NilRepo: true,
109+
})
108110
if err != nil {
109111
res.SetError(err, cmds.ErrNormal)
110112
return

0 commit comments

Comments
 (0)
Please sign in to comment.