Skip to content

Align routing to specification #105

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

Merged
merged 1 commit into from
Dec 13, 2016
Merged

Align routing to specification #105

merged 1 commit into from
Dec 13, 2016

Conversation

technige
Copy link
Contributor

@technige technige commented Dec 8, 2016

This update provides a more solid routing implementation and a clear separation of routing code into a distinct module. Coupled with full test coverage over this module, this provides a thorough source for updates to the internal routing specification document.

Two files here should be of particular interest to the reviewer: routing.py and test_routing.py. These provide the routing implementation and tests. A summary of the main classes follows:

routing.py

A module containing three classes that together implement the routing mechanism used by RoutingDriver (itself still located in session.py). These are:

  • RoundRobinSet - A generic collection that essentially consists of an ordered set paired with a perpetually-looping iterator. This means that elements maintain their original insertion order and duplicates are not permitted. The iterator allows these elements to be selected in turn (using next) and will restart at the top after completing each cycle. This collection class is used to store lists of routers, readers and writers within a RoutingTable.
  • RoutingTable - A store for routing information, constructed from the output of the getServers procedure. This holds three collections of servers: routers, readers and writers, as well as a last_updated_time and a ttl. Storing these last two values separately, instead of as a combined expiry_time, gives extra detail on the freshness of the information and makes testing simpler.
  • RoutingConnectionPool - An extension of the plain ConnectionPool class that also holds a RoutingTable. This is used by the RoutingDriver instead of the simpler version of the class and is described in more detail in the section below.

RoutingConnectionPool

The main class for coördination of all routing functionality. Method descriptions follow:

  • fetch_routing_info(address) - Fetch the raw routing info from a given address. The main responsibility of this method is to connect to a router and obtain a raw set of routing records; their correctness is not checked. This method also triggers removal of routers that are unavailable for connection. There are three possible outcomes: a list of routing records, None if the server cannot be contacted or ServiceUnavailable if the server exists but does not provide a valid routing service.
  • fetch_routing_table(address) - Wrapper for fetch_routing_info that parses the received routing records, checks them for correctness and builds and returns a new RoutingTable instance. If the fetch_routing_info method returns None, so does this method. If the records cannot be parsed, a ProtocolError is raised. If there is only one router and no writers, a ServiceUnavailable is raised.
  • update_routing_table() - This method steps through all known routers, attempting to fetch a routing table from each. The first to respond correctly will immediately be used to update the main routing table adn the method will exit. If no routing table can be obtained after querying all servers, ServiceUnavailable is raised.
  • refresh_routing_table() - Conditionally call update_routing_table if the current table is stale. This method checks freshness twice: one immediately and once after obtaining the refresh_lock. This ensures that concurrent refreshes do not interfere with each other and no unnecessary parallel calls are made.
  • acquire_for_read - Performs a refresh followed by acquisition of a connection to one of the addresses in the readers table.
  • acquire_for_write - Performs a refresh followed by acquisition of a connection to one of the addresses in the writers table.
  • remove - Remove an adddress from the routing table and from the connection pool itself (via ConnectionPool.remove).

@zhenlineo zhenlineo merged commit 96fcb55 into 1.1 Dec 13, 2016
@zhenlineo zhenlineo deleted the 1.1-routing-spec branch April 24, 2017 13:12
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.

2 participants