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

Create a single connection pool per host #359

Merged
merged 3 commits into from
Sep 29, 2017

Conversation

samarabbas
Copy link
Contributor

When history service comes up it creates a gocql client for execution manager and then uses the same client for all shards for making persistence calls. Also created config knobs to configure number of connections for both events and execution maanger clients.

fixes #307

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.02%) to 66.44% when pulling 233f736 on samarabbas:persistence_connections into 9169f8f on uber:master.

@@ -128,7 +113,11 @@ func (s *TestBase) SetupWorkflowStoreWithOptions(options TestBaseOptions) {
if err != nil {
log.Fatal(err)
}
s.ExecutionMgrFactory = newTestExecutionMgrFactory(options, s.CassandraTestCluster, log)
s.ExecutionMgrFactory, err = NewCassandraPersistenceClientFactory(options.ClusterHost, options.ClusterPort,

Choose a reason for hiding this comment

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

is this creating real cassandra session for test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes we create a connection to cassandra for certain tests.


// CreateExecutionManager implements ExecutionManagerFactory interface
func (f *cassandraPersistenceClientFactory) CreateExecutionManager(shardID int) (ExecutionManager, error) {
mgr, err := NewCassandraWorkflowExecutionPersistence(shardID, f.session, f.logger)

Choose a reason for hiding this comment

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

not sure about this, but is it ever possible that the session get into some bad state and needs to be destroyed and recreated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is possible. But we have the similar issues for all other persistence client currently. Creating a separate client just for execution manager won't help much in such a situation.
Having a persistence client factory is the right abstraction to build this kind of resiliency in the future.

Choose a reason for hiding this comment

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

@coveralls
Copy link

Coverage Status

Coverage increased (+0.02%) to 66.49% when pulling 4913b8c on samarabbas:persistence_connections into 9169f8f on uber:master.

Copy link
Contributor

@venkat1109 venkat1109 left a comment

Choose a reason for hiding this comment

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

Looks good for now but we need to revisit this abstraction and naming.

history = persistence.NewHistoryPersistenceClient(history, base.GetMetricsClient())
execMgrFactory := NewExecutionManagerFactory(&p.CassandraConfig, p.Logger, base.GetMetricsClient())

execMgrFactory, err := persistence.NewCassandraPersistenceClientFactory(p.CassandraConfig.Hosts,
Copy link
Contributor

Choose a reason for hiding this comment

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

The mix match of terminology between "CassandraPersistence, CassandraHistoryPersistence, ExecutionManager and ExecutionManagerFactory" is turning out to be super confusing while navigating through the code. IMO, the layering between gocqlConnPool / persistence API / higher level APIs is also not very obvious because of this. Ideally, we should have one gocql client pool or factory that takes as input { keyspace, defaultConsistencyLevels, seeds } and vends a gocql.Session object ? And then on top of this, one single persistence API interface that lists all of our contracts with persistence. What do you think ?

Whatever we decide, this will likely be a separate work item

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree we need another pass to clean up the model. This change is just to have a single client per host for ExecutionManager which will be an improvement to what we have currently.
This is the reason I created PersistenceClientFactory, which should expose API for creating various persistence managers and also manage a pool of gocql clients.

// to cassandra for this engine. So, make sure to
// close executionMgr only after stopping the engine
if i.executionMgr != nil {
i.executionMgr.Close()
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you make the ExecutionManager not Closeable i.e. remove Close() from the interface as well ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought about that as it is little tricky right now. Once we move all the managers be created using the persistenceClientFactory then we can remove Close on all of them.

@@ -62,6 +62,10 @@ type Config struct {
TransferProcessorUpdateAckInterval time.Duration
TransferProcessorForceUpdateInterval time.Duration
TransferTaskWorkerCount int

// Persistence settings
ExecutionMgrNumConns int
Copy link
Contributor

Choose a reason for hiding this comment

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

any good reason these two should use a different connection pool ? They are both directing requests to the same keyspace, right ? Is the consistency level coupled with gocql.session today ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. I just created two knobs since we have two separate clients for these. We should clean it up when we can consolidate the gocql clients for all persistence interfaces.

@@ -31,14 +31,18 @@ type Config struct {
DefaultVisibilityMaxPageSize int32
DefaultHistoryMaxPageSize int32
RPS int

// Persistence settings
HistoryMgrNumConns int
Copy link
Contributor

Choose a reason for hiding this comment

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

same comments as above, around gocql connection pool layering

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.02%) to 66.469% when pulling 6024cf7 on samarabbas:persistence_connections into affdf19 on uber:master.

@samarabbas samarabbas merged commit 81e51c6 into uber:master Sep 29, 2017
@samarabbas samarabbas deleted the persistence_connections branch September 29, 2017 23:10
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.

History: Too many tcp connections to cassandra
4 participants