Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Several fixes for the connection_pool subpackage #208

Merged
merged 12 commits into from
Aug 29, 2022

Conversation

oleg-jukovec
Copy link
Collaborator

@oleg-jukovec oleg-jukovec commented Aug 18, 2022

The patchset contains a number of different fixes for the connection_pool package. I tried to make the changes in small commits so that it would be easier to review them. I recommend to review the changes one by one commit.

I didn't forget about (remove if it is not applicable):

oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
The patch fixes PREFER_RW/PREFER_RO usage. It also make comments in
Go-style. See `Const` section in `Go Doc Comments` guide [1].

1. https://go.dev/doc/comment

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
It's enough to get `box.info` table once in
ConnectionPool.getConnectionRole().

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
After the patch all errors in the connection_pool subpackage start
with a lowercase letter [1].

1. https://github.com/golang/go/wiki/CodeReviewComments#error-strings

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
We return a role of an instance from `GetPoolInfo()` call. It is
unexpected that Role constants are not a part of the public API.

Part of #208
@oleg-jukovec oleg-jukovec force-pushed the oleg-jukovec/connection_pool_fixes branch from 384023f to 2f3421a Compare August 18, 2022 11:51
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
We add all connections into ConnectionPool.anyPool, but `MasterRole`
connection only in ConnectionPool.rwPool and `ReplicaRole`
connections only in ConnectionPool.roPool. As a result `UnknownRole`
connections appears only in the `anyPool`. See `setConnectionToPool`
implementation.

So we need to close connections from the `anyPool` instead of
`roPool` + `rwPool`.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
* Duplicates could be added to a list of connections, which then
  cannot be deleted.
* The delete function uses an address from a connection instead of
  argument value. It may lead to unexpected errors.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
After the patch ConnectionPool.getNextConnection() does not return
(nil, nil). It always return a connection or an error.

The check Connection.ConnectedNow() does not have sence because
the connection may be closed right after the call. The code just
complicates the logic and does not protect against anything.

A chain of two atomic operations IsEmpty() + GetNextConnection()
wrong because it leads too a race condition.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
We need to use copies of slices, not just pointers to them. It helps
to avoid unexpected changes.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
If we create a connection immediately after closing previous, then it
can to lead to too frequent connection creation under some
configurations [1] and high CPU load. It will be expected to recreate
connection with OptsPool.CheckTimeout frequency.

1. #136

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
The ConnectionPool.checker() goroutine may still work some time
after ConnectionPool.Close() call. It may lead to re-open
connection in a concurrent closing pool. The connection still
opened after the pool is closed.

The patch adds RWLock to protect blocks which work with anyPool,
roPool and rwPool. We don't need to protect regular requests
because in the worst case, we will send a request into
a closed connection. It can happen for other reasons and it seems
like we can't avoid it. So it seems loke an expected behavior.

Closes #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
The ConnectionPool.checker() goroutine may still work some time
after ConnectionPool.Close() call. It may lead to re-open
connection in a concurrent closing pool. The connection still
opened after the pool is closed.

The patch adds RWLock to protect blocks which work with anyPool,
roPool and rwPool. We don't need to protect regular requests
because in the worst case, we will send a request into
a closed connection. It can happen for other reasons and it seems
like we can't avoid it. So it seems like an expected behavior.

Closes #208
@oleg-jukovec oleg-jukovec force-pushed the oleg-jukovec/connection_pool_fixes branch from 2f3421a to 93315de Compare August 18, 2022 11:58
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
The ConnectionPool.checker() goroutine may still work some time
after ConnectionPool.Close() call. It may lead to re-open
connection in a concurrent closing pool. The connection still
opened after the pool is closed.

The patch adds RWLock to protect blocks which work with anyPool,
roPool and rwPool. We don't need to protect regular requests
because in the worst case, we will send a request into
a closed connection. It can happen for other reasons and it seems
like we can't avoid it. So it is an expected behavior.

Closes #208
@oleg-jukovec oleg-jukovec force-pushed the oleg-jukovec/connection_pool_fixes branch from 93315de to d22723a Compare August 18, 2022 12:05
@oleg-jukovec oleg-jukovec marked this pull request as ready for review August 18, 2022 13:43
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
After the patch ConnectionPool.getNextConnection() does not return
(nil, nil). It always return a connection or an error.

