Skip to content

Commit 94abfa7

Browse files
authored
Support master standby connections (#10)
* Support master standby connections * fix coverage * update readme * update test env * Bump REL v0.28.0
1 parent 2c17aeb commit 94abfa7

File tree

7 files changed

+135
-12
lines changed

7 files changed

+135
-12
lines changed

.github/workflows/test.yml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ on:
77
branches: [ main ]
88

99
jobs:
10-
test:
11-
name: Test
10+
postgresql:
11+
name: PostgreSQL
1212
strategy:
1313
matrix:
1414
postgres: [9, 10, 11, 12, 13]
@@ -42,3 +42,20 @@ jobs:
4242
- name: Codecov
4343
uses: codecov/codecov-action@v1
4444
if: matrix.postgres == 13
45+
46+
primaryreplica:
47+
name: Primary Replica
48+
runs-on: ubuntu-latest
49+
steps:
50+
- name: Set up Go 1.x
51+
uses: actions/setup-go@v2
52+
- name: Check out code into the Go module directory
53+
uses: actions/checkout@v2
54+
- name: Start posgresql containers
55+
run: docker-compose -f "docker-compose.yml" up -d --build
56+
- name: Test
57+
env:
58+
TEST_PRIMARY_REPLICA: 'true'
59+
run: |
60+
sleep 15
61+
go test -race -tags=primaryreplica ./...

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,34 @@ func main() {
3535
}
3636
```
3737

38+
## Example Replication (Master/Standby)
39+
40+
```go
41+
package main
42+
43+
import (
44+
"context"
45+
46+
"github.com/go-rel/primaryreplica"
47+
_ "github.com/lib/pq"
48+
"github.com/go-rel/postgres"
49+
"github.com/go-rel/rel"
50+
)
51+
52+
func main() {
53+
// open postgres connections.
54+
adapter := primaryreplica.New(
55+
postgres.MustOpen("postgres://postgres@master/rel_test?sslmode=disable"),
56+
postgres.MustOpen("postgres://postgres@standby/rel_test?sslmode=disable"),
57+
)
58+
defer adapter.Close()
59+
60+
// initialize REL's repo.
61+
repo := rel.New(adapter)
62+
repo.Ping(context.TODO())
63+
}
64+
```
65+
3866
## Supported Driver
3967

4068
- github.com/lib/pq

docker-compose.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
version: '2'
2+
3+
services:
4+
postgresql-master:
5+
image: docker.io/bitnami/postgresql:13
6+
ports:
7+
- '25432:5432'
8+
environment:
9+
- POSTGRESQL_REPLICATION_MODE=master
10+
- POSTGRESQL_REPLICATION_USER=repl_user
11+
- POSTGRESQL_REPLICATION_PASSWORD=repl_password
12+
- POSTGRESQL_USERNAME=rel
13+
- POSTGRESQL_PASSWORD=rel
14+
- POSTGRESQL_DATABASE=rel_test
15+
- ALLOW_EMPTY_PASSWORD=yes
16+
postgresql-slave:
17+
image: docker.io/bitnami/postgresql:13
18+
ports:
19+
- '25433:5432'
20+
depends_on:
21+
- postgresql-master
22+
environment:
23+
- POSTGRESQL_REPLICATION_MODE=slave
24+
- POSTGRESQL_REPLICATION_USER=repl_user
25+
- POSTGRESQL_REPLICATION_PASSWORD=repl_password
26+
- POSTGRESQL_MASTER_HOST=postgresql-master
27+
- POSTGRESQL_PASSWORD=rel
28+
- POSTGRESQL_MASTER_PORT_NUMBER=5432
29+
- ALLOW_EMPTY_PASSWORD=yes

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ module github.com/go-rel/postgres
33
go 1.17
44

55
require (
6-
github.com/go-rel/rel v0.27.0
6+
github.com/go-rel/primaryreplica v0.1.0
7+
github.com/go-rel/rel v0.28.0
78
github.com/go-rel/sql v0.5.0
89
github.com/lib/pq v1.10.3
910
github.com/stretchr/testify v1.7.0

go.sum

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
44
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
55
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
66
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
7-
github.com/go-rel/rel v0.27.0 h1:Z9NOScAMwu54sxXmL/gET5+qKkisTS95MIk6uH/+r9Y=
7+
github.com/go-rel/primaryreplica v0.1.0 h1:ARt8QHa55Tmz7hJYtGunz4B3THQiFDOJb0yZBgnrzx4=
8+
github.com/go-rel/primaryreplica v0.1.0/go.mod h1:j/b9RmL4gdnuQMh4UPBeE1h6RpQCtiUIC9QHIvgjIs8=
89
github.com/go-rel/rel v0.27.0/go.mod h1:zaIYPmM3AfJrh0xBmm7KoVKRgTNvr0cgZfcJ88gVA2U=
10+
github.com/go-rel/rel v0.28.0 h1:gRcQjNbwuFL35RxeHFMKSy3a/xV+WbtkA8wP24dWPEA=
11+
github.com/go-rel/rel v0.28.0/go.mod h1:zaIYPmM3AfJrh0xBmm7KoVKRgTNvr0cgZfcJ88gVA2U=
912
github.com/go-rel/sql v0.5.0 h1:+TVS9JvEl06Q8rswwuWlY6VZ+gwSBX9um+vKuZ9gsyY=
1013
github.com/go-rel/sql v0.5.0/go.mod h1:2YwenlIaHpTqdD/KPVYG7Y5Ub1+sn1winlC8TrighRU=
1114
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=

postgres.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ func Open(dsn string) (rel.Adapter, error) {
6464
return New(database), err
6565
}
6666

67+
// MustOpen postgres connection using dsn.
68+
func MustOpen(dsn string) rel.Adapter {
69+
var database, err = db.Open("postgres", dsn)
70+
check(err)
71+
return New(database)
72+
}
73+
6774
// Insert inserts a record to database and returns its id.
6875
func (p Postgres) Insert(ctx context.Context, query rel.Query, primaryField string, mutates map[string]rel.Mutate) (interface{}, error) {
6976
var (
@@ -176,3 +183,9 @@ func columnMapper(column *rel.Column) (string, int, int) {
176183

177184
return typ, m, n
178185
}
186+
187+
func check(err error) {
188+
if err != nil {
189+
panic(err)
190+
}
191+
}

postgres_test.go

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package postgres
22

33
import (
44
"context"
5+
"errors"
56
"os"
67
"testing"
78
"time"
89

10+
"github.com/go-rel/primaryreplica"
911
"github.com/go-rel/rel"
1012
"github.com/go-rel/rel/adapter/specs"
1113
_ "github.com/lib/pq"
@@ -24,16 +26,10 @@ func dsn() string {
2426
return os.Getenv("POSTGRESQL_DATABASE") + "?sslmode=disable&timezone=Asia/Jakarta"
2527
}
2628

27-
return "postgres://rel@localhost:5432/rel_test?sslmode=disable&timezone=Asia/Jakarta"
29+
return "postgres://rel:rel@localhost:25432/rel_test?sslmode=disable&timezone=Asia/Jakarta"
2830
}
2931

30-
func TestAdapter_specs(t *testing.T) {
31-
adapter, err := Open(dsn())
32-
assert.Nil(t, err)
33-
defer adapter.Close()
34-
35-
repo := rel.New(adapter)
36-
32+
func AdapterSpecs(t *testing.T, repo rel.Repository) {
3733
// Prepare tables
3834
teardown := specs.Setup(t, repo)
3935
defer teardown()
@@ -101,6 +97,36 @@ func TestAdapter_specs(t *testing.T) {
10197
specs.CheckConstraintOnUpdate(t, repo)
10298
}
10399

100+
func TestAdapter_specs(t *testing.T) {
101+
if os.Getenv("TEST_PRIMARY_REPLICA") == "true" {
102+
t.Log("Skipping single node specs")
103+
return
104+
}
105+
106+
adapter := MustOpen(dsn())
107+
defer adapter.Close()
108+
109+
repo := rel.New(adapter)
110+
AdapterSpecs(t, repo)
111+
}
112+
113+
func TestAdapter_PrimaryReplica_specs(t *testing.T) {
114+
if os.Getenv("TEST_PRIMARY_REPLICA") != "true" {
115+
t.Log("Skipping primary replica specs")
116+
return
117+
}
118+
119+
adapter := primaryreplica.New(
120+
MustOpen("postgres://rel:rel@localhost:25432/rel_test?sslmode=disable&timezone=Asia/Jakarta"),
121+
MustOpen("postgres://rel:rel@localhost:25433/rel_test?sslmode=disable&timezone=Asia/Jakarta"),
122+
)
123+
124+
defer adapter.Close()
125+
126+
repo := rel.New(adapter)
127+
AdapterSpecs(t, repo)
128+
}
129+
104130
func TestAdapter_Transaction_commitError(t *testing.T) {
105131
adapter, err := Open(dsn())
106132
assert.Nil(t, err)
@@ -125,3 +151,9 @@ func TestAdapter_Exec_error(t *testing.T) {
125151
_, _, err = adapter.Exec(ctx, "error", nil)
126152
assert.NotNil(t, err)
127153
}
154+
155+
func TestCheck(t *testing.T) {
156+
assert.Panics(t, func() {
157+
check(errors.New("error"))
158+
})
159+
}

0 commit comments

Comments
 (0)