comparison libervia/web/pages/_browser/cache.py @ 1622:c2065de5f6d0

browser (cache): better handling of roster and identities: roster and identities are now handled and updated separately.
author Goffi <goffi@goffi.org>
date Thu, 15 May 2025 17:52:59 +0200
parents a2cd4222c702
children
comparison
equal deleted inserted replaced
1621:d7c8a986f4fb 1622:c2065de5f6d0
7 7
8 log.warning = log.warn 8 log.warning = log.warn
9 session_uuid = window.session_uuid 9 session_uuid = window.session_uuid
10 bridge = Bridge() 10 bridge = Bridge()
11 async_bridge = AsyncBridge() 11 async_bridge = AsyncBridge()
12 profile = window.profile or ""
13 STORAGE_KEY = f"libervia_cache_{profile}"
12 14
13 # XXX: we don't use browser.object_storage because it is affected by 15 # XXX: we don't use browser.object_storage because it is affected by
14 # https://github.com/brython-dev/brython/issues/1467 and mixing local_storage.storage 16 # https://github.com/brython-dev/brython/issues/1467 and mixing local_storage.storage
15 # and object_storage was resulting in weird behaviour (keys found in one not in the 17 # and object_storage was resulting in weird behaviour (keys found in one not in the
16 # other) 18 # other)
17 19
18 20
19 class Cache: 21 class Cache:
20 22
21 def __init__(self): 23 def __init__(self):
24 self._cache = {
25 'metadata': {
26 "session_uuid": session_uuid,
27 },
28 'roster': {},
29 'identities': {},
30 }
22 try: 31 try:
23 cache = storage['libervia_cache'] 32 cache = storage[STORAGE_KEY]
24 except KeyError: 33 except KeyError:
25 self.request_data_from_backend() 34 self.request_data_from_backend()
26 else: 35 else:
27 cache = json.loads(cache) 36 cache = json.loads(cache)
28 if cache['metadata']['session_uuid'] != session_uuid: 37 if cache['metadata']['session_uuid'] != session_uuid:
29 log.debug("data in cache are not valid for this session, resetting") 38 log.debug("Data in cache are not valid for this session, resetting.")
30 del storage['libervia_cache'] 39 del storage[STORAGE_KEY]
40 self.request_data_from_backend()
41 elif not cache.get("roster") or not cache.get("identities"):
42 log.debug("Incomplete data in cache, requesting backend.")
31 self.request_data_from_backend() 43 self.request_data_from_backend()
32 else: 44 else:
33 self._cache = cache 45 self._cache = cache
34 log.debug("storage cache is used") 46 log.debug("Storage cache is used.")
35 47
36 @property 48 @property
37 def roster(self): 49 def roster(self):
38 return self._cache['roster'] 50 return self._cache['roster']
39 51
42 return self._cache['identities'] 54 return self._cache['identities']
43 55
44 def update(self): 56 def update(self):
45 log.debug(f"updating: {self._cache}") 57 log.debug(f"updating: {self._cache}")
46 # FIXME: workaround in Brython 3.13.0 58 # FIXME: workaround in Brython 3.13.0
47 # storage['libervia_cache'] = json.dumps(self._cache) 59 # storage[STORAGE_KEY] = json.dumps(self._cache)
48 storage['libervia_cache'] = javascript.JSON.stringify(self._cache) 60 storage[STORAGE_KEY] = javascript.JSON.stringify(self._cache)
49 log.debug("cache stored") 61 log.debug("cache stored")
50
51 def _store_if_complete(self):
52 self._completed_count -= 1
53 if self._completed_count == 0:
54 del self._completed_count
55 self.update()
56 62
57 def get_contacts_cb(self, contacts): 63 def get_contacts_cb(self, contacts):
58 log.debug("roster received") 64 log.debug("roster received")
59 roster = self._cache['roster'] 65 roster = self._cache['roster'] = {}
60 for contact_jid, attributes, groups in contacts: 66 for contact_jid, attributes, groups in contacts:
61 roster[contact_jid] = { 67 roster[contact_jid] = {
62 'attributes': attributes, 68 'attributes': attributes,
63 'groups': groups, 69 'groups': groups,
64 } 70 }
65 self._store_if_complete() 71 self.update()
66 72
67 def identities_base_get_cb(self, identities_raw): 73 def identities_base_get_cb(self, identities_raw):
68 log.debug("base identities received") 74 log.debug("base identities received")
69 identities = json.loads(identities_raw) 75 identities = json.loads(identities_raw)
70 self._cache['identities'].update(identities) 76 self._cache['identities'] = identities
71 self._store_if_complete() 77 self.update()
72 78
73 def request_failed(self, exc, message): 79 def request_failed(self, exc, message):
74 notification.show(message.format(exc=exc), "error") 80 notification.show(message.format(exc=exc), "error")
75 self._store_if_complete()
76 81
77 def request_data_from_backend(self): 82 def request_data_from_backend(self):
78 self._cache = {
79 'metadata': {
80 "session_uuid": session_uuid,
81 },
82 'roster': {},
83 'identities': {},
84 }
85 self._completed_count = 2
86 log.debug("requesting roster to backend") 83 log.debug("requesting roster to backend")
87 bridge.contacts_get( 84 bridge.contacts_get(
88 callback=self.get_contacts_cb, 85 callback=self.get_contacts_cb,
89 errback=lambda e: self.request_failed(e, "Can't get contacts: {exc}") 86 errback=lambda e: self.request_failed(e, "Can't get contacts: {exc}")
90 ) 87 )