From bc687fd1e734645f0fd1124c8e27ec041d99f4e2 Mon Sep 17 00:00:00 2001 From: Pavlo Strokov Date: Wed, 18 Aug 2021 13:50:00 +0300 Subject: postgres-listener: Fix data race during initialisation During connection establishment the 'listener' field is assigned the value the other goroutine tries to read. The simple synchronisation over operations order solves the problem. --- internal/praefect/datastore/listener_postgres.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'internal/praefect/datastore') diff --git a/internal/praefect/datastore/listener_postgres.go b/internal/praefect/datastore/listener_postgres.go index edaba97d3..9c45f3537 100644 --- a/internal/praefect/datastore/listener_postgres.go +++ b/internal/praefect/datastore/listener_postgres.go @@ -88,6 +88,7 @@ func NewPostgresListener(logger logrus.FieldLogger, opts PostgresListenerOpts, h func (pgl *PostgresListener) connect() error { firstConnectionAttempt := true connectErrChan := make(chan error, 1) + listenerAssignedChan := make(chan struct{}) connectionLifecycle := func(eventType pq.ListenerEventType, err error) { pgl.reconnectTotal.WithLabelValues(listenerEventTypeToString(eventType)).Inc() @@ -107,8 +108,14 @@ func (pgl *PostgresListener) connect() error { // once the connection is established we can be sure that the connection // address is correct and all other errors could be considered as // a temporary, so listener will try to re-connect and proceed. - pgl.async(pgl.ping) - pgl.async(pgl.handleNotifications) + pgl.async(func() { + <-listenerAssignedChan + pgl.ping() + }) + pgl.async(func() { + <-listenerAssignedChan + pgl.handleNotifications() + }) close(connectErrChan) // to signal the connection was established without troubles firstConnectionAttempt = false @@ -123,6 +130,7 @@ func (pgl *PostgresListener) connect() error { } pgl.listener = pq.NewListener(pgl.opts.Addr, pgl.opts.MinReconnectInterval, pgl.opts.MaxReconnectInterval, connectionLifecycle) + close(listenerAssignedChan) listenErrChan := make(chan error, 1) pgl.async(func() { -- cgit v1.2.3