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

In NewService, optionally set opts.RootDatastore to a persistent data store #92

Merged
merged 2 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 35 additions & 11 deletions service.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (
"unsafe"

pubsub_fix "github.com/berty/go-libp2p-pubsub"
"github.com/dgraph-io/badger/v2/options"
ds "github.com/ipfs/go-datastore"
ds_sync "github.com/ipfs/go-datastore/sync"
badger "github.com/ipfs/go-ds-badger2"
ipfs_interface "github.com/ipfs/interface-go-ipfs-core"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/crypto"
Expand Down Expand Up @@ -101,28 +103,47 @@ type Opts struct {
GroupMessageStoreType string
}

func (opts *Opts) applyPushDefaults() error {
func (opts *Opts) applyPushDefaults() {
if opts.Logger == nil {
opts.Logger = zap.NewNop()
}

if opts.PrometheusRegister == nil {
opts.PrometheusRegister = prometheus.DefaultRegisterer
}

opts.applyDefaultsGetDatastore()

return nil
}

func (opts *Opts) applyDefaultsGetDatastore() {
func (opts *Opts) applyDefaultsGetDatastore() error {
if opts.RootDatastore == nil {
if opts.DatastoreDir == "" || opts.DatastoreDir == InMemoryDirectory {
opts.RootDatastore = ds_sync.MutexWrap(ds.NewMapDatastore())
} else {
D4ryl00 marked this conversation as resolved.
Show resolved Hide resolved
opts.RootDatastore = nil
bopts := badger.DefaultOptions
bopts.ValueLogLoadingMode = options.FileIO

ds, err := badger.NewDatastore(opts.DatastoreDir, &bopts)
if err != nil {
return fmt.Errorf("unable to init badger datastore: %w", err)
}
opts.RootDatastore = ds

oldClose := opts.close
opts.close = func() error {
var err error
if oldClose != nil {
err = oldClose()
}

if dserr := ds.Close(); dserr != nil {
err = multierr.Append(err, fmt.Errorf("unable to close datastore: %w", dserr))
}

return err
}
}
}

return nil
}

func (opts *Opts) applyDefaults(ctx context.Context) error {
Expand All @@ -132,12 +153,12 @@ func (opts *Opts) applyDefaults(ctx context.Context) error {

rng := mrand.New(mrand.NewSource(srand.MustSecure())) // nolint:gosec // we need to use math/rand here, but it is seeded from crypto/rand

opts.applyDefaultsGetDatastore()

if err := opts.applyPushDefaults(); err != nil {
if err := opts.applyDefaultsGetDatastore(); err != nil {
return err
}

opts.applyPushDefaults()

if opts.SecretStore == nil {
secretStore, err := secretstore.NewSecretStore(opts.RootDatastore, &secretstore.NewSecretStoreOptions{
Logger: opts.Logger,
Expand Down Expand Up @@ -287,7 +308,10 @@ func (opts *Opts) applyDefaults(ctx context.Context) error {
return nil
}

// NewService initializes a new Service
// NewService initializes a new Service using the opts.
// If opts.RootDatastore is nil and opts.DatastoreDir is "" or InMemoryDirectory, then set
// opts.RootDatastore to an in-memory data store. Otherwise, if opts.RootDatastore is nil then set
// opts.RootDatastore to a persistent data store at opts.DatastoreDir .
func NewService(opts Opts) (_ Service, err error) {
ctx, cancel := context.WithCancel(context.Background())

Expand Down
24 changes: 5 additions & 19 deletions service_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ import (
"os"
"time"

"github.com/dgraph-io/badger/v2/options"
"github.com/ipfs/go-datastore"
badger "github.com/ipfs/go-ds-badger2"
"go.uber.org/zap"
"google.golang.org/grpc"

Expand All @@ -31,6 +28,10 @@ type ServiceClient interface {
io.Closer
}

// NewServiceClient initializes a new ServiceClient using the opts.
// If opts.RootDatastore is nil and opts.DatastoreDir is "" or InMemoryDirectory, then set
// opts.RootDatastore to an in-memory data store. Otherwise, if opts.RootDatastore is nil then set
// opts.RootDatastore to a persistent data store at opts.DatastoreDir .
func NewServiceClient(opts Opts) (ServiceClient, error) {
var err error

Expand Down Expand Up @@ -85,13 +86,7 @@ func NewInMemoryServiceClient() (ServiceClient, error) {
func NewPersistentServiceClient(path string) (ServiceClient, error) {
var opts Opts

bopts := badger.DefaultOptions
bopts.ValueLogLoadingMode = options.FileIO

ds, err := badger.NewDatastore(path, &bopts)
if err != nil {
return nil, fmt.Errorf("unable to init badger datastore: %w", err)
}
opts.DatastoreDir = path

repo, err := ipfsutil.LoadRepoFromPath(path)
if err != nil {
Expand All @@ -109,8 +104,6 @@ func NewPersistentServiceClient(path string) (ServiceClient, error) {
return nil, err
}

opts.RootDatastore = ds

var cleanupLogger func()
if opts.Logger, cleanupLogger, err = setupDefaultLogger(); err != nil {
return nil, fmt.Errorf("uanble to setup logger: %w", err)
Expand All @@ -123,7 +116,6 @@ func NewPersistentServiceClient(path string) (ServiceClient, error) {

return &persistentServiceClient{
ServiceClient: cl,
ds: ds,
cleanup: cleanupLogger,
}, nil
}
Expand All @@ -140,18 +132,12 @@ type serviceClient struct {

type persistentServiceClient struct {
ServiceClient
ds datastore.Batching
cleanup func()
}

func (p *persistentServiceClient) Close() error {
err := p.ServiceClient.Close()

if dserr := p.ds.Close(); err == nil && dserr != nil {
// only return ds error if no error have been catch earlier
err = fmt.Errorf("unable to close datastore: %w", dserr)
}

if p.cleanup != nil {
p.cleanup()
}
Expand Down
Loading