]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/storage_client.py
clean up storage_broker interface: should fix #732
[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 from zope.interface import implements
23 from allmydata.interfaces import IStorageBroker
24
25 class StorageFarmBroker:
26     implements(IStorageBroker)
27     """I live on the client, and know about storage servers. For each server
28     that is participating in a grid, I either maintain a connection to it or
29     remember enough information to establish a connection to it on demand.
30     I'm also responsible for subscribing to the IntroducerClient to find out
31     about new servers as they are announced by the Introducer.
32     """
33     def __init__(self, permute_peers=True):
34         assert permute_peers # False not implemented yet
35         self.servers = {} # serverid -> StorageClient instance
36         self.permute_peers = permute_peers
37         self.introducer_client = None
38     def add_server(self, serverid, s):
39         self.servers[serverid] = s
40     def use_introducer(self, introducer_client):
41         self.introducer_client = ic = introducer_client
42         ic.subscribe_to("storage")
43
44     def get_servers_for_index(self, peer_selection_index):
45         # first cut: return a list of (peerid, versioned-rref) tuples
46         assert self.permute_peers == True
47         servers = self.get_all_servers()
48         key = peer_selection_index
49         return sorted(servers, key=lambda x: sha.new(key+x[0]).digest())
50
51     def get_all_servers(self):
52         # return a frozenset of (peerid, versioned-rref) tuples
53         servers = {}
54         for serverid,server in self.servers.items():
55             servers[serverid] = server
56         if self.introducer_client:
57             ic = self.introducer_client
58             for serverid,server in ic.get_peers("storage"):
59                 servers[serverid] = server
60         return frozenset(servers.items())
61
62     def get_all_serverids(self):
63         for serverid in self.servers:
64             yield serverid
65         if self.introducer_client:
66             for serverid,server in self.introducer_client.get_peers("storage"):
67                 yield serverid
68
69     def get_nickname_for_serverid(self, serverid):
70         if serverid in self.servers:
71             return self.servers[serverid].nickname
72         if self.introducer_client:
73             return self.introducer_client.get_nickname_for_peerid(serverid)
74         return None
75
76 class NativeStorageClient:
77     def __init__(self, serverid, furl, nickname, min_shares=1):
78         self.serverid = serverid
79         self.furl = furl
80         self.nickname = nickname
81         self.min_shares = min_shares
82
83 class UnknownServerTypeError(Exception):
84     pass