Skip to content

Commit

Permalink
feat(core): setup node<->sql bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
moul committed Jul 27, 2018
1 parent 51a2915 commit b5a1320
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 46 deletions.
2 changes: 1 addition & 1 deletion core/Makefile
Expand Up @@ -13,7 +13,7 @@ all: install

.PHONY: install
install: generate
go install -v ./cmd/...
$(BUILD_ENV) go install -v ./cmd/...

.PHONY: test
test: generate
Expand Down
85 changes: 50 additions & 35 deletions core/cmd/berty/daemon.go
Expand Up @@ -8,16 +8,21 @@ import (
"syscall"

reuse "github.com/libp2p/go-reuseport"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"

"github.com/berty/berty/core/node"
"github.com/berty/berty/core/sql"
"github.com/berty/berty/core/sql/sqlcipher"
)

type daemonOptions struct {
bind string
hideBanner bool
sqlPath string
sqlKey string
}

func newDaemonCommand() *cobra.Command {
Expand All @@ -31,73 +36,83 @@ func newDaemonCommand() *cobra.Command {
flags := cmd.Flags()
flags.StringVarP(&opts.bind, "bind", "", "0.0.0.0:1337", "gRPC listening address")
flags.BoolVar(&opts.hideBanner, "hide-banner", false, "hide banner")
flags.StringVarP(&opts.sqlPath, "sql-path", "", "/tmp/berty.db", "sqlcipher database path")
flags.StringVarP(&opts.sqlKey, "sql-key", "", "s3cur3", "sqlcipher database encryption key")
return cmd
}

func daemon(opts *daemonOptions) error {
// initialize dependencies
errChan := make(chan error)

// initialize gRPC
gs := grpc.NewServer()
reflection.Register(gs)
listener, err := reuse.Listen("tcp", opts.bind)
if err != nil {
return err
}

// initialize nodes
// initialize sql
db, err := sqlcipher.Open(opts.sqlPath, []byte(opts.sqlKey))
if err != nil {
return errors.Wrap(err, "failed to open sqlcipher")
}
defer db.Close()
if db, err = sql.Init(db); err != nil {
return errors.Wrap(err, "failed to initialize sql")
}

// initialize node
n := node.New(
node.WithP2PGrpcServer(gs),
node.WithNodeGrpcServer(gs),
node.WithSQL(db),
)
_ = n

// start grpc server(s)
go gs.Serve(listener)
go func() {
errChan <- gs.Serve(listener)
}()
if !opts.hideBanner {
fmt.Println(banner)
}
log.Printf("listening on %s", opts.bind)

// start node
go func() {
errChan <- n.Start()
}()

// signal handling
signal_chan := make(chan os.Signal, 1)
signal.Notify(signal_chan,
signalChan := make(chan os.Signal, 1)
signal.Notify(
signalChan,
syscall.SIGHUP,
syscall.SIGINT,
syscall.SIGTERM,
syscall.SIGQUIT)

exit_chan := make(chan int)
syscall.SIGQUIT,
)
go func() {
for {
s := <-signal_chan
s := <-signalChan
switch s {
// kill -SIGHUP XXXX
case syscall.SIGHUP:
fmt.Println("hungup")

// kill -SIGINT XXXX or Ctrl+c
case syscall.SIGINT:
exit_chan <- 0

// kill -SIGTERM XXXX
case syscall.SIGTERM:
fmt.Println("force stop")
exit_chan <- 0

// kill -SIGQUIT XXXX
case syscall.SIGQUIT:
fmt.Println("stop and core dump")
exit_chan <- 0

case syscall.SIGHUP: // kill -SIGHUP XXXX
log.Println("sighup received")
case syscall.SIGINT: // kill -SIGINT XXXX or Ctrl+c
log.Println("sigint received")
errChan <- nil
case syscall.SIGTERM: // kill -SIGTERM XXXX (force stop)
log.Println("sigterm received")
errChan <- nil
case syscall.SIGQUIT: // kill -SIGQUIT XXXX (stop and core dump)
log.Println("sigquit received")
errChan <- nil
default:
fmt.Println("Unknown signal.")
exit_chan <- 1
errChan <- fmt.Errorf("unknown signal received")
}
}
}()

code := <-exit_chan
if code != 0 {
os.Exit(code)
}
return nil
// exiting on first goroutine triggering an error
return <-errChan
}
18 changes: 15 additions & 3 deletions core/node/node.go
@@ -1,8 +1,14 @@
package node

type Node struct{}
import "github.com/jinzhu/gorm"

func New(opts ...nodeOptions) *Node {
// Node is the top-level object of a Berty peer
type Node struct {
db *gorm.DB
}

// New initializes a new Node object
func New(opts ...NewNodeOption) *Node {
n := &Node{}

for _, opt := range opts {
Expand All @@ -11,4 +17,10 @@ func New(opts ...nodeOptions) *Node {
return n
}

type nodeOptions func(n *Node)
// Start is the node's mainloop
func (n *Node) Start() error {
select {}
}

// NewNodeOption is a callback used to configure a Node during intiailization phase
type NewNodeOption func(n *Node)
16 changes: 13 additions & 3 deletions core/node/nodeapi.go
Expand Up @@ -10,42 +10,52 @@ import (
"github.com/berty/berty/core/api/node"
)

type nodeapi struct{}

func WithNodeGrpcServer(gs *grpc.Server) nodeOptions {
// WithNodeGrpcServer registers the Node as a 'berty.node' protobuf server implementation
func WithNodeGrpcServer(gs *grpc.Server) NewNodeOption {
return func(n *Node) {
node.RegisterServiceServer(gs, n)
}
}

//
// events
//

// EventList implements berty.node.EventList
func (n *Node) EventList(*node.Void, node.Service_EventListServer) error {
return fmt.Errorf("not implemented")
}

// EventStream implements berty.node.EventStream
func (n *Node) EventStream(*node.Void, node.Service_EventStreamServer) error {
return fmt.Errorf("not implemented")
}

//
// contacts
//

// ContactAcceptRequest implements berty.node.ContactAcceptRequest
func (n *Node) ContactAcceptRequest(context.Context, *entity.Contact) (*entity.Contact, error) {
return nil, fmt.Errorf("not implemented")
}

// ContactRequest implements berty.node.ContactRequest
func (n *Node) ContactRequest(context.Context, *node.ContactRequestInput) (*entity.Contact, error) {
return nil, fmt.Errorf("not implemented")
}

// ContactUpdate implements berty.node.ContactUpdate
func (n *Node) ContactUpdate(context.Context, *entity.Contact) (*entity.Contact, error) {
return nil, fmt.Errorf("not implemented")
}

// ContactRemove implements berty.node.ContactRemove
func (n *Node) ContactRemove(context.Context, *entity.Contact) (*entity.Contact, error) {
return nil, fmt.Errorf("not implemented")
}

// ContactList implements berty.node.ContactList
func (n *Node) ContactList(*node.Void, node.Service_ContactListServer) error {
return fmt.Errorf("not implemented")
}
6 changes: 3 additions & 3 deletions core/node/p2papi.go
Expand Up @@ -9,14 +9,14 @@ import (
"github.com/berty/berty/core/api/p2p"
)

type p2papi struct{}

func WithP2PGrpcServer(gs *grpc.Server) nodeOptions {
// WithP2PGrpcServer registers the Node as a 'berty.p2p' protobuf server implementation
func WithP2PGrpcServer(gs *grpc.Server) NewNodeOption {
return func(n *Node) {
p2p.RegisterServiceServer(gs, n)
}
}

// Handle implements berty.p2p.Handle
func (n *Node) Handle(context.Context, *p2p.Event) (*p2p.Void, error) {
return nil, fmt.Errorf("not implemented")
}
10 changes: 10 additions & 0 deletions core/node/sql.go
@@ -0,0 +1,10 @@
package node

import "github.com/jinzhu/gorm"

// WithSQL registers a gorm connection as the node database
func WithSQL(db *gorm.DB) NewNodeOption {
return func(n *Node) {
n.db = db
}
}
3 changes: 2 additions & 1 deletion core/sql/gorm_test.go
Expand Up @@ -5,8 +5,9 @@ import (
"os"
"testing"

"github.com/berty/berty/core/sql/sqlcipher"
. "github.com/smartystreets/goconvey/convey"

"github.com/berty/berty/core/sql/sqlcipher"
)

func TestInit(t *testing.T) {
Expand Down

0 comments on commit b5a1320

Please sign in to comment.