The check Connection.ConnectedNow() does not have sence because
the connection may be closed right after the call. The code just
complicates the logic and does not protect against anything.

A chain of two atomic operations IsEmpty() + GetNextConnection()
wrong because it leads too a race condition.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
We need to use copies of slices, not just pointers to them. It helps
to avoid unexpected changes.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
If we create a connection immediately after closing previous, then it
can to lead to too frequent connection creation under some
configurations [1] and high CPU load. It will be expected to recreate
connection with OptsPool.CheckTimeout frequency.

1. #136

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 18, 2022
The ConnectionPool.checker() goroutine may still work some time
after ConnectionPool.Close() call. It may lead to re-open
connection in a concurrent closing pool. The connection still
opened after the pool is closed.

The patch adds RWLock to protect blocks which work with anyPool,
roPool and rwPool. We don't need to protect regular requests
because in the worst case, we will send a request into
a closed connection. It can happen for other reasons and it seems
like we can't avoid it. So it is an expected behavior.

Closes #208
@oleg-jukovec oleg-jukovec force-pushed the oleg-jukovec/connection_pool_fixes branch from d22723a to e5cd08b Compare August 18, 2022 18:52
Copy link

@AnaNek AnaNek left a comment

Choose a reason for hiding this comment

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

Thank you for fixing connection_pool! Some of my comments are questions for understanding my mistakes.

oleg-jukovec added a commit that referenced this pull request Aug 23, 2022
* Duplicates could be added to a list of connections, which then
  cannot be deleted.
* The delete function uses an address from a connection instead of
  argument value. It may lead to unexpected errors.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 23, 2022
After the patch ConnectionPool.getNextConnection() does not return
(nil, nil). It always return a connection or an error.

The check Connection.ConnectedNow() does not have sence because
the connection may be closed right after the call. The code just
complicates the logic and does not protect against anything.

A chain of two atomic operations IsEmpty() + GetNextConnection()
wrong because it leads too a race condition.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 23, 2022
We need to use copies of slices, not just pointers to them. It helps
to avoid unexpected changes.

Part of #208
The ConnectionPool.checker() goroutine may still work some time
after ConnectionPool.Close() call. It may lead to re-open
connection in a concurrent closing pool. The connection still
opened after the pool is closed.

The patch adds RWLock to protect blocks which work with anyPool,
roPool and rwPool. We don't need to protect regular requests
because in the worst case, we will send a request into
a closed connection. It can happen for other reasons and it seems
like we can't avoid it. So it is an expected behavior.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 25, 2022
An user can specify duplicate addresses in ConnectionPool. We cannot
support multiple connections to the same address due to
ConnectionPool.GetPoolInfo() implementation without breaking backward
compatibility. So we need to skip duplicates.

Closes #208
@oleg-jukovec oleg-jukovec force-pushed the oleg-jukovec/connection_pool_fixes branch from 4e7b1c3 to 43cac08 Compare August 25, 2022 08:57
oleg-jukovec added a commit that referenced this pull request Aug 25, 2022
An user can specify duplicate addresses in ConnectionPool. We cannot
support multiple connections to the same address due to
ConnectionPool.GetPoolInfo() implementation without breaking backward
compatibility. So we need to skip duplicates.

Closes #208
@oleg-jukovec oleg-jukovec force-pushed the oleg-jukovec/connection_pool_fixes branch from 43cac08 to 5e94fd7 Compare August 25, 2022 09:00
An user can specify duplicate addresses for a ConnectionPool. We
cannot support multiple connections to the same address due to
the ConnectionPool.GetPoolInfo() implementation without breaking
backward compatibility. So we need to skip duplicates.

Closes #208
@oleg-jukovec oleg-jukovec force-pushed the oleg-jukovec/connection_pool_fixes branch from 5e94fd7 to 6dee596 Compare August 25, 2022 09:02
Copy link

@AnaNek AnaNek left a comment

Choose a reason for hiding this comment

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

LGTM.

Copy link
Member

@DifferentialOrange DifferentialOrange left a comment

Choose a reason for hiding this comment

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

