{"action":"created","issue":{"url":"https://api.github.com/repos/gocql/gocql/issues/348","labels_url":"https://api.github.com/repos/gocql/gocql/issues/348/labels{/name}","comments_url":"https://api.github.com/repos/gocql/gocql/issues/348/comments","events_url":"https://api.github.com/repos/gocql/gocql/issues/348/events","html_url":"https://github.com/gocql/gocql/pull/348","id":67011941,"number":348,"title":"Policy based ConnectionPool with token-aware, and round-robin policy implementation","user":{"login":"justinretailnext","id":10342005,"avatar_url":"https://avatars.githubusercontent.com/u/10342005?v=3","gravatar_id":"","url":"https://api.github.com/users/justinretailnext","html_url":"https://github.com/justinretailnext","followers_url":"https://api.github.com/users/justinretailnext/followers","following_url":"https://api.github.com/users/justinretailnext/following{/other_user}","gists_url":"https://api.github.com/users/justinretailnext/gists{/gist_id}","starred_url":"https://api.github.com/users/justinretailnext/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justinretailnext/subscriptions","organizations_url":"https://api.github.com/users/justinretailnext/orgs","repos_url":"https://api.github.com/users/justinretailnext/repos","events_url":"https://api.github.com/users/justinretailnext/events{/privacy}","received_events_url":"https://api.github.com/users/justinretailnext/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2015-04-07T23:24:25Z","updated_at":"2015-04-16T21:25:11Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/gocql/gocql/pulls/348","html_url":"https://github.com/gocql/gocql/pull/348","diff_url":"https://github.com/gocql/gocql/pull/348.diff","patch_url":"https://github.com/gocql/gocql/pull/348.patch"},"body":"Based on the work of PRs #340, #338, and #309, this PR adds a new ConnectionPool implementation which uses replaceable policy implementations of new interfaces HostSelectionPolicy and ConnSelectionPolicy. \r\n```\r\n//HostSelectionPolicy is an interface for selecting\r\n//the most appropriate host to execute a given query.\r\ntype HostSelectionPolicy interface {\r\n\t//SetHosts notifies this policy of the current hosts in the cluster\r\n\tSetHosts(hosts []HostInfo)\r\n\t//SetPartitioner notifies this policy of the current token partitioner\r\n\tSetPartitioner(partitioner string)\r\n\t//Pick returns an iteration function over selected hosts\r\n\tPick(*Query) NextHost\r\n}\r\n\r\n//NextHost is an iteration function over picked hosts\r\ntype NextHost func() *HostInfo\r\n\r\n//ConnSelectionPolicy is an interface for selecting an\r\n//appropriate connection for executing a query\r\ntype ConnSelectionPolicy interface {\r\n\tSetConns(conns []*Conn)\r\n\tPick(*Query) *Conn\r\n}\r\n```\r\n\r\nThe new connection pool (see type policyConnPool) is implemented as a pool of hosts which each have a pool of connections and makes a clearer distinction between selecting a host for a query and selecting a connection for the selected hosts. This allows for the implementation of the selection policies for host selection and connection selection to be implemented specifically in terms of hosts or connections while allowing the polices to still be composible; for example, the provided NewTokenAwareConnPool \"ConnPoolType\" is a composition of a token aware host selection policy, which falls back to a round-robin host selection policy when a routing key cannot be determined, combined with the trivial round-robin connection selection policy:\r\n\r\n```\r\nfunc NewTokenAwareConnPool(cfg *ClusterConfig) ConnectionPool {\r\n\treturn newPolicyConnPool(\r\n\t\tcfg,\r\n\t\tNewTokenAwareHostPolicy(NewRoundRobinHostPolicy()),\r\n\t\tNewRoundRobinConnPolicy,\r\n\t)\r\n}\r\n```\r\nHost selection also (in comparison to connection selection) returns an iterator over hosts allowing for say the token aware policy to return first the token replicas, followed by a shuffled round-robin.\r\n\r\nThe SimplePool ConnectionPool has been left untouched since it is mature code, however the new pool implementation can replace SimplePool (see NewRoundRobinConnPool in connectionpool.go)\r\n\r\nI've also added the connectionpool_systems_test.sh and connectionpool_systems_test.go to verify that the new connection pool implementation behaves correctly when the cluster topology changes. Prior to PR #332, the SimplePool actually failed this test.\r\n\r\nOne more thing to note in this change is that there is no \"distance\" property to the HostSelectionPolicy so, as-is the interface can't support an a datacenter aware policy. Adding such support would be a good follow-on to this PR.\n\n<!-- Reviewable:start -->\n[<img src=\"https://reviewable.io/review_button.png\" height=40 alt=\"Review on Reviewable\"/>](https://reviewable.io/reviews/gocql/gocql/348)\n<!-- Reviewable:end -->\n"},"comment":{"url":"https://api.github.com/repos/gocql/gocql/issues/comments/93843081","html_url":"https://github.com/gocql/gocql/pull/348#issuecomment-93843081","issue_url":"https://api.github.com/repos/gocql/gocql/issues/348","id":93843081,"user":{"login":"justinretailnext","id":10342005,"avatar_url":"https://avatars.githubusercontent.com/u/10342005?v=3","gravatar_id":"","url":"https://api.github.com/users/justinretailnext","html_url":"https://github.com/justinretailnext","followers_url":"https://api.github.com/users/justinretailnext/followers","following_url":"https://api.github.com/users/justinretailnext/following{/other_user}","gists_url":"https://api.github.com/users/justinretailnext/gists{/gist_id}","starred_url":"https://api.github.com/users/justinretailnext/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justinretailnext/subscriptions","organizations_url":"https://api.github.com/users/justinretailnext/orgs","repos_url":"https://api.github.com/users/justinretailnext/repos","events_url":"https://api.github.com/users/justinretailnext/events{/privacy}","received_events_url":"https://api.github.com/users/justinretailnext/received_events","type":"User","site_admin":false},"created_at":"2015-04-16T21:25:11Z","updated_at":"2015-04-16T21:25:11Z","body":"Alright, hopefully this PR is now good enough to merge! I've done my best to improve the unit test coverage for this PR and the supporting changes to metadata, and tokens. I copied a couple tests in conn_test.go for testing policyConnPool and the round robin host policy, however I stopped at that when I realized a number of the tests in that file are marked as skipped for being flaky. I've also gone back and added documentation strings to all of the tests I've added as part of this series of PRs."}}