diff options
author | Pavlo Strokov <pstrokov@gitlab.com> | 2021-08-18 13:50:00 +0300 |
---|---|---|
committer | Pavlo Strokov <pstrokov@gitlab.com> | 2021-08-20 12:18:28 +0300 |
commit | bc687fd1e734645f0fd1124c8e27ec041d99f4e2 (patch) | |
tree | 7c570396cf5987a7ff30c599aa8418b3253b8281 /internal | |
parent | 1a92a69ad7863d3d51ad8d09fe3d75853eee1741 (diff) |
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.
Diffstat (limited to 'internal')
-rw-r--r-- | internal/praefect/datastore/listener_postgres.go | 12 |
1 files changed, 10 insertions, 2 deletions
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() { |