1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
5 from builtins import object
12 """Parse Arvados timestamp to unix time."""
16 return calendar.timegm(ciso8601.parse_datetime_as_naive(t).timetuple())
17 except (TypeError, ValueError):
20 def use_counter(orig_func):
21 @functools.wraps(orig_func)
22 def use_counter_wrapper(self, *args, **kwargs):
25 return orig_func(self, *args, **kwargs)
28 return use_counter_wrapper
30 def check_update(orig_func):
31 @functools.wraps(orig_func)
32 def check_update_wrapper(self, *args, **kwargs):
34 return orig_func(self, *args, **kwargs)
35 return check_update_wrapper
37 class FreshBase(object):
38 """Base class for maintaining object lifecycle.
42 * Indicate if an object is up to date (stale() == false) or needs to be
43 updated sets stale() == True). Use invalidate() to mark the object as
44 stale. An object is also automatically stale if it has not been updated
45 in `_poll_time` seconds.
47 * Record access time (atime) timestamp
49 * Manage internal use count used by the inode cache ("inc_use" and
50 "dec_use"). An object which is in use cannot be cleared by the inode
53 * Manage the kernel reference count ("inc_ref" and "dec_ref"). An object
54 which is referenced by the kernel cannot have its inode entry deleted.
56 * Record cache footprint, cache priority
58 * Record Arvados uuid at the time the object is placed in the cache
60 * Clear the object contents (invalidates the object)
64 __slots__ = ("_stale", "_poll", "_last_update", "_atime", "_poll_time", "use_count",
65 "ref_count", "dead", "cache_size", "cache_uuid", "allow_attr_cache")
70 self._last_update = time.time()
71 self._atime = time.time()
77 self.cache_uuid = None
79 # Can the kernel cache attributes?
80 self.allow_attr_cache = True
83 """Indicate that object contents should be refreshed from source."""
86 def kernel_invalidate(self):
87 """Indicate that an invalidation for this object should be sent to the kernel."""
90 # Test if the entries dict is stale.
95 return (self._last_update + self._poll_time) < self._atime
100 self._last_update = time.time()
112 return self.use_count > 0
122 return self.ref_count
124 def dec_ref(self, n):
126 return self.ref_count
128 def has_ref(self, only_children):
129 """Determine if there are any kernel references to this
130 object or its children.
132 If only_children is True, ignore refcount of self and only consider
138 return self.ref_count > 0
149 def child_event(self, ev):
152 def time_to_next_poll(self):
154 t = (self._last_update + self._poll_time) - self._atime
160 return self._poll_time