Skip to content
Snippets Groups Projects
serve.go 2.63 KiB
Newer Older
Androlo's avatar
Androlo committed
package erisdb

import (
	"fmt"
	ep "github.com/eris-ltd/erisdb/erisdb/pipe"
Androlo's avatar
Androlo committed
	"github.com/eris-ltd/erisdb/server"
	"github.com/tendermint/log15"
Androlo's avatar
Androlo committed
	. "github.com/tendermint/tendermint/common"
	cfg "github.com/tendermint/tendermint/config"
	tmcfg "github.com/tendermint/tendermint/config/tendermint"
Androlo's avatar
Androlo committed
	"github.com/tendermint/tendermint/node"
	"github.com/tendermint/tendermint/p2p"
	"path"
Androlo's avatar
Androlo committed
)

var log = log15.New("module", "eris/erisdb_server")
var tmConfig cfg.Config

func init() {
	cfg.OnConfig(func(newConfig cfg.Config) {
Androlo's avatar
Androlo committed
		fmt.Println("NEWCONFIG")
Androlo's avatar
Androlo committed
		tmConfig = newConfig
	})
}

// This function returns a properly configured ErisDb server process with a running
// tendermint node attached to it. To start listening for incoming requests, call
// 'Start()' on the process. Make sure to register any start event listeners before
// that.
func ServeErisDB(workDir string) (*server.ServeProcess, error) {
	log.Info("ErisDB Serve initializing.")
	errEns := EnsureDir(workDir)

	if errEns != nil {
		return nil, errEns
	}
Androlo's avatar
Androlo committed

Androlo's avatar
Androlo committed
	var sConf *server.ServerConfig
Androlo's avatar
Androlo committed

Androlo's avatar
Androlo committed
	sConfPath := path.Join(workDir, "server_conf.toml")
	if !FileExists(sConfPath) {
		sConf = server.DefaultServerConfig()
		server.WriteServerConfig(sConfPath, sConf)
	} else {
		var errRSC error
		sConf, errRSC = server.ReadServerConfig(sConfPath)
		if errRSC != nil {
			log.Error("Server config file error.", "error", errRSC.Error())
		}
	}
Androlo's avatar
Androlo committed

Androlo's avatar
Androlo committed
	// Get tendermint configuration
	tmConfig = tmcfg.GetConfig(workDir)
	cfg.ApplyConfig(tmConfig) // Notify modules of new config
Androlo's avatar
Androlo committed

Androlo's avatar
Androlo committed
	// Set the node up.
	nodeRd := make(chan struct{})
	nd := node.NewNode()
	// Load the supporting objects.
	pipe := ep.NewPipe(nd)
	codec := &TCodec{}
Androlo's avatar
Androlo committed
	evtSubs := NewEventSubscriptions(pipe.Events())
Androlo's avatar
Androlo committed
	// The services.
	tmwss := NewErisDbWsService(codec, pipe)
	tmjs := NewErisDbJsonService(codec, pipe, evtSubs)
	// The servers.
	jsonServer := NewJsonRpcServer(tmjs)
	restServer := NewRestServer(codec, pipe, evtSubs)
Androlo's avatar
Androlo committed
	wsServer := server.NewWebSocketServer(sConf.WebSocket.MaxWebSocketSessions, tmwss)
Androlo's avatar
Androlo committed
	// Create a server process.
	proc := server.NewServeProcess(sConf, jsonServer, restServer, wsServer)
Androlo's avatar
Androlo committed

Androlo's avatar
Androlo committed
	stopChan := proc.StopEventChannel()
	go startNode(nd, nodeRd, stopChan)
Androlo's avatar
Androlo committed
	<-nodeRd
Androlo's avatar
Androlo committed
	return proc, nil
}

// Private. Create a new node
Androlo's avatar
Androlo committed
func startNode(nd *node.Node, ready chan struct{}, shutDown <-chan struct{}) {
Androlo's avatar
Androlo committed
	laddr := tmConfig.GetString("node_laddr")
	if laddr != "" {
		l := p2p.NewDefaultListener("tcp", laddr, false)
Androlo's avatar
Androlo committed
		nd.AddListener(l)
Androlo's avatar
Androlo committed
	}
Androlo's avatar
Androlo committed

Androlo's avatar
Androlo committed
	nd.Start()

	// If seedNode is provided by config, dial out.
Androlo's avatar
Androlo committed

Androlo's avatar
Androlo committed
	if len(tmConfig.GetString("seeds")) > 0 {
		nd.DialSeed()
	}
Androlo's avatar
Androlo committed

Androlo's avatar
Androlo committed
	ready <- struct{}{}
	// Block until everything is shut down.
Androlo's avatar
Androlo committed
	<-shutDown
Androlo's avatar
Androlo committed
	nd.Stop()
Androlo's avatar
Androlo committed
}