8784: Fix test for latest firefox.
[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_size = 0
68         self.cache_uuid = None
69         self.allow_attr_cache = True
70         self.allow_dirent_cache = True
71
72     def invalidate(self):
73         """Indicate that object contents should be refreshed from source."""
74         self._stale = True
75
76     def kernel_invalidate(self):
77         """Indicate that an invalidation for this object should be sent to the kernel."""
78         pass
79
80     # Test if the entries dict is stale.
81     def stale(self):
82         if self._stale:
83             return True
84         if self._poll:
85             return (self._last_update + self._poll_time) < self._atime
86         return False
87
88     def fresh(self):
89         self._stale = False
90         self._last_update = time.time()
91
92     def atime(self):
93         return self._atime
94
95     def persisted(self):
96         return False
97
98     def clear(self):
99         pass
100
101     def in_use(self):
102         return self.use_count > 0
103
104     def inc_use(self):
105         self.use_count += 1
106
107     def dec_use(self):
108         self.use_count -= 1
109
110     def inc_ref(self):
111         self.ref_count += 1
112         return self.ref_count
113
114     def dec_ref(self, n):
115         self.ref_count -= n
116         return self.ref_count
117
118     def has_ref(self, only_children):
119         """Determine if there are any kernel references to this
120         object or its children.
121
122         If only_children is True, ignore refcount of self and only consider
123         children.
124         """
125         if only_children:
126             return False
127         else:
128             return self.ref_count > 0
129
130     def objsize(self):
131         return 0
132
133     def uuid(self):
134         return None
135
136     def finalize(self):
137         pass