]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/introducer/interfaces.py
introducer: move the relevant interfaces out to introducer/interfaces.py
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / introducer / interfaces.py
1
2 from zope.interface import Interface
3 from foolscap.schema import StringConstraint, TupleOf, SetOf
4 from foolscap import RemoteInterface
5 FURL = StringConstraint(1000)
6
7 # Announcements are (FURL, service_name, remoteinterface_name,
8 #                    nickname, my_version, oldest_supported)
9 #  the (FURL, service_name, remoteinterface_name) refer to the service being
10 #  announced. The (nickname, my_version, oldest_supported) refer to the
11 #  client as a whole. The my_version/oldest_supported strings can be parsed
12 #  by an allmydata.util.version.Version instance, and then compared. The
13 #  first goal is to make sure that nodes are not confused by speaking to an
14 #  incompatible peer. The second goal is to enable the development of
15 #  backwards-compatibility code.
16
17 Announcement = TupleOf(FURL, str, str,
18                        str, str, str)
19
20 class RIIntroducerSubscriberClient(RemoteInterface):
21     __remote_name__ = "RIIntroducerSubscriberClient.tahoe.allmydata.com"
22
23     def announce(announcements=SetOf(Announcement)):
24         """I accept announcements from the publisher."""
25         return None
26
27     def set_encoding_parameters(parameters=(int, int, int)):
28         """Advise the client of the recommended k-of-n encoding parameters
29         for this grid. 'parameters' is a tuple of (k, desired, n), where 'n'
30         is the total number of shares that will be created for any given
31         file, while 'k' is the number of shares that must be retrieved to
32         recover that file, and 'desired' is the minimum number of shares that
33         must be placed before the uploader will consider its job a success.
34         n/k is the expansion ratio, while k determines the robustness.
35
36         Introducers should specify 'n' according to the expected size of the
37         grid (there is no point to producing more shares than there are
38         peers), and k according to the desired reliability-vs-overhead goals.
39
40         Note that setting k=1 is equivalent to simple replication.
41         """
42         return None
43
44 # When Foolscap can handle multiple interfaces (Foolscap#17), the
45 # full-powered introducer will implement both RIIntroducerPublisher and
46 # RIIntroducerSubscriberService. Until then, we define
47 # RIIntroducerPublisherAndSubscriberService as a combination of the two, and
48 # make everybody use that.
49
50 class RIIntroducerPublisher(RemoteInterface):
51     """To publish a service to the world, connect to me and give me your
52     announcement message. I will deliver a copy to all connected subscribers."""
53     __remote_name__ = "RIIntroducerPublisher.tahoe.allmydata.com"
54
55     def publish(announcement=Announcement):
56         # canary?
57         return None
58
59 class RIIntroducerSubscriberService(RemoteInterface):
60     __remote_name__ = "RIIntroducerSubscriberService.tahoe.allmydata.com"
61
62     def subscribe(subscriber=RIIntroducerSubscriberClient, service_name=str):
63         """Give me a subscriber reference, and I will call its new_peers()
64         method will any announcements that match the desired service name. I
65         will ignore duplicate subscriptions.
66         """
67         return None
68
69 class RIIntroducerPublisherAndSubscriberService(RemoteInterface):
70     __remote_name__ = "RIIntroducerPublisherAndSubscriberService.tahoe.allmydata.com"
71     def publish(announcement=Announcement):
72         return None
73     def subscribe(subscriber=RIIntroducerSubscriberClient, service_name=str):
74         return None
75
76 class IIntroducerClient(Interface):
77     """I provide service introduction facilities for a node. I help nodes
78     publish their services to the rest of the world, and I help them learn
79     about services available on other nodes."""
80
81     def publish(furl, service_name, remoteinterface_name):
82         """Once you call this, I will tell the world that the Referenceable
83         available at FURL is available to provide a service named
84         SERVICE_NAME. The precise definition of the service being provided is
85         identified by the Foolscap 'remote interface name' in the last
86         parameter: this is supposed to be a globally-unique string that
87         identifies the RemoteInterface that is implemented."""
88
89     def subscribe_to(service_name):
90         """Call this if you will eventually want to use services with the
91         given SERVICE_NAME. This will prompt me to subscribe to announcements
92         of those services. You can pick up the announcements later by calling
93         get_all_connections_for() or get_permuted_peers().
94         """
95
96     def get_all_connections():
97         """Return a frozenset of (nodeid, service_name, rref) tuples, one for
98         each active connection we've established to a remote service. This is
99         mostly useful for unit tests that need to wait until a certain number
100         of connections have been made."""
101
102     def get_all_connectors():
103         """Return a dict that maps from (nodeid, service_name) to a
104         RemoteServiceConnector instance for all services that we are actively
105         trying to connect to. Each RemoteServiceConnector has the following
106         public attributes::
107
108           service_name: the type of service provided, like 'storage'
109           announcement_time: when we first heard about this service
110           last_connect_time: when we last established a connection
111           last_loss_time: when we last lost a connection
112
113           version: the peer's version, from the most recent connection
114           oldest_supported: the peer's oldest supported version, same
115
116           rref: the RemoteReference, if connected, otherwise None
117           remote_host: the IAddress, if connected, otherwise None
118
119         This method is intended for monitoring interfaces, such as a web page
120         which describes connecting and connected peers.
121         """
122
123     def get_all_peerids():
124         """Return a frozenset of all peerids to whom we have a connection (to
125         one or more services) established. Mostly useful for unit tests."""
126
127     def get_all_connections_for(service_name):
128         """Return a frozenset of (nodeid, service_name, rref) tuples, one
129         for each active connection that provides the given SERVICE_NAME."""
130
131     def get_permuted_peers(service_name, key):
132         """Returns an ordered list of (peerid, rref) tuples, selecting from
133         the connections that provide SERVICE_NAME, using a hash-based
134         permutation keyed by KEY. This randomizes the service list in a
135         repeatable way, to distribute load over many peers.
136         """
137
138     def connected_to_introducer():
139         """Returns a boolean, True if we are currently connected to the
140         introducer, False if not."""
141