Skip to content

Commit

Permalink
misc fixes, faster startup time
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Luzzardi <[email protected]>
  • Loading branch information
aluzzardi committed Dec 6, 2018
1 parent e74fca2 commit f30e1c0
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 136 deletions.
15 changes: 8 additions & 7 deletions builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,23 @@ import (

// Builder is a wrapper around `docker build` which provides a better UX.
type Builder struct {
image string
parser *Parser
rootDir string
image string
parser *Parser
}

// BuildOpts contains a list of build options.
type BuildOpts struct {
RootDir string
Verbose bool
NoCache bool
}

// New creates a new Builder.
func New(image string) *Builder {
func New(rootDir, image string) *Builder {
return &Builder{
image: image,
parser: &Parser{},
rootDir: rootDir,
image: image,
parser: &Parser{},
}
}

Expand All @@ -37,7 +38,7 @@ func (b *Builder) Build(ctx context.Context, opts BuildOpts) error {
if opts.NoCache {
args = append(args, "--no-cache")
}
args = append(args, opts.RootDir)
args = append(args, b.rootDir)
cmd := exec.CommandContext(ctx, "docker", args...)
outReader, err := cmd.StdoutPipe()
if err != nil {
Expand Down
6 changes: 2 additions & 4 deletions cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,12 @@ var buildCmd = &cobra.Command{
ui.Fatal("%v", err)
}

ui.Info("Building %s", p.Name)

b := builder.New(p.Image)
b := builder.New(rootDir, p.Image)
opts := builder.BuildOpts{
RootDir: rootDir,
Verbose: verbose,
NoCache: noCache,
}
ui.Info("Building %s", p.Name)
if err := b.Build(ctx, opts); err != nil {
ui.Fatal("Failed to build the application: %v", err)
}
Expand Down
5 changes: 3 additions & 2 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ var createCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
name := args[0]
rootDir := getCwd(cmd)
rootDir := path.Join(getCwd(cmd), name)
p := project.New(name)
create(rootDir, p)
},
Expand All @@ -53,7 +53,8 @@ func create(rootDir string, p *project.Project) {
ui.Fatal("Failed to initialize: %v", err)
}

b := builder.New(p.Name)
ui.Info("Building %s", p.Name)
b := builder.New(rootDir, p.Image)
if err := b.Build(ctx, builder.BuildOpts{}); err != nil {
ui.Fatal("Failed to build the application: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (c *Config) StateDir() string {

// LogFile returns the log file path
func (c *Config) LogFile() string {
return path.Join(c.StateDir(), "log")
return path.Join(c.RootDir, "log")
}

// DataDir returns the data directory within the project state.
Expand Down
151 changes: 64 additions & 87 deletions discovery/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"os"
"path"
"path/filepath"
"sort"
"sync"
"time"

"github.com/blocklayerhq/chainkit/project"
Expand Down Expand Up @@ -47,23 +45,39 @@ var (
}
)

// PeerInfo contains information about one peer.
type PeerInfo struct {
NodeID string `json:"node_id"`
IP []string `json:"ips"`
TendermintP2PPort int `json:"tendermint_p2p_port"`
}

// Server is the discovery server
type Server struct {
root string
port int
node *core.IpfsNode
api iface.CoreAPI
dht *dht.IpfsDHT

dht *dht.IpfsDHT
connectedCh chan (struct{})

api iface.CoreAPI
}

// New returns a new discovery server
func New(root string, port int) *Server {
return &Server{
root: root,
port: port,
root: root,
port: port,
connectedCh: make(chan struct{}),
}
}

// Stop must be called after start
func (s *Server) Stop() error {
return s.node.Close()
}

// Start starts the discovery server
func (s *Server) Start(ctx context.Context) error {
daemonLocked, err := fsrepo.LockedByOtherProcess(s.root)
Expand Down Expand Up @@ -111,7 +125,8 @@ func (s *Server) Start(ctx context.Context) error {
if err != nil {
return err
}
s.dhtConnect(ctx)

go s.dhtConnect(ctx)

return nil
}
Expand All @@ -127,34 +142,20 @@ func (s *Server) ipfsInit() error {
return fsrepo.Init(s.root, conf)
}

// Stop must be called after start
func (s *Server) Stop() error {
return s.node.Close()
}

// ListenAddresses returns the IPFS listening addresses for the server
func (s *Server) ListenAddresses() []string {
ifaceAddrs, err := s.node.PeerHost.Network().InterfaceListenAddresses()
if err != nil {
panic(err)
}

var addrs []string
for _, addr := range ifaceAddrs {
addrs = append(addrs, addr.String())
}
sort.Sort(sort.StringSlice(addrs))
return addrs
}
func (s *Server) dhtConnect(ctx context.Context) {
defer close(s.connectedCh)
for _, peerAddr := range bootstrapPeers {
addr, _ := iaddr.ParseString(peerAddr)
peerinfo, _ := pstore.InfoFromP2pAddr(addr.Multiaddr())

// AnnounceAddresses returns the announce addresses of IPFS
func (s *Server) AnnounceAddresses() []string {
var addrs []string
for _, addr := range s.node.PeerHost.Addrs() {
addrs = append(addrs, addr.String())
err := s.node.PeerHost.Connect(ctx, *peerinfo)
if err != nil {
ui.Error("Connection with bootstrap node %v failed: %v", *peerinfo, err)
continue
}
ui.Verbose("Connection established with bootstrap node: %v", *peerinfo)
}
sort.Sort(sort.StringSlice(addrs))
return addrs
ui.Info("connect done")
}

// Publish publishes chain information. Returns the chain ID.
Expand Down Expand Up @@ -192,55 +193,6 @@ func (s *Server) Publish(ctx context.Context, manifestPath, genesisPath, imagePa
return p.String(), nil
}

// Announce announces our presence as a network node.
func (s *Server) Announce(ctx context.Context, chainID string, peer *PeerInfo) error {
id, err := cid.Decode(filepath.Base(chainID))
if err != nil {
return err
}

s.node.PeerHost.SetStreamHandler("/chainkit/0.1.0", func(stream net.Stream) {
defer stream.Close()
enc := json.NewEncoder(stream)
if err := enc.Encode(peer); err != nil {
ui.Error("failed to encode: %v", err)
return
}
})

cctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
if err := s.dht.Provide(cctx, id, true); err != nil {
return err
}
return nil
}

func (s *Server) dhtConnect(ctx context.Context) {
connect := func(peerAddr string) error {
addr, _ := iaddr.ParseString(peerAddr)
peerinfo, _ := pstore.InfoFromP2pAddr(addr.Multiaddr())

err := s.node.PeerHost.Connect(ctx, *peerinfo)
if err != nil {
ui.Error("%v", err)
return err
}
ui.Verbose("Connection established with bootstrap node: %v", *peerinfo)
return nil
}

wg := sync.WaitGroup{}
for _, peerAddr := range bootstrapPeers {
wg.Add(1)
go func(peerAddr string) {
defer wg.Done()
connect(peerAddr)
}(peerAddr)
}
wg.Wait()
}

// Join joins a network.
func (s *Server) Join(ctx context.Context, chainID, manifestPath string) (*project.Project, []byte, error) {
manifest, genesis, image, err := s.getNetworkMetadata(ctx, chainID)
Expand Down Expand Up @@ -305,15 +257,40 @@ func (s *Server) getNetworkMetadata(ctx context.Context, chainID string) (io.Rea
return manifestFile, genesisFile, imageFile, nil
}

// PeerInfo contains information about one peer.
type PeerInfo struct {
NodeID string `json:"node_id"`
IP []string `json:"ips"`
TendermintP2PPort int `json:"tendermint_p2p_port"`
// Announce announces our presence as a network node.
func (s *Server) Announce(ctx context.Context, chainID string, peer *PeerInfo) error {
// Wait for the DHT to be connected before searching.
<-s.connectedCh

id, err := cid.Decode(filepath.Base(chainID))
if err != nil {
return err
}

s.node.PeerHost.SetStreamHandler("/chainkit/0.1.0", func(stream net.Stream) {
defer stream.Close()
enc := json.NewEncoder(stream)
if err := enc.Encode(peer); err != nil {
ui.Error("failed to encode: %v", err)
return
}
})

cctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
if err := s.dht.Provide(cctx, id, true); err != nil {
return err
}
return nil
}

// SearchPeers looks for peers in the network
func (s *Server) SearchPeers(ctx context.Context, chainID string) (<-chan *PeerInfo, error) {
// Wait for the DHT to be connected before searching.
ui.Info("waiting for connection")
<-s.connectedCh
ui.Info("wait done")

id, err := cid.Decode(filepath.Base(chainID))
if err != nil {
return nil, err
Expand Down
8 changes: 0 additions & 8 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,6 @@ func (n *Node) Start(ctx context.Context, p *project.Project, genesis []byte) er
return err
}

for _, addr := range n.discovery.ListenAddresses() {
ui.Verbose("IPFS Swarm listening on %s", addr)
}

for _, addr := range n.discovery.AnnounceAddresses() {
ui.Verbose("IPFS Swarm announcing %s", addr)
}

// Create a network.
chainID, err := n.createNetwork(n.parentCtx, p)
if err != nil {
Expand Down
48 changes: 24 additions & 24 deletions templates/assets_vfsdata.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions templates/src/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@

# State folder
/state
/log
3 changes: 0 additions & 3 deletions util/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ import (
"os"
"os/exec"
"path"
"strings"
"syscall"
"time"

"github.com/blocklayerhq/chainkit/config"
"github.com/blocklayerhq/chainkit/project"
"github.com/blocklayerhq/chainkit/ui"
)

// DockerRun runs a command within the project's container.
Expand Down Expand Up @@ -49,7 +47,6 @@ func Run(ctx context.Context, command string, args ...string) error {

// RunWithFD is like Run, but accepts custom stdin/stdout/stderr.
func RunWithFD(ctx context.Context, stdin io.Reader, stdout, stderr io.Writer, command string, args ...string) error {
ui.Verbose("$ %s %s", command, strings.Join(args, " "))
cmd := exec.Command(command)
cmd.Args = append([]string{command}, args...)
cmd.Stdin = stdin
Expand Down

0 comments on commit f30e1c0

Please sign in to comment.