Merge branch 'master' into 6234-user-edit-self
[arvados.git] / services / fuse / arvados_fuse / fresh.py
1 import time
2 import ciso8601
3 import calendar
4 import functools
5
6 def convertTime(t):
7     """Parse Arvados timestamp to unix time."""
8     if not t:
9         return 0
10     try:
11         return calendar.timegm(ciso8601.parse_datetime_unaware(t).timetuple())
12     except (TypeError, ValueError):
13         return 0
14
15 def use_counter(orig_func):
16     @functools.wraps(orig_func)
17     def use_counter_wrapper(self, *args, **kwargs):
18         try:
19             self.inc_use()
20             return orig_func(self, *args, **kwargs)
21         finally:
22             self.dec_use()
23     return use_counter_wrapper
24
25 def check_update(orig_func):
26     @functools.wraps(orig_func)
27     def check_update_wrapper(self, *args, **kwargs):
28         self.checkupdate()
29         return orig_func(self, *args, **kwargs)
30     return check_update_wrapper
31
32 class FreshBase(object):
33     """Base class for maintaining object lifecycle.
34
35     Functions include:
36
37     * Indicate if an object is up to date (stale() == false) or needs to be
38       updated sets stale() == True).  Use invalidate() to mark the object as
39       stale.  An object is also automatically stale if it has not been updated
40       in `_poll_time` seconds.
41
42     * Record access time (atime) timestamp
43
44     * Manage internal use count used by the inode cache ("inc_use" and
45       "dec_use").  An object which is in use cannot be cleared by the inode
46       cache.
47
48     * Manage the kernel reference count ("inc_ref" and "dec_ref").  An object
49       which is referenced by the kernel cannot have its inode entry deleted.
50
51     * Record cache footprint, cache priority
52
53     * Record Arvados uuid at the time the object is placed in the cache
54
55     * Clear the object contents (invalidates the object)
56
57     """
58     def __init__(self):
59         self._stale = True
60         self._poll = False
61         self._last_update = time.time()
62         self._atime = time.time()
63         self._poll_time = 60
64         self.use_count = 0
65         self.ref_count = 0
66         self.dead = False
67         self.cache_priority = None
68         self.cache_size = 0
69         self.cache_uuid = None
70
71     # Mark the value as stale
72     def invalidate(self):
73         self._stale = True
74
75     # Test if the entries dict is stale.
76     def stale(self):
77         if self._stale:
78             return True
79         if self._poll:
80             return (self._last_update + self._poll_time) < self._atime
81         return False
82
83     def fresh(self):
84         self._stale = False
85         self._last_update = time.time()
86
87     def atime(self):
88         return self._atime
89
90     def persisted(self):
91         return False
92
93     def clear(self, force=False):
94         pass
95
96     def in_use(self):
97         return self.use_count > 0
98
99     def inc_use(self):
100         self.use_count += 1
101
102     def dec_use(self):
103         self.use_count -= 1
104
105     def inc_ref(self):
106         self.ref_count += 1
107         return self.ref_count
108
109     def dec_ref(self, n):
110         self.ref_count -= n
111         return self.ref_count
112
113     def objsize(self):
114         return 0
115
116     def uuid(self):
117         return None
118
119     def finalize(self):
120         pass