Skip to content

Commit

Permalink
Share PGSQL connection pool between ledgers.
Browse files Browse the repository at this point in the history
To do this, we introduce a storage.Driver interface between the storage.Factory and the Store implementations.
This interface is in charge of initializing the connection to the underlying database (in case of PGSQL, create the pool) and create the underlying stores for ledgers.
  • Loading branch information
Geoffrey Ragot authored and gfyrag committed Dec 9, 2021
1 parent cb5c6fc commit 1db8bca
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 49 deletions.
14 changes: 12 additions & 2 deletions ledger/ledger_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package ledger

import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/jackc/pgx/v4/pgxpool"

"io/ioutil"
"log"
"math/rand"
Expand Down Expand Up @@ -57,7 +60,14 @@ func TestMain(m *testing.M) {
viper.Set("storage.sqlite.db_name", "ledger")
os.Remove(path.Join(os.TempDir(), "ledger_test.db"))
case "postgres":
store, err := postgres.NewStore("test")
pool, err := pgxpool.Connect(
context.Background(),
viper.GetString("storage.postgres.conn_string"),
)
if err != nil {
panic(err)
}
store, err := postgres.NewStore("test", pool)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -446,7 +456,7 @@ func TestRevertTransaction(t *testing.T) {
})
}

func BenchmarkTransaction1(b *testing.B) {
func markTransaction1(b *testing.B) {
with(func(l *Ledger) {
for n := 0; n < b.N; n++ {
txs := []core.Transaction{}
Expand Down
43 changes: 8 additions & 35 deletions storage/postgres/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,25 @@ import (
"strings"

"github.com/jackc/pgx/v4/pgxpool"
"github.com/spf13/viper"
)

//go:embed migration
var migrations embed.FS

type PGStore struct {
ledger string
connString string
pool *pgxpool.Pool
}

func (s *PGStore) connect() error {
log.Println("initiating postgres pool")

pool, err := pgxpool.Connect(
context.Background(),
s.connString,
)

if err != nil {
return err
}

s.pool = pool

return nil
ledger string
pool *pgxpool.Pool
}

func (s *PGStore) Conn() *pgxpool.Pool {
return s.pool
}

func NewStore(name string) (*PGStore, error) {
store := &PGStore{
ledger: name,
connString: viper.GetString("storage.postgres.conn_string"),
}

err := store.connect()

if err != nil {
return store, err
}

return store, nil
func NewStore(name string, pool *pgxpool.Pool) (*PGStore, error) {
return &PGStore{
ledger: name,
pool: pool,
}, nil
}

func (s *PGStore) Initialize() error {
Expand Down Expand Up @@ -105,7 +78,7 @@ func (s *PGStore) table(name string) string {
}

func (s *PGStore) Close() {
s.pool.Close()
//s.pool.Close()
}

func (s *PGStore) DropTest() {
Expand Down
85 changes: 73 additions & 12 deletions storage/storage.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package storage

import (
"context"
"github.com/jackc/pgx/v4/pgxpool"
"github.com/numary/ledger/core"
"github.com/numary/ledger/ledger/query"
"github.com/numary/ledger/storage/postgres"
"github.com/numary/ledger/storage/sqlite"
"github.com/pkg/errors"
"github.com/spf13/viper"
"log"
"sync"
)

type Store interface {
Expand All @@ -25,22 +29,79 @@ type Store interface {
Close()
}

func GetStore(name string) (Store, error) {
driver := viper.GetString("storage.driver")
type Driver interface {
Initialize() error
NewStore(name string) (Store, error)
}

var builtInDrivers = make(map[string]Driver)

func RegisterDriver(name string, driver Driver) {
builtInDrivers[name] = driver
}

switch driver {
case "sqlite":
return sqlite.NewStore(name)
case "postgres":
return postgres.NewStore(name)
type SQLiteSDriver struct {}

func (d *SQLiteSDriver) Initialize() error {
return nil
}

func (d *SQLiteSDriver) NewStore(name string) (Store, error) {
return sqlite.NewStore(name)
}

type PGSqlDriver struct {
once sync.Once
pool *pgxpool.Pool
}

func (d *PGSqlDriver) Initialize() error {
errCh := make(chan error, 1)
d.once.Do(func() {
log.Println("initiating postgres pool")

pool, err := pgxpool.Connect(
context.Background(),
viper.GetString("storage.postgres.conn_string"),
)
if err != nil {
errCh <- err
}
d.pool = pool
errCh <- nil
})
select {
case err := <- errCh:
return err
default:
break
return nil
}
}

func (d *PGSqlDriver) NewStore(name string) (Store, error) {
return postgres.NewStore(name, d.pool)
}

func init() {
RegisterDriver("sqlite", &SQLiteSDriver{})
RegisterDriver("postgres", &PGSqlDriver{})
}

func GetStore(name string) (Store, error) {
driverStr := viper.GetString("storage.driver")
driver, ok := builtInDrivers[driverStr]
if !ok {
panic(errors.Errorf(
"unsupported store: %s",
driver,
))
}
err := driver.Initialize()
if err != nil {
return nil, errors.Wrap(err, "initializing driver")
}

panic(errors.Errorf(
"unsupported store: %s",
driver,
))
return driver.NewStore(name)
}

type Factory interface {
Expand Down

3 comments on commit 1db8bca

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leger Bench for SQLite

Benchmark suite Current: 1db8bca Previous: 5a2de8f Ratio
BenchmarkTransaction_20_1k 989508114 ns/op 771735100 ns/op 1.28
BenchmarkGetAccount 18552806 ns/op 17587361 ns/op 1.05
BenchmarkFindTransactions 620298 ns/op 494158 ns/op 1.26

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leger Bench for PostgreSQL

Benchmark suite Current: 1db8bca Previous: 5a2de8f Ratio
BenchmarkTransaction_20_1k 7546015044 ns/op 11028919519 ns/op 0.68
BenchmarkGetAccount 7120867 ns/op 10026448 ns/op 0.71
BenchmarkFindTransactions 2541482 ns/op 694444 ns/op 3.66

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Leger Bench for PostgreSQL'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: 1db8bca Previous: 5a2de8f Ratio
BenchmarkFindTransactions 2541482 ns/op 694444 ns/op 3.66

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.