changeset 38bd66006727 in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset&node=38bd66006727
description:
        Reset less often the user sessions

        issue10202
        review341741060
diffstat:

 CHANGELOG             |   1 +
 trytond/ir/session.py |  42 +++++++++++++++++++++++++++++-------------
 2 files changed, 30 insertions(+), 13 deletions(-)

diffs (101 lines):

diff -r 15ef08043b65 -r 38bd66006727 CHANGELOG
--- a/CHANGELOG Sun Oct 02 00:22:56 2022 +0200
+++ b/CHANGELOG Mon Oct 03 00:06:41 2022 +0200
@@ -1,3 +1,4 @@
+* Reset the user sessions less often
 * Add straight values to wizard state view
 * Add strip option to Char fields
 * Strip only one wildcard
diff -r 15ef08043b65 -r 38bd66006727 trytond/ir/session.py
--- a/trytond/ir/session.py     Sun Oct 02 00:22:56 2022 +0200
+++ b/trytond/ir/session.py     Mon Oct 03 00:06:41 2022 +0200
@@ -4,9 +4,14 @@
 import json
 from secrets import token_hex
 
+from trytond.cache import Cache
 from trytond.config import config
 from trytond.model import ModelSQL, fields
 
+_session_timeout = datetime.timedelta(
+    seconds=config.getint('session', 'timeout'))
+_reset_interval = _session_timeout // 10
+
 
 class Session(ModelSQL):
     "Session"
@@ -14,6 +19,7 @@
     _rec_name = 'key'
 
     key = fields.Char('Key', required=True, select=True, strip=False)
+    _session_reset_cache = Cache('ir_session.session_reset', context=False)
 
     @classmethod
     def __setup__(cls):
@@ -32,6 +38,13 @@
         return token_hex(nbytes)
 
     @classmethod
+    def write(cls, *args):
+        super().write(*args)
+        for sessions in args[0:None:2]:
+            for session in sessions:
+                cls._session_reset_cache.set(session.key, session.write_date)
+
+    @classmethod
     def new(cls, values=None):
         "Create a new session for the transaction user and return the key."
         if values is None:
@@ -68,17 +81,20 @@
                 ('create_uid', '=', user),
                 domain or [],
                 ])
-        find = None
+        find, last_reset = None, None
         to_delete = []
         for session in sessions:
             if abs(session.create_date - now) < timeout:
                 if session.key == key:
                     find = True
+                    last_reset = session.write_date or session.create_date
             else:
                 if find is None and session.key == key:
                     find = False
                 to_delete.append(session)
         cls.delete(to_delete)
+        if find:
+            cls._session_reset_cache.set(key, last_reset)
         return find
 
     @classmethod
@@ -105,18 +121,18 @@
     def reset(cls, key, domain=None):
         "Reset key session timestamp"
         now = datetime.datetime.now()
-        timeout = datetime.timedelta(
-            seconds=config.getint('session', 'timeout'))
-        timestamp = now - timeout
-        sessions = cls.search([
-                ('key', '=', key),
-                ['OR',
-                    ('create_date', '>=', timestamp),
-                    ('write_date', '>=', timestamp),
-                    ],
-                domain or [],
-                ])
-        cls.write(sessions, {})
+        last_reset = cls._session_reset_cache.get(key)
+        if last_reset is None or (now - _reset_interval) > last_reset:
+            timestamp = now - _session_timeout
+            sessions = cls.search([
+                    ('key', '=', key),
+                    ['OR',
+                        ('create_date', '>=', timestamp),
+                        ('write_date', '>=', timestamp),
+                        ],
+                    domain or [],
+                    ])
+            cls.write(sessions, {})
 
     @classmethod
     def clear(cls, users, domain=None):

Reply via email to