from allmydata.interfaces import RIStorageServer
from allmydata import node
+from zope.interface import implements
from twisted.internet import reactor
from twisted.application.internet import TimerService
+from foolscap import Referenceable
from foolscap.logging import log
import allmydata
from allmydata.mutable import MutableFileNode, MutableWatcher
from allmydata.stats import StatsProvider
from allmydata.interfaces import IURI, INewDirectoryURI, \
- IReadonlyNewDirectoryURI, IFileURI, IMutableFileURI
+ IReadonlyNewDirectoryURI, IFileURI, IMutableFileURI, RIStubClient
KiB=1024
MiB=1024*KiB
TiB=1024*GiB
PiB=1024*TiB
+class StubClient(Referenceable):
+ implements(RIStubClient)
+
class Client(node.Node, testutil.PollMixin):
PORTNUMFILE = "client.port"
STOREDIR = 'storage'
run_helper = self.get_config("run_helper")
if run_helper:
self.init_helper()
- helper_furl = self.get_config("helper.furl")
- self.add_service(Uploader(helper_furl))
- self.add_service(Downloader())
- self.add_service(Checker())
- self.add_service(MutableWatcher())
+ self.init_client()
# ControlServer and Helper are attached after Tub startup
hotline_file = os.path.join(self.basedir,
d.addCallback(_publish)
d.addErrback(log.err, facility="tahoe.init", level=log.BAD)
+ def init_client(self):
+ helper_furl = self.get_config("helper.furl")
+ self.add_service(Uploader(helper_furl))
+ self.add_service(Downloader())
+ self.add_service(Checker())
+ self.add_service(MutableWatcher())
+ def _publish(res):
+ # we publish an empty object so that the introducer can count how
+ # many clients are connected and see what versions they're
+ # running.
+ sc = StubClient()
+ furl = self.tub.registerReference(sc)
+ ri_name = RIStubClient.__remote_name__
+ self.introducer_client.publish(furl, "stub_client", ri_name)
+ d = self.when_tub_ready()
+ d.addCallback(_publish)
+ d.addErrback(log.err, facility="tahoe.init", level=log.BAD)
+
def init_control(self):
d = self.when_tub_ready()
def _publish(res):
"""Returns a boolean, True if we are currently connected to the
introducer, False if not."""
+class RIStubClient(RemoteInterface):
+ """Each client publishes a service announcement for a dummy object called
+ the StubClient. This object doesn't actually offer any services, but the
+ announcement helps the Introducer keep track of which clients are
+ subscribed (so the grid admin can keep track of things like the size of
+ the grid and the client versions in use. This is the (empty)
+ RemoteInterface for the StubClient."""
class RIBucketWriter(RemoteInterface):
def write(offset=Offset, data=ShareData):