|
2 | 2 | import json |
3 | 3 | import logging |
4 | 4 | import os |
| 5 | +import time |
5 | 6 | import uuid |
6 | 7 | from collections import deque |
7 | 8 | from concurrent.futures import ThreadPoolExecutor |
@@ -61,27 +62,48 @@ def _read_manifest(self): |
61 | 62 | except FileNotFoundError: |
62 | 63 | return [] |
63 | 64 |
|
64 | | - async def _get_file(self, path, handle_only=False, delete=True): |
| 65 | + def _path_for_ident(self, ident): |
| 66 | + return os.path.join(self._message_path, ident) |
| 67 | + |
| 68 | + async def _get_file(self, ident, handle_only=False, delete=True): |
65 | 69 | """ |
66 | 70 | Retrieves a file from disk. If handle_only is True then we will |
67 | 71 | return the handle to the file and do nothing else. Otherwise the file |
68 | 72 | is read into memory all at once and returned. If delete is True (the |
69 | 73 | default) and handle_only is False (the default) then the underlying |
70 | 74 | file will be removed as well. |
71 | 75 | """ |
72 | | - path = os.path.join(self._message_path, path) |
| 76 | + path = self._path_for_ident(ident) |
73 | 77 | fp = await self._loop.run_in_executor(pool, open, path, "rb") |
74 | 78 | if handle_only: |
75 | 79 | return fp |
76 | 80 | bytes = await self._loop.run_in_executor(pool, lambda: fp.read()) |
77 | 81 | fp.close() |
78 | 82 | if delete: |
79 | | - os.remove(path) |
| 83 | + await self._loop.run_in_executor(pool, os.remove, path) |
80 | 84 | return bytes |
81 | 85 |
|
82 | 86 | def _write_file(self, data, ident): |
83 | 87 | with open(os.path.join(self._message_path, ident), "wb") as fp: |
84 | 88 | fp.write(data) |
| 89 | + |
| 90 | + async def expire(self): |
| 91 | + async with self._manifest_lock: |
| 92 | + new_queue = asyncio.Queue() |
| 93 | + while self.q.qsize() > 0: |
| 94 | + ident = await self.q.get() |
| 95 | + data = await self._get_file(ident, handle_only=True, delete=False) |
| 96 | + msg = json.load(data) |
| 97 | + if "expire_time" in msg and msg['expire_time'] < time.time(): |
| 98 | + logger.info("Expiring message %s", ident) |
| 99 | + # TODO: Do something with expired message |
| 100 | + await self._loop.run_in_executor(pool, os.remove, self._path_for_ident(ident)) |
| 101 | + else: |
| 102 | + await new_queue.put(ident) |
| 103 | + self.q = new_queue |
| 104 | + |
| 105 | + |
| 106 | + |
85 | 107 |
|
86 | 108 |
|
87 | 109 | class FileBufferManager(BaseBufferManager): |
|
0 commit comments