Should be ok

@oleg-jukovec oleg-jukovec merged commit 5801dc6 into master Aug 29, 2022
@oleg-jukovec oleg-jukovec deleted the oleg-jukovec/connection_pool_fixes branch August 29, 2022 08:59
oleg-jukovec added a commit that referenced this pull request Aug 29, 2022
The patch fixes PREFER_RW/PREFER_RO usage. It also make comments in
Go-style. See `Const` section in `Go Doc Comments` guide [1].

1. https://go.dev/doc/comment

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 29, 2022
oleg-jukovec added a commit that referenced this pull request Aug 29, 2022
It's enough to get `box.info` table once in
ConnectionPool.getConnectionRole().

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 29, 2022
After the patch all errors in the connection_pool subpackage start
with a lowercase letter [1].

1. https://github.com/golang/go/wiki/CodeReviewComments#error-strings

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 29, 2022
We return a role of an instance from `GetPoolInfo()` call. It is
unexpected that Role constants are not a part of the public API.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 29, 2022
We add all connections into ConnectionPool.anyPool, but `MasterRole`
connection only in ConnectionPool.rwPool and `ReplicaRole`
connections only in ConnectionPool.roPool. As a result `UnknownRole`
connections appears only in the `anyPool`. See `setConnectionToPool`
implementation.

So we need to close connections from the `anyPool` instead of
`roPool` + `rwPool`.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 29, 2022
* Duplicates could be added to a list of connections, which then
  cannot be deleted.
* The delete function uses an address from a connection instead of
  argument value. It may lead to unexpected errors.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 29, 2022
After the patch ConnectionPool.getNextConnection() does not return
(nil, nil). It always return a connection or an error.

The check Connection.ConnectedNow() does not have sence because
the connection may be closed right after the call. The code just
complicates the logic and does not protect against anything.

A chain of two atomic operations IsEmpty() + GetNextConnection()
wrong because it leads too a race condition.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 29, 2022
We need to use copies of slices, not just pointers to them. It helps
to avoid unexpected changes.

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 29, 2022
If we create a connection immediately after closing previous, then it
can to lead to too frequent connection creation under some
configurations [1] and high CPU load. It will be expected to recreate
connection with OptsPool.CheckTimeout frequency.

1. #136

Part of #208
oleg-jukovec added a commit that referenced this pull request Aug 29, 2022
The ConnectionPool.checker() goroutine may still work some time
after ConnectionPool.Close() call. It may lead to re-open
connection in a concurrent closing pool. The connection still
opened after the pool is closed.

The patch adds RWLock to protect blocks which work with anyPool,
roPool and rwPool. We don't need to protect regular requests
because in the worst case, we will send a request into
a closed connection. It can happen for other reasons and it seems
like we can't avoid it. So it is an expected behavior.

Part of #208
oleg-jukovec added a commit that referenced this pull request Oct 4, 2022
Overview

    The release adds support for the latest version of the
    queue package with master-replica switching.

Breaking changes

    There are no breaking changes in the release.

