#538: add remote_get_version() to four main Referenceable objects: Introducer Service, Storage Server, Helper, CHK Upload Helper. Remove unused storage-server get_versions().

This commit is contained in:
Brian Warner 2008-11-21 17:43:52 -07:00
parent 1d377cc2d9
commit 0eb6b324a4
7 changed files with 52 additions and 27 deletions

View File

@ -81,7 +81,7 @@ class ControlServer(Referenceable, service.Service):
return results
peerid, connection = everyone_left.pop(0)
start = time.time()
d = connection.callRemote("get_versions")
d = connection.callRemote("get_version")
def _done(ignored):
stop = time.time()
elapsed = stop - start

View File

@ -1,7 +1,7 @@
from zope.interface import Interface
from foolscap.schema import StringConstraint, ListOf, TupleOf, SetOf, DictOf, \
ChoiceOf, IntegerConstraint
ChoiceOf, IntegerConstraint, Any
from foolscap import RemoteInterface, Referenceable
HASH_SIZE=32
@ -86,21 +86,11 @@ ReadData = ListOf(ShareData)
class RIStorageServer(RemoteInterface):
__remote_name__ = "RIStorageServer.tahoe.allmydata.com"
def get_versions():
def get_version():
"""
Return a tuple of (my_version, oldest_supported) strings. Each string can be parsed by
a pyutil.version_class.Version instance or a distutils.version.LooseVersion instance,
and then compared. The first goal is to make sure that nodes are not confused by
speaking to an incompatible peer. The second goal is to enable the development of
backwards-compatibility code.
The meaning of the oldest_supported element is that if you treat this storage server as
though it were of that version, then you will not be disappointed.
The precise meaning of this method might change in incompatible ways until we get the
whole compatibility scheme nailed down.
Return a dictionary of version information.
"""
return TupleOf(str, str)
return DictOf(str, Any())
def allocate_buckets(storage_index=StorageIndex,
renew_secret=LeaseRenewSecret,
@ -351,8 +341,6 @@ class IStorageBucketReader(Interface):
# hm, we need a solution for forward references in schemas
from foolscap.schema import Any
FileNode_ = Any() # TODO: foolscap needs constraints on copyables
DirectoryNode_ = Any() # TODO: same
AnyNode_ = ChoiceOf(FileNode_, DirectoryNode_)
@ -2077,6 +2065,12 @@ class RIEncryptedUploadable(RemoteInterface):
class RICHKUploadHelper(RemoteInterface):
__remote_name__ = "RIUploadHelper.tahoe.allmydata.com"
def get_version():
"""
Return a dictionary of version information.
"""
return DictOf(str, Any())
def upload(reader=RIEncryptedUploadable):
return UploadResults
@ -2084,6 +2078,12 @@ class RICHKUploadHelper(RemoteInterface):
class RIHelper(RemoteInterface):
__remote_name__ = "RIHelper.tahoe.allmydata.com"
def get_version():
"""
Return a dictionary of version information.
"""
return DictOf(str, Any())
def upload_chk(si=StorageIndex):
"""See if a file with a given storage index needs uploading. The
helper will ask the appropriate storage servers to see if the file

View File

@ -1,6 +1,6 @@
from zope.interface import Interface
from foolscap.schema import StringConstraint, TupleOf, SetOf
from foolscap.schema import StringConstraint, TupleOf, SetOf, DictOf, Any
from foolscap import RemoteInterface
FURL = StringConstraint(1000)
@ -68,6 +68,8 @@ class RIIntroducerSubscriberService(RemoteInterface):
class RIIntroducerPublisherAndSubscriberService(RemoteInterface):
__remote_name__ = "RIIntroducerPublisherAndSubscriberService.tahoe.allmydata.com"
def get_version():
return DictOf(str, Any())
def publish(announcement=Announcement):
return None
def subscribe(subscriber=RIIntroducerSubscriberClient, service_name=str):

View File

@ -3,6 +3,7 @@ import time, os.path
from zope.interface import implements
from twisted.application import service
from foolscap import Referenceable
import allmydata
from allmydata import node
from allmydata.util import log
from allmydata.introducer.interfaces import \
@ -46,6 +47,10 @@ class IntroducerNode(node.Node):
class IntroducerService(service.MultiService, Referenceable):
implements(RIIntroducerPublisherAndSubscriberService)
name = "introducer"
VERSION = { "http://allmydata.org/tahoe/protocols/introducer/v1":
{ },
"application-version": str(allmydata.__version__),
}
def __init__(self, basedir="."):
service.MultiService.__init__(self)
@ -64,6 +69,9 @@ class IntroducerService(service.MultiService, Referenceable):
def get_subscribers(self):
return self._subscribers
def remote_get_version(self):
return self.VERSION
def remote_publish(self, announcement):
self.log("introducer: announcement published: %s" % (announcement,) )
index = make_index(announcement)

View File

@ -5,6 +5,7 @@ from twisted.application import service
from twisted.internet import defer
from foolscap import Referenceable, DeadReferenceError
from foolscap.eventual import eventually
import allmydata
from allmydata import interfaces, storage, uri
from allmydata.immutable import upload
from allmydata.immutable.layout import ReadBucketProxy
@ -131,6 +132,10 @@ class CHKUploadHelper(Referenceable, upload.CHKUploader):
remote AssistedUploader.
"""
implements(interfaces.RICHKUploadHelper)
VERSION = { "http://allmydata.org/tahoe/protocols/helper/chk-upload/v1" :
{ },
"application-version": str(allmydata.__version__),
}
def __init__(self, storage_index, helper,
incoming_file, encoding_file,
@ -186,6 +191,9 @@ class CHKUploadHelper(Referenceable, upload.CHKUploader):
self.log("no ciphertext yet", level=log.NOISY)
return (self._results, self)
def remote_get_version(self):
return self.VERSION
def remote_upload(self, reader):
# reader is an RIEncryptedUploadable. I am specified to return an
# UploadResults dictionary.
@ -482,6 +490,10 @@ class Helper(Referenceable, service.MultiService):
# helper at random.
name = "helper"
VERSION = { "http://allmydata.org/tahoe/protocols/helper/v1" :
{ },
"application-version": str(allmydata.__version__),
}
chk_upload_helper_class = CHKUploadHelper
MAX_UPLOAD_STATUSES = 10
@ -554,6 +566,9 @@ class Helper(Referenceable, service.MultiService):
stats.update(self._counters)
return stats
def remote_get_version(self):
return self.VERSION
def remote_upload_chk(self, storage_index):
self.count("chk_upload_helper.upload_requests")
r = upload.UploadResults()

View File

@ -1,5 +1,4 @@
import os, re, weakref, stat, struct, time
from distutils.version import LooseVersion
from foolscap import Referenceable
from twisted.application import service
@ -764,10 +763,10 @@ def create_mutable_sharefile(filename, my_nodeid, write_enabler, parent):
class StorageServer(service.MultiService, Referenceable):
implements(RIStorageServer, IStatsProducer)
name = 'storage'
# This means that if a client treats me as though I were a 1.0.0 storage server, they will
# not be disappointed.
OLDEST_SUPPORTED_VERSION = LooseVersion("1.0.0")
VERSION = { "http://allmydata.org/tahoe/protocols/storage/v1" :
{ "maximum-immutable-share-size": 2**32 },
"application-version": str(allmydata.__version__),
}
def __init__(self, storedir, sizelimit=None,
discard_storage=False, readonly_storage=False,
@ -899,8 +898,8 @@ class StorageServer(service.MultiService, Referenceable):
space += bw.allocated_size()
return space
def remote_get_versions(self):
return (str(allmydata.__version__), str(self.OLDEST_SUPPORTED_VERSION))
def remote_get_version(self):
return self.VERSION
def remote_allocate_buckets(self, storage_index,
renew_secret, cancel_secret,

View File

@ -153,8 +153,9 @@ class Basic(unittest.TestCase):
open(os.path.join(basedir, "vdrive.furl"), "w").write("")
c = client.Client(basedir)
ss = c.getServiceNamed("storage")
mine, oldest = ss.remote_get_versions()
self.failUnlessEqual(mine, str(allmydata.__version__))
verdict = ss.remote_get_version()
self.failUnlessEqual(verdict["application-version"],
str(allmydata.__version__))
self.failIfEqual(str(allmydata.__version__), "unknown")
self.failUnless("." in str(allmydata.__version__),
"non-numeric version in '%s'" % allmydata.__version__)