Skip to content

Commit

Permalink
Merge pull request #204 from leif/preferred_peers-rebased3
Browse files Browse the repository at this point in the history
new feature: preferred storage servers
  • Loading branch information
daira committed Dec 4, 2015
2 parents 45ec924 + 96eaca6 commit b5222e3
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 4 deletions.
25 changes: 25 additions & 0 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,31 @@ Client Configuration
.. _performance.rst: performance.rst
.. _mutable.rst: specifications/mutable.rst

``peers.preferred = (string, optional)``

This is an optional comma-separated list of Node IDs of servers that will
be tried first when selecting storage servers for reading or writing.

Servers should be identified here by their Node ID as it appears in the web
ui, underneath the server's nickname. For storage servers running tahoe
versions >=1.10 (if the introducer is also running tahoe >=1.10) this will
be a "Node Key" (which is prefixed with 'v0-'). For older nodes, it will be
a TubID instead. When a preferred server (and/or the introducer) is
upgraded to 1.10 or later, clients must adjust their configs accordingly.

Every node selected for upload, whether preferred or not, will still
receive the same number of shares (one, if there are ``N`` or more servers
accepting uploads). Preferred nodes are simply moved to the front of the
server selection lists computed for each file.

This is useful if a subset of your nodes have different availability or
connectivity characteristics than the rest of the grid. For instance, if
there are more than ``N`` servers on the grid, and ``K`` or more of them
are at a single physical location, it would make sense for clients at that
location to prefer their local servers so that they can maintain access to
all of their uploads without using the internet.


Frontend Configuration
======================

Expand Down
4 changes: 3 additions & 1 deletion src/allmydata/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,9 @@ def init_client(self):
def init_client_storage_broker(self):
# create a StorageFarmBroker object, for use by Uploader/Downloader
# (and everybody else who wants to use storage servers)
sb = storage_client.StorageFarmBroker(self.tub, permute_peers=True)
ps = self.get_config("client", "peers.preferred", "").split(",")
preferred_peers = tuple([p.strip() for p in ps if p != ""])
sb = storage_client.StorageFarmBroker(self.tub, permute_peers=True, preferred_peers=preferred_peers)
self.storage_broker = sb

# load static server specifications from tahoe.cfg, if any.
Expand Down
10 changes: 7 additions & 3 deletions src/allmydata/storage_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ class StorageFarmBroker:
I'm also responsible for subscribing to the IntroducerClient to find out
about new servers as they are announced by the Introducer.
"""
def __init__(self, tub, permute_peers):
def __init__(self, tub, permute_peers, preferred_peers=()):
self.tub = tub
assert permute_peers # False not implemented yet
self.permute_peers = permute_peers
self.preferred_peers = preferred_peers
# self.servers maps serverid -> IServer, and keeps track of all the
# storage servers that we've heard about. Each descriptor manages its
# own Reconnector, and will give us a RemoteReference when we ask
Expand Down Expand Up @@ -121,10 +122,13 @@ def _trigger_connections(self):
def get_servers_for_psi(self, peer_selection_index):
# return a list of server objects (IServers)
assert self.permute_peers == True
connected_servers = self.get_connected_servers()
preferred_servers = frozenset(s for s in connected_servers if s.get_longname() in self.preferred_peers)
def _permuted(server):
seed = server.get_permutation_seed()
return sha1(peer_selection_index + seed).digest()
return sorted(self.get_connected_servers(), key=_permuted)
is_unpreferred = server not in preferred_servers
return (is_unpreferred, sha1(peer_selection_index + seed).digest())
return sorted(connected_servers, key=_permuted)

def get_all_serverids(self):
return frozenset(self.servers.keys())
Expand Down
12 changes: 12 additions & 0 deletions src/allmydata/test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,18 @@ def test_permute(self):
sb.servers.clear()
self.failUnlessReallyEqual(self._permute(sb, "one"), [])

def test_permute_with_preferred(self):
sb = StorageFarmBroker(None, True, ['1','4'])
for k in ["%d" % i for i in range(5)]:
ann = {"anonymous-storage-FURL": "pb://abcde@nowhere/fake",
"permutation-seed-base32": base32.b2a(k) }
sb.test_add_rref(k, "rref", ann)

self.failUnlessReallyEqual(self._permute(sb, "one"), ['1','4','3','0','2'])
self.failUnlessReallyEqual(self._permute(sb, "two"), ['4','1','0','2','3'])
sb.servers.clear()
self.failUnlessReallyEqual(self._permute(sb, "one"), [])

def test_versions(self):
basedir = "test_client.Basic.test_versions"
os.mkdir(basedir)
Expand Down

0 comments on commit b5222e3

Please sign in to comment.