]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/storage_client.py
start to factor server-connection-management into a distinct 'StorageServerFarmBroker...
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / storage_client.py
1
2 """
3 I contain the client-side code which speaks to storage servers, in particular
4 the foolscap-based server implemented in src/allmydata/storage/*.py .
5 """
6
7 # roadmap:
8 #
9 #  implement ServerFarm, change Client to create it, change
10 #  uploader/servermap to get rrefs from it. ServerFarm calls
11 #  IntroducerClient.subscribe_to .
12 #
13 #  implement NativeStorageClient, change Tahoe2PeerSelector to use it. All
14 #  NativeStorageClients come from the introducer
15 #
16 #  change web/check_results.py to get NativeStorageClients from check results,
17 #  ask it for a nickname (instead of using client.get_nickname_for_serverid)
18 #
19 #  implement tahoe.cfg scanner, create static NativeStorageClients
20
21 import sha
22
23 class StorageFarmBroker:
24     """I live on the client, and know about storage servers. For each server
25     that is participating in a grid, I either maintain a connection to it or
26     remember enough information to establish a connection to it on demand.
27     I'm also responsible for subscribing to the IntroducerClient to find out
28     about new servers as they are announced by the Introducer.
29     """
30     def __init__(self, permute_peers=True):
31         assert permute_peers # False not implemented yet
32         self.servers = {} # serverid -> StorageClient instance
33         self.permute_peers = permute_peers
34         self.introducer_client = None
35     def add_server(self, serverid, s):
36         self.servers[serverid] = s
37     def use_introducer(self, introducer_client):
38         self.introducer_client = ic = introducer_client
39         ic.subscribe_to("storage")
40
41     def get_servers(self, peer_selection_index):
42         # first cut: return an iterator of (peerid, versioned-rref) tuples
43         assert self.permute_peers == True
44         servers = {}
45         for serverid,server in self.servers.items():
46             servers[serverid] = server
47         if self.introducer_client:
48             ic = self.introducer_client
49             for serverid,server in ic.get_permuted_peers("storage",
50                                                          peer_selection_index):
51                 servers[serverid] = server
52         servers = servers.items()
53         key = peer_selection_index
54         return sorted(servers, key=lambda x: sha.new(key+x[0]).digest())
55
56     def get_all_serverids(self):
57         for serverid in self.servers:
58             yield serverid
59         if self.introducer_client:
60             for serverid,server in self.introducer_client.get_peers("storage"):
61                 yield serverid
62
63     def get_nickname_for_serverid(self, serverid):
64         if serverid in self.servers:
65             return self.servers[serverid].nickname
66         if self.introducer_client:
67             return self.introducer_client.get_nickname_for_peerid(serverid)
68         return None
69
70 class NativeStorageClient:
71     def __init__(self, serverid, furl, nickname, min_shares=1):
72         self.serverid = serverid
73         self.furl = furl
74         self.nickname = nickname
75         self.min_shares = min_shares
76
77 class UnknownServerTypeError(Exception):
78     pass