Skip to content

Commit

Permalink
fixes node tests (ethereum#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
renaynay committed Jul 21, 2020
1 parent 0fa792d commit 3488916
Show file tree
Hide file tree
Showing 9 changed files with 247 additions and 502 deletions.
11 changes: 0 additions & 11 deletions node/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,6 @@ func convertFileLockError(err error) error {
return err
}

// DuplicateServiceError is returned during Node startup if a registered service
// constructor returns a service of the same type that was already started.
type DuplicateServiceError struct {
Kind reflect.Type
}

// Error generates a textual representation of the duplicate service error.
func (e *DuplicateServiceError) Error() string {
return fmt.Sprintf("duplicate service: %v", e.Kind)
}

// StopError is returned if a Node fails to stop either any of its registered
// services or itself.
type StopError struct {
Expand Down
69 changes: 36 additions & 33 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type Node struct {

ServiceContext *ServiceContext

lifecycles []Lifecycle // All registered backends, services, and auxiliary services that have a lifecycle
lifecycles map[reflect.Type]Lifecycle // All registered backends, services, and auxiliary services that have a lifecycle

rpcAPIs []rpc.API // List of APIs currently provided by the node
inprocHandler *rpc.Server // In-process RPC request handler to process the API requests
Expand Down Expand Up @@ -107,8 +107,10 @@ func New(conf *Config) (*Node, error) {
accman: am,
ephemeralKeystore: ephemeralKeystore,
config: conf,
lifecycles: make(map[reflect.Type]Lifecycle),
ServiceContext: &ServiceContext{
Config: *conf,
Lifecycles: make(map[reflect.Type]Lifecycle),
},
httpServers: make([]*HTTPServer, 0),
ipc: &HTTPServer{
Expand Down Expand Up @@ -199,12 +201,12 @@ func (n *Node) Close() error {

// RegisterLifecycle registers the given Lifecycle on the node
func (n *Node) RegisterLifecycle(lifecycle Lifecycle) {
for _, existing := range n.lifecycles {
if existing == lifecycle {
Fatalf("Lifecycle cannot be registered more than once", lifecycle)
}
kind := reflect.TypeOf(lifecycle)
if _, exists := n.lifecycles[kind]; exists {
Fatalf("Lifecycle cannot be registered more than once", kind)
}
n.lifecycles = append(n.lifecycles, lifecycle)

n.lifecycles[kind] = lifecycle
}

// RegisterProtocols adds backend's protocols to the node's p2p server
Expand Down Expand Up @@ -265,7 +267,7 @@ func (n *Node) CreateHTTPServer(h *HTTPServer, exposeAll bool) error {

// running returns true if the node's p2p server is already running
func (n *Node) running() bool {
return n.server.Listening()
return n.server.Running()
}

// Start creates a live P2P node and starts running it.
Expand All @@ -289,9 +291,8 @@ func (n *Node) Start() error {

// TODO running p2p server needs to somehow be added to the backend

// Start the configured RPC interfaces
if err := n.startRPC(); err != nil {
n.stopLifecycles(n.lifecycles)
// Configure the RPC interfaces
if err := n.configureRPC(); err != nil {
n.server.Stop()
return err
}
Expand All @@ -301,8 +302,11 @@ func (n *Node) Start() error {
for _, lifecycle := range n.lifecycles {
if err := lifecycle.Start(); err != nil {
n.stopLifecycles(started)
n.server.Stop()
return err
}
started = append(started, lifecycle)
n.ServiceContext.Lifecycles[reflect.TypeOf(lifecycle)] = lifecycle
}

// Finish initializing the service context
Expand Down Expand Up @@ -478,15 +482,7 @@ func (n *Node) stopServer(server *HTTPServer) {

// removeLifecycle removes a stopped Lifecycle from the running node's Lifecycles
func (n *Node) removeLifecycle(lifecycle Lifecycle) {
remainingLifecycles := make([]Lifecycle, len(n.lifecycles)-1)
index := 0
for _, remaining := range n.lifecycles {
if remaining != lifecycle {
remainingLifecycles[index] = remaining
index ++
}
}
n.lifecycles = remainingLifecycles
delete(n.lifecycles, reflect.TypeOf(lifecycle))
}

// Stop terminates a running node along with all it's services. In the node was
Expand All @@ -496,7 +492,7 @@ func (n *Node) Stop() error {
defer n.lock.Unlock()

// Short circuit if the node's not running
if n.server == nil {
if n.server == nil || !n.running() {
return ErrNodeStopped
}

Expand All @@ -506,10 +502,11 @@ func (n *Node) Stop() error {
failure := &StopError{
Services: make(map[reflect.Type]error),
}
for _, lifecycle := range n.lifecycles {
for kind, lifecycle := range n.lifecycles {
if err := lifecycle.Stop(); err != nil {
failure.Services[reflect.TypeOf(lifecycle)] = err
}
delete(n.lifecycles, kind)
}
n.server.Stop()
n.server = nil
Expand Down Expand Up @@ -554,18 +551,6 @@ func (n *Node) Wait() {
<-stop
}

// Restart terminates a running node and boots up a new one in its place. If the
// node isn't running, an error is returned.
func (n *Node) Restart() error {
if err := n.Stop(); err != nil {
return err
}
if err := n.Start(); err != nil {
return err
}
return nil
}

// Attach creates an RPC client attached to an in-process API handler.
func (n *Node) Attach() (*rpc.Client, error) {
n.lock.RLock()
Expand Down Expand Up @@ -695,6 +680,24 @@ func (n *Node) ResolvePath(x string) string {
return n.config.ResolvePath(x)
}

// Lifecycle retrieves a currently running Lifecycle registered of a specific type.
func (n *Node) Lifecycle(lifecycle interface{}) error {
n.lock.RLock()
defer n.lock.RUnlock()

// Short circuit if the node's not running
if !n.running() {
return ErrNodeStopped
}
// Otherwise try to find the service to return
element := reflect.ValueOf(lifecycle).Elem()
if running, ok := n.lifecycles[element.Type()]; ok {
element.Set(reflect.ValueOf(running))
return nil
}
return ErrServiceUnknown
}

// apis returns the collection of RPC descriptors this node offers.
func (n *Node) apis() []rpc.API {
return []rpc.API{
Expand Down
7 changes: 1 addition & 6 deletions node/node_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type SampleLifecycle struct{}
func (s *SampleLifecycle) Start() error { fmt.Println("Service starting..."); return nil }
func (s *SampleLifecycle) Stop() error { fmt.Println("Service stopping..."); return nil }

func ExampleService() {
func ExampleLifecycle() {
// Create a network node to run protocols with the default values.
stack, err := node.New(&node.Config{})
if err != nil {
Expand All @@ -50,15 +50,10 @@ func ExampleService() {
if err := stack.Start(); err != nil {
log.Fatalf("Failed to start the protocol stack: %v", err)
}
if err := stack.Restart(); err != nil {
log.Fatalf("Failed to restart the protocol stack: %v", err)
}
if err := stack.Stop(); err != nil {
log.Fatalf("Failed to stop the protocol stack: %v", err)
}
// Output:
// Service starting...
// Service stopping...
// Service starting...
// Service stopping...
}
Loading

0 comments on commit 3488916

Please sign in to comment.