Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace nodebuilder with a nicer interface #1572

Merged
merged 1 commit into from
Aug 27, 2015
Merged

Conversation

whyrusleeping
Copy link
Member

a less extreme version of #1557 that uses a BuildCfg to set all the same options.

License: MIT
Signed-off-by: Jeromy [email protected]

@whyrusleeping
Copy link
Member Author

@jbenet let me know what you think of this interface. If its what we want, i'll go ahead and switch over a bunch of the codebase to use it instead of the old way.

@jbenet
Copy link
Member

jbenet commented Aug 14, 2015

i like it :)

@whyrusleeping
Copy link
Member Author

alright! Choo Choo! time for the refactor train :D

@rht
Copy link
Contributor

rht commented Aug 14, 2015

Also, have been wondering, why the https://github.com/ipfs/go-ipfs/pull/1572/files#diff-54f2c4a5481de30b8ccb59ad5b6588b3L242? Sounds redundant with something that sounds "NodeBuilder".

Can't the node be asserted to exist at the creation of the commands.Context object?

@whyrusleeping
Copy link
Member Author

@rht on the invocContext.ConstructNode call, I think its so that the http client doesnt have to waste time constructing the node if it doesnt need to. Although that can likely be refactored... @jbenet thoughts?

@whyrusleeping
Copy link
Member Author

interesting failure here: https://travis-ci.org/ipfs/go-ipfs/jobs/75662605

}

// TODO: shrink this function as much as possible, moving logic into NewNode
func NewMockNodeOnNet(ctx context.Context, mn mocknet.Mocknet) (*core.IpfsNode, error) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it proved difficult to combine mocknet and the node constructor i was working on, i have this method here as a bit of a shim until i figure out the right way to do it.

@whyrusleeping
Copy link
Member Author

if anyone has a good idea on how to make the node construction process work nicely with the MockNet, i would love to hear your thoughts. cc @jbenet @Heems @rht

@whyrusleeping
Copy link
Member Author

much better :) RFCR

@whyrusleeping
Copy link
Member Author

The simplest case of getting an offline node for testing something is now:

node, err := core.NewNode(ctx, nil)

}
n.Resolver = &path.Resolver{DAG: n.DAG}

success = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be just n.teardown() (no defer) since it is only used for this path.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, there are three different places we could return early, triggering the need for a teardown.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i c, I got this reversed. teardown is not called only for this path.

This can be used for res.SetError

defer func(){
  if err != nil {
    res.SetError(err, cmds.ErrNormal)
  }
}()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function is a scary still, and the success/defer stuff is not easy to modify safely (error prone).

how about this (it should work exactly):

func cfgDefaults(cfg *BuildCfg) (*BuildCfg, error) {
  if cfg == nil {
    cfg = new(BuildCfg)
  }

  err := cfg.fillDefaults()
  if err != nil {
    return nil, err
  }    
}

func NewNode(ctx context.Context, cfg *BuildCfg) (*IpfsNode, error) {
  cfg, err := cfgDefaults(cfg)
  if err != nil {
    return nil, err
  }

  n := &IpfsNode{
    mode:      offlineMode,
    Repo:      cfg.Repo,
    ctx:       ctx,
    Peerstore: peer.NewPeerstore(),
  }
  if cfg.Online {
    n.mode = onlineMode
  }

  // TODO: this is a weird circular-ish dependency, rework it
  n.proc = goprocessctx.WithContextAndTeardown(ctx, n.teardown)
  if err := tryNodeSetup(ctx, cfg, n); err != nil {
    n.Close() 
    return nil, err
  }

  return n, nil
}

func tryNodeSetup(ctx context.Context, cfg *BuildCfg, n *IpfsNode) error {
  // setup local peer ID (private key is loaded in online setup)
  if err := n.loadID(); err != nil {
    return nil, err
  }

  bs := bstore.NewBlockstore(n.Repo.Datastore())
  n.Blockstore, err = bstore.WriteCached(bs, kSizeBlockstoreWriteCache)
  if err != nil {
    return nil, err
  }

  if cfg.Online {
    do := setupDiscoveryOption(n.Repo.Config().Discovery)
    if err := n.startOnlineServices(ctx, cfg.Routing, cfg.Host, do); err != nil {
      return nil, err
    }
  } else {
    n.Exchange = offline.Exchange(n.Blockstore)
  }

  n.Blocks = bserv.New(n.Blockstore, n.Exchange)
  n.DAG = dag.NewDAGService(n.Blocks)
  n.Pinning, err = pin.LoadPinner(n.Repo.Datastore(), n.DAG)
  if err != nil {
    // TODO: we should move towards only running 'NewPinner' explicity on
    // node init instead of implicitly here as a result of the pinner keys
    // not being found in the datastore.
    // this is kinda sketchy and could cause data loss
    n.Pinning = pin.NewPinner(n.Repo.Datastore(), n.DAG)
  }
  n.Resolver = &path.Resolver{DAG: n.DAG}
  return nil
}

