have expired. Other controls dictate when leases are considered to have
expired. The default is False.
-expire.mode = (string, "age" or "date-cutoff", required if expiration enabled)
+expire.mode = (string, "age" or "cutoff-date", required if expiration enabled)
If this string is "age", the age-based expiration scheme is used, and the
"expire.override_lease_duration" setting can be provided to influence the
- lease ages. If it is "date-cutoff", the absolute-date-cutoff mode is used,
+ lease ages. If it is "cutoff-date", the absolute-date-cutoff mode is used,
and the "expire.cutoff_date" setting must be provided to specify the cutoff
date. The mode setting currently has no default: you must provide a value.
been passed.
This key is only valid when age-based expiration is in use (i.e. when
- "expire.mode = age" is used). It will be rejected if date-cutoff expiration
+ "expire.mode = age" is used). It will be rejected if cutoff-date expiration
is in use.
-expire.cutoff_date = (date string, required if mode=date-cutoff)
+expire.cutoff_date = (date string, required if mode=cutoff-date)
- When date-cutoff expiration is in use, a lease will be expired if its
+ When cutoff-date expiration is in use, a lease will be expired if its
create/renew timestamp is older than the cutoff date. This string will be a
date in the following format:
last renewal time and the cutoff date.
This key is only valid when cutoff-based expiration is in use (i.e. when
- "expire.mode = date-cutoff"). It will be rejected if age-based expiration is
+ "expire.mode = cutoff-date"). It will be rejected if age-based expiration is
in use.
expire.immutable = (boolean, optional)
from allmydata.introducer.client import IntroducerClient
from allmydata.util import hashutil, base32, pollmixin, cachedir
from allmydata.util.abbreviate import parse_abbreviated_size
+from allmydata.util.time_format import parse_duration, parse_date
from allmydata.uri import LiteralFileURI
from allmydata.dirnode import NewDirectoryNode
from allmydata.mutable.filenode import MutableFileNode
reserved = 0
discard = self.get_config("storage", "debug_discard", False,
boolean=True)
+
+ expire = self.get_config("storage", "expire.enabled", False, boolean=True)
+ if expire:
+ mode = self.get_config("storage", "expire.mode") # require a mode
+ else:
+ mode = self.get_config("storage", "expire.mode", "age")
+
+ o_l_d = self.get_config("storage", "expire.override_lease_duration", None)
+ if o_l_d is not None:
+ o_l_d = parse_duration(o_l_d)
+
+ cutoff_date = None
+ if mode == "cutoff-date":
+ cutoff_date = self.get_config("storage", "expire.cutoff_date")
+ cutoff_date = parse_date(cutoff_date)
+
+ sharetypes = []
+ if self.get_config("storage", "expire.immutable", True, boolean=True):
+ sharetypes.append("immutable")
+ if self.get_config("storage", "expire.mutable", True, boolean=True):
+ sharetypes.append("mutable")
+ expiration_sharetypes = tuple(sharetypes)
+
ss = StorageServer(storedir, self.nodeid,
reserved_space=reserved,
discard_storage=discard,
readonly_storage=readonly,
- stats_provider=self.stats_provider)
+ stats_provider=self.stats_provider,
+ expiration_enabled=expire,
+ expiration_mode=mode,
+ expiration_override_lease_duration=o_l_d,
+ expiration_cutoff_date=cutoff_date,
+ expiration_sharetypes=expiration_sharetypes)
self.add_service(ss)
+
d = self.when_tub_ready()
# we can't do registerReference until the Tub is ready
def _publish(res):
def __init__(self, server, statefile, historyfile,
expiration_enabled, mode,
override_lease_duration, # used if expiration_mode=="age"
- date_cutoff, # used if expiration_mode=="date-cutoff"
+ cutoff_date, # used if expiration_mode=="cutoff-date"
sharetypes):
self.historyfile = historyfile
self.expiration_enabled = expiration_enabled
self.mode = mode
self.override_lease_duration = None
- self.date_cutoff = None
+ self.cutoff_date = None
if self.mode == "age":
assert isinstance(override_lease_duration, (int, type(None)))
self.override_lease_duration = override_lease_duration # seconds
- elif self.mode == "date-cutoff":
- assert isinstance(date_cutoff, int) # seconds-since-epoch
- assert date_cutoff is not None
- self.date_cutoff = date_cutoff
+ elif self.mode == "cutoff-date":
+ assert isinstance(cutoff_date, int) # seconds-since-epoch
+ assert cutoff_date is not None
+ self.cutoff_date = cutoff_date
else:
- raise ValueError("GC mode '%s' must be 'age' or 'date-cutoff'" % mode)
+ raise ValueError("GC mode '%s' must be 'age' or 'cutoff-date'" % mode)
self.sharetypes_to_expire = sharetypes
ShareCrawler.__init__(self, server, statefile)
if age > age_limit:
expired = True
else:
- assert self.mode == "date-cutoff"
- if grant_renew_time < self.date_cutoff:
+ assert self.mode == "cutoff-date"
+ if grant_renew_time < self.cutoff_date:
expired = True
if sharetype not in self.sharetypes_to_expire:
expired = False
h["expiration-enabled"] = self.expiration_enabled
h["configured-expiration-mode"] = (self.mode,
self.override_lease_duration,
- self.date_cutoff,
+ self.cutoff_date,
self.sharetypes_to_expire)
s = self.state["cycle-to-date"]
so_far["expiration-enabled"] = self.expiration_enabled
so_far["configured-expiration-mode"] = (self.mode,
self.override_lease_duration,
- self.date_cutoff,
+ self.cutoff_date,
self.sharetypes_to_expire)
so_far_sr = so_far["space-recovered"]
expiration_enabled=False,
expiration_mode="age",
expiration_override_lease_duration=None,
- expiration_date_cutoff=None,
+ expiration_cutoff_date=None,
expiration_sharetypes=("mutable", "immutable")):
service.MultiService.__init__(self)
assert isinstance(nodeid, str)
self.lease_checker = klass(self, statefile, historyfile,
expiration_enabled, expiration_mode,
expiration_override_lease_duration,
- expiration_date_cutoff,
+ expiration_cutoff_date,
expiration_sharetypes)
self.lease_checker.setServiceParent(self)
d.addCallback(_check_html)
return d
- def test_expire_date_cutoff(self):
- basedir = "storage/LeaseCrawler/expire_date_cutoff"
+ def test_expire_cutoff_date(self):
+ basedir = "storage/LeaseCrawler/expire_cutoff_date"
fileutil.make_dirs(basedir)
- # setting date-cutoff to 2000 seconds ago means that any lease which
+ # setting cutoff-date to 2000 seconds ago means that any lease which
# is more than 2000s old will be expired.
now = time.time()
then = int(now - 2000)
ss = InstrumentedStorageServer(basedir, "\x00" * 20,
expiration_enabled=True,
- expiration_mode="date-cutoff",
- expiration_date_cutoff=then)
+ expiration_mode="cutoff-date",
+ expiration_cutoff_date=then)
# make it start sooner than usual.
lc = ss.lease_checker
lc.slow_start = 0
self.failUnlessEqual(last["expiration-enabled"], True)
self.failUnlessEqual(last["configured-expiration-mode"],
- ("date-cutoff", None, then,
+ ("cutoff-date", None, then,
("mutable", "immutable")))
self.failUnlessEqual(last["leases-per-share-histogram"],
{1: 2, 2: 2})
then = int(now - 2000)
ss = StorageServer(basedir, "\x00" * 20,
expiration_enabled=True,
- expiration_mode="date-cutoff",
- expiration_date_cutoff=then,
+ expiration_mode="cutoff-date",
+ expiration_cutoff_date=then,
expiration_sharetypes=("immutable",))
lc = ss.lease_checker
lc.slow_start = 0
then = int(now - 2000)
ss = StorageServer(basedir, "\x00" * 20,
expiration_enabled=True,
- expiration_mode="date-cutoff",
- expiration_date_cutoff=then,
+ expiration_mode="cutoff-date",
+ expiration_cutoff_date=then,
expiration_sharetypes=("mutable",))
lc = ss.lease_checker
lc.slow_start = 0
e = self.failUnlessRaises(ValueError,
StorageServer, basedir, "\x00" * 20,
expiration_mode="bogus")
- self.failUnless("GC mode 'bogus' must be 'age' or 'date-cutoff'" in str(e), str(e))
+ self.failUnless("GC mode 'bogus' must be 'age' or 'cutoff-date'" in str(e), str(e))
def test_parse_duration(self):
DAY = 24*60*60