Skip to content

Commit d32a0cd

Browse files
Merge pull request #360 from phenobarbital/dev
bump version of background service
2 parents e8634d5 + 50971af commit d32a0cd

4 files changed

Lines changed: 33 additions & 8 deletions

File tree

navigator/background/tracker/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class JobRecord(BaseModel):
1919
"""
2020
task_id: str = Field(default=gen_uuid)
2121
name: str = None
22+
content: Optional[str] = None
2223
status: str = 'pending'
2324
attributes: Dict[str, Any] = Field(default_factory=dict)
2425
result: Optional[Any] = None

navigator/background/tracker/redis.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99

1010
Encoder = Callable[[Any], bytes]
11+
MAX_TTL = 30 * 24 * 3600
1112

1213

1314
class RedisJobTracker:
@@ -17,7 +18,12 @@ class RedisJobTracker:
1718
key <prefix>{task_id}
1819
and keeps a Set <prefix>__all with the ids for quick listing.
1920
"""
20-
def __init__(self, url: str = None, prefix: str = 'job:') -> None:
21+
def __init__(
22+
self,
23+
url: str = None,
24+
prefix: str = 'job:',
25+
ttl_seconds: int = 30 * 24 * 3600, # 30 days
26+
) -> None:
2127
self._url = url or CACHE_URL
2228
self._redis: redis.Redis = redis.from_url(
2329
self._url,
@@ -28,6 +34,7 @@ def __init__(self, url: str = None, prefix: str = 'job:') -> None:
2834
self._decoder: Encoder = self._decode_model
2935
self.prefix = prefix if prefix.endswith(":") else f"{prefix}:"
3036
self._lock = asyncio.Lock()
37+
self._ttl = min(ttl_seconds, MAX_TTL)
3138

3239
def _key(self, task_id: str) -> str:
3340
return f"{self.prefix}{task_id}"
@@ -49,7 +56,9 @@ async def create_job(self, job: JobRecord, **kwargs) -> JobRecord:
4956
) from exc
5057
key = self._key(job.task_id)
5158
async with self._lock:
52-
await self._redis.set(key, self._encoder(job))
59+
await self._redis.set(
60+
key, self._encoder(job), ex=self._ttl
61+
)
5362
await self._redis.sadd(self._set_key, job.task_id)
5463

5564
# Create secondary index for attributes if provided
@@ -75,7 +84,9 @@ async def _update(self, job_id: str, **patch) -> None:
7584
rec: JobRecord = self._decoder(payload)
7685
for k, v in patch.items():
7786
setattr(rec, k, v)
78-
await self._redis.set(key, self._encoder(rec))
87+
await self._redis.set(
88+
key, self._encoder(rec), keepttl=True
89+
) # keep the TTL
7990

8091
# Update secondary index for attributes if they are part of the patch
8192
if 'attributes' in patch:
@@ -178,7 +189,11 @@ async def forget(self, job_id: str) -> None:
178189
if payload:
179190
rec: JobRecord = self._decoder(payload)
180191
for k, v in rec.attributes.items():
181-
await self._redis.srem(self._attr_key(k, v), job_id)
192+
akey = self._attr_key(k, v)
193+
await self._redis.srem(akey, job_id)
194+
# set attr-set to expire in 24 h if now empty
195+
if await self._redis.scard(akey) == 0:
196+
await self._redis.expire(akey, 86400)
182197

183198
await self._redis.delete(self._key(job_id))
184199
await self._redis.srem(self._set_key, job_id)

navigator/background/wrappers/__init__.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ def __init__(
6363
retry_delay: float = 0.0,
6464
**kwargs
6565
):
66-
self.args = args
67-
self.kwargs = kwargs
6866
self.fn = fn
6967
self.tracker = tracker
7068
self._name: str = kwargs.pop('name', fn.__name__ if fn else 'unknown_task')
@@ -77,16 +75,27 @@ def __init__(
7775
)
7876
self.jitter: float = jitter
7977
# Create the Job Record at status "pending"
78+
# generate a list of arguments accepted by JobRecord:
79+
job_args = {}
80+
content = kwargs.pop('content', None)
81+
for k, v in kwargs.items():
82+
if not k.startswith('_'):
83+
if k in JobRecord.__fields__:
84+
job_args[k] = v
8085
self.job_record: JobRecord = JobRecord(
8186
name=self._name,
87+
content=content,
8288
status=job_status,
83-
**kwargs
89+
**job_args
8490
)
8591
self.logger = logger or logging.getLogger('NAV.Queue.TaskWrapper')
8692
# Retry information:
8793
self.max_retries = max_retries
8894
self.retries_done = 0
8995
self.retry_delay = retry_delay
96+
# Store the arguments and keyword arguments for the Function
97+
self.args = args
98+
self.kwargs = kwargs
9099

91100
@property
92101
def task_uuid(self) -> uuid.UUID:

navigator/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
__description__ = (
55
"Navigator Web Framework based on aiohttp, " "with batteries included."
66
)
7-
__version__ = "2.13.0"
7+
__version__ = "2.13.1"
88
__copyright__ = "Copyright (c) 2020-2024 Jesus Lara"
99
__author__ = "Jesus Lara"
1010
__author_email__ = "jesuslarag@gmail.com"

0 commit comments

Comments
 (0)