Skip to content

Conversation

RafiaSabih
Copy link
Contributor

Refactor connection pooler to be a map of PostgresRole, as now we require connection pooler for each service.

@FxKu
Copy link
Member

FxKu commented Oct 7, 2020

@RafiaSabih can you rebase your PR, so that it does not list unrelated commits?

Rafia Sabih added 19 commits October 7, 2020 10:44
- Refactor code for connection pooler deployment and services
- Refactor sync code for connection pooler
- Rename EnableConnectionPooler to EnableMasterConnectionPooler
- Update yamls and tests
- Update deleteConnectionPooler to include role
- Rename EnableMasterConnectionPooler back to original name for backward
  compatiility
- other minor chnages and code improvements
- Refactor needConnectionPooler for master and replica separately
- Improve sync function
- Add test cases to create, delete and sync with repplica connection
  pooler

Other changes
- Fixed the issue with failing test cases
- Add more test cases for replica connection pooler
- Added docs about the new flag
Have one unified function to tell if any connection pooler is required

Add a helper function to list the roles that require connection pooler,
helps in avoiding duplication of code
@RafiaSabih
Copy link
Contributor Author

RafiaSabih commented Oct 8, 2020

Current issues open for discussion,

  • some of the functions in connection_pooler package still require cluster package for things like Spec (to get the values of flag EnableConnectionPooler, etc.), OpConfig( to get ConnectionPooler for schema, user, etc. and also for some not so related stuff like PodServiceAccountName).
    For connection pooler related stuff, maybe we can have separate config for it and thus would not require cluster package for them and also they are not used anywhere else. For PodServiceAccountName, I am not very sure how to handle that.

  • Other issue is in accessing c.KubeClient, which is also not very clear to me on how to handle that dependency

One way could be to let the functions like createConnectionPooler, deleteConnectionPooler, updateConenctionPooler which are using Kubeclient in the cluster package itself, but then it kind of defeats the purpose of refactoring.
Another way could be to have a third package which does this stuff for connection pooler and maybe other resources and both cluster and connection pooler could use import it.

processMu sync.RWMutex // protects the current operation for reporting, no need to hold the master mutex
specMu sync.RWMutex // protects the spec for reporting, no need to hold the master mutex

ConnectionPooler map[PostgresRole]*connection_pooler.ConnectionPoolerObjects
Copy link
Member

Choose a reason for hiding this comment

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

So this whole PR is not solely a refactoring but rather a code change that enables separate connection poolers for the master and replicas ?


roles := c.RolesConnectionPooler()
for _, r := range roles {
c.logger.Warningf("found roles are %v", r)
Copy link
Member

Choose a reason for hiding this comment

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

why Warningf and not Infof ? at this point there is technically nothing bad happening


for _, r := range c.RolesConnectionPooler() {
if c.ConnectionPooler[r] != nil {
c.logger.Warning("Connection pooler already exists in the cluster")
Copy link
Member

Choose a reason for hiding this comment

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

It would be more descriptive here to log also the role for which the pooler exists, and the name of this pooler similar to how errors are processed below in this code

return nil
}

func syncResources(a, b *v1.ResourceRequirements) bool {
Copy link
Member

Choose a reason for hiding this comment

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

I understand this function was named like that in the original code, but judging from what it does, shouldSyncResources or needToSyncResouces is a better name for it from a readability perspective.

package pooler_interface

//functions of cluster package used in connection_pooler package
type pooler interface {
Copy link
Member

Choose a reason for hiding this comment

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

Is this interface meant to help resolving cyclic dependencies ?

pgPort = 5432
)

// K8S objects that are belongs to a connection pooler
Copy link
Member

Choose a reason for hiding this comment

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

typo: are belongs -> belong


const (
// Master role
Master PostgresRole = "master"
Copy link
Member

Choose a reason for hiding this comment

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

Role constants are already defined in pkg/cluster/types.go. Why are they re-defined here ?

@sdudoladov
Copy link
Member

sdudoladov commented Oct 13, 2020

Current issues open for discussion,

I feel they are all caused by the fundamental circular dependency between pkg/cluster and pkg/connection_pooler

We can try to resolve the dependency by making the pkg/connection_pooler depend on an additional ClusterInterface instead of directly importing objects from pkg/cluster. The interface would

  1. live in the connection_pooler package
  2. contain all methods required by a connection pooler

One can have the effective implementation of the interface in the cluster package. When the operator creates a PG cluster, it will just provide an implementation of the ClusterInterface to a connection pooler.

@sdudoladov
Copy link
Member

@RafiaSabih could you update the PR description with

  1. the scope of this PR. It does not seem to me to be limited to refactoring only as it also manipulates with the objects belonging to the replica connection pooler
  2. the relationship between this PR and #1127 . Do you still work on the latter ? there are commits there from the last week

Rafia Sabih added 13 commits October 19, 2020 09:37
Kepp connectionPooler in cluster package itself. This helps in getting
rid of previously added packages and interfaces.
Based on the new structure of ConnectionPooler in cluster, there are
functional changes to come.
This commit is only for updating and cleaning of packages.
create and sync connectionPooler were doing essentially the same task
with respect to creating new connectionPooler if not present. Hence, the
code from create is already present in sync, which is now utilized and
duplicate code is removed.

Other code duplication is also removed in sync, for deciding upon when
to delete the connectionPooler. Basically, anytime
newNeedConnectionPooler is false, we have to delete it, if present.

Other respective modifications in tests.
@RafiaSabih
Copy link
Contributor Author

👍

@Jan-M
Copy link
Member

Jan-M commented Oct 29, 2020

👍


//delete connection pooler
func (c *Cluster) deleteConnectionPooler(role PostgresRole) (err error) {
//c.setProcessName("deleting connection pooler")
Copy link
Contributor

Choose a reason for hiding this comment

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

Should it be commented out?

@erthalion
Copy link
Contributor

👍

@RafiaSabih RafiaSabih merged commit 133f77c into replica-pooler Oct 29, 2020
@RafiaSabih RafiaSabih deleted the pooler-refac branch October 29, 2020 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants