+
+"""
+I contain the client-side code which speaks to storage servers, in particular
+the foolscap-based server implemented in src/allmydata/storage/*.py .
+"""
+
+# roadmap:
+#
+# implement ServerFarm, change Client to create it, change
+# uploader/servermap to get rrefs from it. ServerFarm calls
+# IntroducerClient.subscribe_to .
+#
+# implement NativeStorageClient, change Tahoe2PeerSelector to use it. All
+# NativeStorageClients come from the introducer
+#
+# change web/check_results.py to get NativeStorageClients from check results,
+# ask it for a nickname (instead of using client.get_nickname_for_serverid)
+#
+# implement tahoe.cfg scanner, create static NativeStorageClients
+
+import sha
+
+class StorageFarmBroker:
+ """I live on the client, and know about storage servers. For each server
+ that is participating in a grid, I either maintain a connection to it or
+ remember enough information to establish a connection to it on demand.
+ 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, permute_peers=True):
+ assert permute_peers # False not implemented yet
+ self.servers = {} # serverid -> StorageClient instance
+ self.permute_peers = permute_peers
+ self.introducer_client = None
+ def add_server(self, serverid, s):
+ self.servers[serverid] = s
+ def use_introducer(self, introducer_client):
+ self.introducer_client = ic = introducer_client
+ ic.subscribe_to("storage")
+
+ def get_servers(self, peer_selection_index):
+ # first cut: return an iterator of (peerid, versioned-rref) tuples
+ assert self.permute_peers == True
+ servers = {}
+ for serverid,server in self.servers.items():
+ servers[serverid] = server
+ if self.introducer_client:
+ ic = self.introducer_client
+ for serverid,server in ic.get_permuted_peers("storage",
+ peer_selection_index):
+ servers[serverid] = server
+ servers = servers.items()
+ key = peer_selection_index
+ return sorted(servers, key=lambda x: sha.new(key+x[0]).digest())
+
+ def get_all_serverids(self):
+ for serverid in self.servers:
+ yield serverid
+ if self.introducer_client:
+ for serverid,server in self.introducer_client.get_peers("storage"):
+ yield serverid
+
+ def get_nickname_for_serverid(self, serverid):
+ if serverid in self.servers:
+ return self.servers[serverid].nickname
+ if self.introducer_client:
+ return self.introducer_client.get_nickname_for_peerid(serverid)
+ return None
+
+class NativeStorageClient:
+ def __init__(self, serverid, furl, nickname, min_shares=1):
+ self.serverid = serverid
+ self.furl = furl
+ self.nickname = nickname
+ self.min_shares = min_shares
+
+class UnknownServerTypeError(Exception):
+ pass