New features

    Support the queue 1.2.1 (#177).

    ConnectionHandler interface for handling changes of connections in
    ConnectionPool (#178)

    Execute, ExecuteTyped and ExecuteAsync methods to
    ConnectionPool (#176)

    ConnectorAdapter type to use ConnectionPool as Connector
    interface (#176)

    An example how to use queue and connection_pool subpackages
    together (#176)

Bugfixes

    Mode type description in the connection_pool subpackage (#208)

    Missed Role type constants in the connection_pool subpackage (#208)

    ConnectionPool does not close UnknownRole connections (#208)

    Segmentation faults in ConnectionPool requests after
    disconnect (#208)

    Addresses in ConnectionPool may be changed from an external
    code (#208)

    ConnectionPool recreates connections too often (#208)

    A connection is still opened after ConnectionPool.Close() (#208)

    Future.GetTyped() after Future.Get() does not decode response
    correctly (#213)

    Decimal package use a test function GetNumberLength instead of a
    package-level function getNumberLength (#219)

    Datetime location after encode + decode is unequal (#217)
oleg-jukovec added a commit that referenced this pull request Oct 4, 2022
Overview

    The release adds support for the latest version of the
    queue package with master-replica switching.

Breaking changes

    There are no breaking changes in the release.

New features

    Support the queue 1.2.1 (#177).

    ConnectionHandler interface for handling changes of connections in
    ConnectionPool (#178).

    Execute, ExecuteTyped and ExecuteAsync methods to
    ConnectionPool (#176).

    ConnectorAdapter type to use ConnectionPool as Connector
    interface (#176).

    An example how to use queue and connection_pool subpackages
    together (#176).

Bugfixes

    Mode type description in the connection_pool subpackage (#208).

    Missed Role type constants in the connection_pool
    subpackage (#208).

    ConnectionPool does not close UnknownRole connections (#208).

    Segmentation faults in ConnectionPool requests after
    disconnect (#208).

    Addresses in ConnectionPool may be changed from an external
    code (#208).

    ConnectionPool recreates connections too often (#208).

    A connection is still opened after ConnectionPool.Close() (#208).

    Future.GetTyped() after Future.Get() does not decode response
    correctly (#213).

    Decimal package use a test function GetNumberLength instead of a
    package-level function getNumberLength (#219).

    Datetime location after encode + decode is unequal (#217).
@oleg-jukovec oleg-jukovec mentioned this pull request Oct 4, 2022
oleg-jukovec added a commit that referenced this pull request Oct 5, 2022
Overview

    The release adds support for the latest version of the
    queue package with master-replica switching.

Breaking changes

    There are no breaking changes in the release.

New features

    Support the queue 1.2.1 (#177).

    ConnectionHandler interface for handling changes of connections in
    ConnectionPool (#178).

    Execute, ExecuteTyped and ExecuteAsync methods to
    ConnectionPool (#176).

    ConnectorAdapter type to use ConnectionPool as Connector
    interface (#176).

    An example how to use queue and connection_pool subpackages
    together (#176).

Bugfixes

    Mode type description in the connection_pool subpackage (#208).

    Missed Role type constants in the connection_pool
    subpackage (#208).

    ConnectionPool does not close UnknownRole connections (#208).

    Segmentation faults in ConnectionPool requests after
    disconnect (#208).

    Addresses in ConnectionPool may be changed from an external
    code (#208).

    ConnectionPool recreates connections too often (#208).

    A connection is still opened after ConnectionPool.Close() (#208).

    Future.GetTyped() after Future.Get() does not decode response
    correctly (#213).

    Decimal package use a test function GetNumberLength instead of a
    package-level function getNumberLength (#219).

    Datetime location after encode + decode is unequal (#217).
oleg-jukovec added a commit that referenced this pull request Oct 31, 2022
Overview

    The release adds support for the latest version of the
    queue package with master-replica switching.

Breaking changes

    There are no breaking changes in the release.

New features

    Support the queue 1.2.1 (#177).

    ConnectionHandler interface for handling changes of connections in
    ConnectionPool (#178).

    Execute, ExecuteTyped and ExecuteAsync methods to
    ConnectionPool (#176).

    ConnectorAdapter type to use ConnectionPool as Connector
    interface (#176).

    An example how to use queue and connection_pool subpackages
    together (#176).

Bugfixes

    Mode type description in the connection_pool subpackage (#208).

    Missed Role type constants in the connection_pool
    subpackage (#208).

    ConnectionPool does not close UnknownRole connections (#208).

    Segmentation faults in ConnectionPool requests after
    disconnect (#208).

    Addresses in ConnectionPool may be changed from an external
    code (#208).

    ConnectionPool recreates connections too often (#208).

    A connection is still opened after ConnectionPool.Close() (#208).

    Future.GetTyped() after Future.Get() does not decode response
    correctly (#213).

    Decimal package use a test function GetNumberLength instead of a
    package-level function getNumberLength (#219).

    Datetime location after encode + decode is unequal (#217).

    Wrong interval arithmetic with timezones (#221).

    Invalid MsgPack if STREAM_ID > 127 (#224).

    queue.Take() returns an invalid task (#222).
oleg-jukovec added a commit that referenced this pull request Oct 31, 2022
Overview

    The release adds support for the latest version of the
    queue package with master-replica switching.

Breaking changes

    There are no breaking changes in the release.

New features

    Support the queue 1.2.1 (#177).

    ConnectionHandler interface for handling changes of connections in
    ConnectionPool (#178).

    Execute, ExecuteTyped and ExecuteAsync methods to
    ConnectionPool (#176).

    ConnectorAdapter type to use ConnectionPool as Connector
    interface (#176).

    An example how to use queue and connection_pool subpackages
    together (#176).

Bugfixes

    Mode type description in the connection_pool subpackage (#208).

    Missed Role type constants in the connection_pool
    subpackage (#208).

    ConnectionPool does not close UnknownRole connections (#208).

    Segmentation faults in ConnectionPool requests after
    disconnect (#208).

    Addresses in ConnectionPool may be changed from an external
    code (#208).

    ConnectionPool recreates connections too often (#208).

    A connection is still opened after ConnectionPool.Close() (#208).

    Future.GetTyped() after Future.Get() does not decode response
    correctly (#213).

    Decimal package use a test function GetNumberLength instead of a
    package-level function getNumberLength (#219).

    Datetime location after encode + decode is unequal (#217).

    Wrong interval arithmetic with timezones (#221).

    Invalid MsgPack if STREAM_ID > 127 (#224).

    queue.Take() returns an invalid task (#222).
oleg-jukovec added a commit that referenced this pull request Nov 2, 2022
Overview

    The release adds support for the latest version of the
    queue package with master-replica switching.

Breaking changes

    There are no breaking changes in the release.

New features

    Support the queue 1.2.1 (#177).

    ConnectionHandler interface for handling changes of connections in
    ConnectionPool (#178).

    Execute, ExecuteTyped and ExecuteAsync methods to
    ConnectionPool (#176).

    ConnectorAdapter type to use ConnectionPool as Connector
    interface (#176).

    An example how to use queue and connection_pool subpackages
    together (#176).

Bugfixes

    Mode type description in the connection_pool subpackage (#208).

    Missed Role type constants in the connection_pool
    subpackage (#208).

    ConnectionPool does not close UnknownRole connections (#208).

    Segmentation faults in ConnectionPool requests after
    disconnect (#208).

    Addresses in ConnectionPool may be changed from an external
    code (#208).

    ConnectionPool recreates connections too often (#208).

    A connection is still opened after ConnectionPool.Close() (#208).

    Future.GetTyped() after Future.Get() does not decode response
    correctly (#213).

    Decimal package use a test function GetNumberLength instead of a
    package-level function getNumberLength (#219).

    Datetime location after encode + decode is unequal (#217).

    Wrong interval arithmetic with timezones (#221).

    Invalid MsgPack if STREAM_ID > 127 (#224).

    queue.Take() returns an invalid task (#222).
oleg-jukovec added a commit that referenced this pull request Nov 2, 2022
Overview

    The release adds support for the latest version of the
    queue package with master-replica switching.

Breaking changes

    There are no breaking changes in the release.

New features

    Support the queue 1.2.1 (#177).

    ConnectionHandler interface for handling changes of connections in
    ConnectionPool (#178).

    Execute, ExecuteTyped and ExecuteAsync methods to
    ConnectionPool (#176).

    ConnectorAdapter type to use ConnectionPool as Connector
    interface (#176).

    An example how to use queue and connection_pool subpackages
    together (#176).

Bugfixes

    Mode type description in the connection_pool subpackage (#208).

    Missed Role type constants in the connection_pool
    subpackage (#208).

    ConnectionPool does not close UnknownRole connections (#208).

    Segmentation faults in ConnectionPool requests after
    disconnect (#208).

    Addresses in ConnectionPool may be changed from an external
    code (#208).

    ConnectionPool recreates connections too often (#208).

    A connection is still opened after ConnectionPool.Close() (#208).

    Future.GetTyped() after Future.Get() does not decode response
    correctly (#213).

    Decimal package use a test function GetNumberLength instead of a
    package-level function getNumberLength (#219).

    Datetime location after encode + decode is unequal (#217).

    Wrong interval arithmetic with timezones (#221).

    Invalid MsgPack if STREAM_ID > 127 (#224).

    queue.Take() returns an invalid task (#222).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants