66 "fmt"
77 "os"
88 "os/signal"
9+ "sync"
910 "syscall"
1011 "time"
1112
@@ -19,7 +20,7 @@ const errorBufferSize = 100
1920
2021// Logical decoding plugin.
2122const (
22- pgoutputPlugin = "pgoutput"
23+ pgOutputPlugin = "pgoutput"
2324)
2425
2526// Service info message.
@@ -55,13 +56,14 @@ type repository interface {
5556
5657// Listener main service struct.
5758type Listener struct {
59+ mu sync.RWMutex
5860 config config.Config
5961 slotName string
6062 publisher publisher
6163 replicator replication
6264 repository repository
6365 parser parser
64- LSN uint64
66+ lsn uint64
6567 errChannel chan error
6668}
6769
@@ -84,6 +86,18 @@ func NewWalListener(
8486 }
8587}
8688
89+ func (l * Listener ) readLSN () uint64 {
90+ l .mu .RLock ()
91+ defer l .mu .RUnlock ()
92+ return l .lsn
93+ }
94+
95+ func (l * Listener ) setLSN (lsn uint64 ) {
96+ l .mu .Lock ()
97+ l .lsn = lsn
98+ defer l .mu .Unlock ()
99+ }
100+
87101// Process is main service entry point.
88102func (l * Listener ) Process () error {
89103 var serviceErr * serviceErr
@@ -99,16 +113,17 @@ func (l *Listener) Process() error {
99113 }
100114
101115 if ! slotIsExists {
102- consistentPoint , _ , err := l .replicator .CreateReplicationSlotEx (l .slotName , pgoutputPlugin )
116+ consistentPoint , _ , err := l .replicator .CreateReplicationSlotEx (l .slotName , pgOutputPlugin )
103117 if err != nil {
104118 logger .WithError (err ).Infoln ("CreateReplicationSlotEx() error" )
105119 return err
106120 }
107- l . LSN , err = pgx .ParseLSN (consistentPoint )
121+ lsn , err : = pgx .ParseLSN (consistentPoint )
108122 if err != nil {
109123 logger .WithError (err ).Errorln ("slotIsExists() error" )
110124 return err
111125 }
126+ l .setLSN (lsn )
112127 logger .Infoln ("create new slot" )
113128 } else {
114129 logger .Infoln ("slot already exists, LSN updated" )
@@ -164,10 +179,11 @@ func (l *Listener) slotIsExists() (bool, error) {
164179 if len (restartLSNStr ) == 0 {
165180 return false , nil
166181 }
167- l . LSN , err = pgx .ParseLSN (restartLSNStr )
182+ lsn , err : = pgx .ParseLSN (restartLSNStr )
168183 if err != nil {
169184 return false , err
170185 }
186+ l .setLSN (lsn )
171187 return true , nil
172188}
173189
@@ -180,7 +196,7 @@ const protoVersion = "proto_version '1'"
180196// Stream receive event from PostgreSQL.
181197// Accept message, apply filter and publish it in NATS server.
182198func (l * Listener ) Stream (ctx context.Context ) {
183- err := l .replicator .StartReplication (l .slotName , l .LSN , - 1 , protoVersion , publicationNames ("sport" ))
199+ err := l .replicator .StartReplication (l .slotName , l .readLSN () , - 1 , protoVersion , publicationNames ("sport" ))
184200 if err != nil {
185201 l .errChannel <- newListenerError ("StartReplication()" , err )
186202 return
@@ -220,20 +236,20 @@ func (l *Listener) Stream(ctx context.Context) {
220236 logrus .
221237 WithField ("subject" , subjectName ).
222238 WithField ("action" , event .Action ).
223- WithField ("lsn" , l .LSN ).
239+ WithField ("lsn" , l .readLSN () ).
224240 Infoln ("event was send" )
225241 }
226242 }
227243 tx .Clear ()
228244 }
229245
230- if msg .WalMessage .WalStart > l .LSN {
246+ if msg .WalMessage .WalStart > l .readLSN () {
231247 err = l .AckWalMessage (msg .WalMessage .WalStart )
232248 if err != nil {
233249 l .errChannel <- fmt .Errorf ("%v: %w" , ErrAckWalMessage , err )
234250 continue
235251 } else {
236- logrus .WithField ("lsn" , l .LSN ).Debugln ("ack wal msg" )
252+ logrus .WithField ("lsn" , l .readLSN () ).Debugln ("ack wal msg" )
237253 }
238254 }
239255 }
@@ -298,7 +314,7 @@ func (l *Listener) SendPeriodicHeartbeats(ctx context.Context) {
298314
299315// SendStandbyStatus sends a `StandbyStatus` object with the current RestartLSN value to the server.
300316func (l * Listener ) SendStandbyStatus () error {
301- standbyStatus , err := pgx .NewStandbyStatus (l .LSN )
317+ standbyStatus , err := pgx .NewStandbyStatus (l .readLSN () )
302318 if err != nil {
303319 return fmt .Errorf ("unable to create StandbyStatus object: %w" , err )
304320 }
@@ -312,7 +328,7 @@ func (l *Listener) SendStandbyStatus() error {
312328
313329// AckWalMessage acknowledge received wal message.
314330func (l * Listener ) AckWalMessage (lsn uint64 ) error {
315- l .LSN = lsn
331+ l .setLSN ( lsn )
316332 err := l .SendStandbyStatus ()
317333 if err != nil {
318334 return err
0 commit comments