cachu 0.2.2__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cachu-0.2.2 → cachu-0.2.3}/PKG-INFO +1 -1
- {cachu-0.2.2 → cachu-0.2.3}/pyproject.toml +1 -1
- {cachu-0.2.2 → cachu-0.2.3}/setup.cfg +1 -1
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/__init__.py +1 -1
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/backends/async_sqlite.py +22 -6
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu.egg-info/PKG-INFO +1 -1
- {cachu-0.2.2 → cachu-0.2.3}/README.md +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/async_decorator.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/async_operations.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/backends/__init__.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/backends/async_base.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/backends/async_memory.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/backends/async_redis.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/backends/file.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/backends/memory.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/backends/redis.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/backends/sqlite.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/config.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/decorator.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/keys.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/operations.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu/types.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu.egg-info/SOURCES.txt +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu.egg-info/dependency_links.txt +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu.egg-info/requires.txt +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/src/cachu.egg-info/top_level.txt +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_async_memory.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_async_redis.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_async_sqlite.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_clearing.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_config.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_defaultcache.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_delete_keys.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_disable.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_exclude_params.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_file_cache.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_integration.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_memory_cache.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_namespace.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_namespace_isolation.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_redis_cache.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_set_keys.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_sqlite_backend.py +0 -0
- {cachu-0.2.2 → cachu-0.2.3}/tests/test_ttl_isolation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Flexible caching library with support for memory, file, and Redis backends.
|
|
2
2
|
"""
|
|
3
|
-
__version__ = '0.2.
|
|
3
|
+
__version__ = '0.2.3'
|
|
4
4
|
|
|
5
5
|
from .async_decorator import async_cache, clear_async_backends
|
|
6
6
|
from .async_decorator import get_async_backend, get_async_cache_info
|
|
@@ -48,23 +48,37 @@ class AsyncSqliteBackend(AsyncBackend):
|
|
|
48
48
|
await self._connection.execute('PRAGMA busy_timeout=5000')
|
|
49
49
|
|
|
50
50
|
if not self._initialized:
|
|
51
|
-
await self._connection.execute(
|
|
51
|
+
await self._connection.execute("""
|
|
52
52
|
CREATE TABLE IF NOT EXISTS cache (
|
|
53
53
|
key TEXT PRIMARY KEY,
|
|
54
54
|
value BLOB NOT NULL,
|
|
55
55
|
created_at REAL NOT NULL,
|
|
56
56
|
expires_at REAL NOT NULL
|
|
57
57
|
)
|
|
58
|
-
|
|
59
|
-
await self._connection.execute(
|
|
58
|
+
""")
|
|
59
|
+
await self._connection.execute("""
|
|
60
60
|
CREATE INDEX IF NOT EXISTS idx_cache_expires
|
|
61
61
|
ON cache(expires_at)
|
|
62
|
-
|
|
62
|
+
""")
|
|
63
63
|
await self._connection.commit()
|
|
64
64
|
self._initialized = True
|
|
65
65
|
|
|
66
66
|
return self._connection
|
|
67
67
|
|
|
68
|
+
def _schedule_delete(self, key: str) -> None:
|
|
69
|
+
"""Schedule a background deletion task (fire-and-forget).
|
|
70
|
+
"""
|
|
71
|
+
async def _delete() -> None:
|
|
72
|
+
try:
|
|
73
|
+
async with self._write_lock:
|
|
74
|
+
conn = await self._ensure_initialized()
|
|
75
|
+
await conn.execute('DELETE FROM cache WHERE key = ?', (key,))
|
|
76
|
+
await conn.commit()
|
|
77
|
+
except Exception:
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
asyncio.create_task(_delete())
|
|
81
|
+
|
|
68
82
|
async def get(self, key: str) -> Any:
|
|
69
83
|
"""Get value by key. Returns NO_VALUE if not found or expired.
|
|
70
84
|
"""
|
|
@@ -81,6 +95,7 @@ class AsyncSqliteBackend(AsyncBackend):
|
|
|
81
95
|
|
|
82
96
|
value_blob, expires_at = row
|
|
83
97
|
if time.time() > expires_at:
|
|
98
|
+
self._schedule_delete(key)
|
|
84
99
|
return NO_VALUE
|
|
85
100
|
|
|
86
101
|
return pickle.loads(value_blob)
|
|
@@ -103,6 +118,7 @@ class AsyncSqliteBackend(AsyncBackend):
|
|
|
103
118
|
|
|
104
119
|
value_blob, created_at, expires_at = row
|
|
105
120
|
if time.time() > expires_at:
|
|
121
|
+
self._schedule_delete(key)
|
|
106
122
|
return NO_VALUE, None
|
|
107
123
|
|
|
108
124
|
return pickle.loads(value_blob), created_at
|
|
@@ -118,8 +134,8 @@ class AsyncSqliteBackend(AsyncBackend):
|
|
|
118
134
|
async with self._write_lock:
|
|
119
135
|
conn = await self._ensure_initialized()
|
|
120
136
|
await conn.execute(
|
|
121
|
-
|
|
122
|
-
VALUES (?, ?, ?, ?)
|
|
137
|
+
"""INSERT OR REPLACE INTO cache (key, value, created_at, expires_at)
|
|
138
|
+
VALUES (?, ?, ?, ?)""",
|
|
123
139
|
(key, value_blob, now, now + ttl),
|
|
124
140
|
)
|
|
125
141
|
await conn.commit()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|