Note: call n.Close(), or even n.proc.Close(). do not call n.teardown() directly!! or it may be called twice and break semantics (maybe panic)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, i like that better.

@rht
Copy link
Contributor

rht commented Aug 20, 2015

@whyrusleeping there is still one use left of mocknet.FullMeshLinked in p2p/net/mock/mock_notif_test.go. If this is replaced with mocknet.New and mn.Linkall() then mocknet.FullMeshLinked can be removed.

@jbenet
Copy link
Member

jbenet commented Aug 21, 2015

@whyrusleeping should i take another look here?

@whyrusleeping
Copy link
Member Author

@jbenet yeah, i think i got it right now.

@jbenet jbenet mentioned this pull request Aug 22, 2015
16 tasks
online: false,
routing: DHTOption,
peerhost: DefaultHostOption,
func (cfg *BuildCfg) fillDefaults() error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should error when:

  • cfg.Repo != nil && cfg.NilRepo

peers := mn.Peers()
if len(peers) < numPeers {
t.Fatal(errors.New("test initialization error"))
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why removing this? it can catch serious errors that might otherwise drive people mad.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(maybe it just belongs elsewhere)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because no peers are created by the mocknet constructor, i'm creating them manually in a loop and adding them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah ok!

@jbenet
Copy link
Member

jbenet commented Aug 23, 2015

👍 i think this is way cleaner. comments above

@whyrusleeping
Copy link
Member Author

@rht @jbenet do you think FullMeshLinked should be removed? if so, in this PR? or a subsequent one?

@jbenet
Copy link
Member

jbenet commented Aug 24, 2015

@rht @jbenet do you think FullMeshLinked should be removed? if so, in this PR? or a subsequent one?

No, i don't. i meant just New() so that people use FullMeshLinked and friends

@rht
Copy link
Contributor

rht commented Aug 24, 2015

FullMeshLinked should be removed only if it can't be modified to use the new NewNode manual construction.

This would mean FullMeshConntected is to be replaced with mn.ConnectAll() at the end of its construction.

It is part of this PR, I think, because the NewNode change makes it necessary (not optional) to use mn.LinkAll()/mn.ConnectAll() at the end instead of the beginning.

@whyrusleeping
Copy link
Member Author

@jbenet yeah, i think we should do away with the FullMeshLinked and FullMeshConnected and also WithNPeers constructors in favor of explicity calling LinkAll and ConnectAll because it makes it difficult to construct ipfs nodes from the resulting networks

@jbenet
Copy link
Member

jbenet commented Aug 26, 2015

Ok.

@whyrusleeping this needs rebasing i think

@jbenet
Copy link
Member

jbenet commented Aug 26, 2015

i think that's the last thing, right? this should be good to go

@whyrusleeping
Copy link
Member Author

rebased!

@jbenet
Copy link
Member

jbenet commented Aug 26, 2015

@whyrusleeping do all commits pass? either git push-each or squash.

@whyrusleeping
Copy link
Member Author

squashed.

@jbenet
Copy link
Member

jbenet commented Aug 27, 2015

@whyrusleeping conflicts?

License: MIT
Signed-off-by: Jeromy <[email protected]>

use NewNode instead of NewIPFSNode in most of the codebase

License: MIT
Signed-off-by: Jeromy <[email protected]>

make mocknet work with node constructor better

License: MIT
Signed-off-by: Jeromy <[email protected]>

finish cleanup of old construction method

License: MIT
Signed-off-by: Jeromy <[email protected]>

blockservice.New doesnt return an error anymore

License: MIT
Signed-off-by: Jeromy <[email protected]>

break up node construction into separate function

License: MIT
Signed-off-by: Jeromy <[email protected]>

add error case to default filling on node constructor

License: MIT
Signed-off-by: Jeromy <[email protected]>
@whyrusleeping
Copy link
Member Author

@jbenet conflicts resolved.

jbenet added a commit that referenced this pull request Aug 27, 2015
replace nodebuilder with a nicer interface
@jbenet jbenet merged commit b55cf12 into master Aug 27, 2015
@jbenet jbenet deleted the node-construct-v2 branch August 27, 2015 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants