66from collections import deque
77from concurrent .futures import ThreadPoolExecutor
88
9- from ..exceptions import ReceptorBufferError
10- from .base import BaseBuffer , BaseBufferManager
9+ from .base import BaseBufferManager
1110
1211logger = logging .getLogger (__name__ )
1312pool = ThreadPoolExecutor ()
@@ -33,24 +32,23 @@ def __init__(self, dir_, key, loop):
3332 self .q ._queue = deque (self ._read_manifest ())
3433
3534 async def put (self , data ):
36- async with self ._manifest_lock :
37- ident = str (uuid .uuid4 ())
38- await self ._loop .run_in_executor (pool , self ._write_file , data , ident )
39- await self .q .put (ident )
40- await self ._save_manifest ()
35+ ident = str (uuid .uuid4 ())
36+ await self ._loop .run_in_executor (pool , self ._write_file , data , ident )
37+ await self .q .put (ident )
38+ await self ._save_manifest ()
4139
4240 async def get (self , handle_only = False , delete = True ):
43- async with self ._manifest_lock :
44- while True :
45- msg = await self .q .get ()
46- await self ._save_manifest ()
47- try :
48- return await self ._get_file (msg , handle_only = handle_only , delete = delete )
49- except FileNotFoundError :
50- pass
41+ while True :
42+ msg = await self .q .get ()
43+ await self ._save_manifest ()
44+ try :
45+ return await self ._get_file (msg , handle_only = handle_only , delete = delete )
46+ except FileNotFoundError :
47+ pass
5148
5249 async def _save_manifest (self ):
53- await self ._loop .run_in_executor (pool , self ._write_manifest )
50+ async with self ._manifest_lock :
51+ await self ._loop .run_in_executor (pool , self ._write_manifest )
5452
5553 def _write_manifest (self ):
5654 with open (self ._manifest_path , "w" ) as fp :
@@ -90,91 +88,5 @@ class FileBufferManager(BaseBufferManager):
9088 _buffers = {}
9189
9290 def get_buffer_for_node (self , node_id , receptor ):
93- return self ._buffers .setdefault (node_id , FileBuffer (node_id , receptor ))
94-
95-
96- class FileBuffer (BaseBuffer ):
97-
98- def __init__ (self , node_id , receptor ):
99- super ().__init__ (node_id , receptor )
100- self .node_id = node_id
101- self .loop = asyncio .get_event_loop ()
102- self .base_path = os .path .join (os .path .expanduser (self .receptor .config .default_data_dir ))
103- self .message_path = os .path .join (self .base_path , self .receptor .node_id , "messages" )
104- self .manifest_path = os .path .join (self .base_path , self .receptor .node_id , "manifest-{}" .format (node_id ))
105- if not os .path .exists (self .message_path ):
106- os .makedirs (self .message_path , mode = 0o700 )
107-
108- def __iter__ (self ):
109- self .current = 0
110- return self
111-
112- def __next__ (self ):
113- manifest = self .read_manifest ()
114- if len (manifest ) <= self .current :
115- raise StopIteration
116- ident = manifest [self .current ]
117- current_payload = self .read (ident )
118- self .current += 1
119- return ident , current_payload
120-
121- def new_message (self ):
122- ident = str (uuid .uuid4 ())
123- try :
124- handle = open (os .path .join (self .message_path , ident ), "wb" )
125- except Exception as e :
126- raise ReceptorBufferError ("Failed to generate new message file for {}: {}" .format (self .node_id , e ))
127- return (ident , handle )
128-
129- def read_message (self , ident , remove = True ):
130- try :
131- message_data = open (os .path .join (self .message_path , ident ), "rb" ).read ()
132- if remove :
133- os .remove (os .path .join (self .message_path , ident ))
134- except Exception as e :
135- raise ReceptorBufferError ("Failed to handle message data file for {} {}: {}" .format (self .node_id , ident , e ))
136- return message_data
137-
138- def write_manifest (self , manifest ):
139- try :
140- fd = open (self .manifest_path , "w" )
141- json .dump (manifest , fd )
142- fd .close ()
143- except Exception as e :
144- raise ReceptorBufferError ("Failed to handle metadata file for {}: {}" .format (self .node_id , e ))
145-
146- def read_manifest (self ):
147- if not os .path .exists (self .manifest_path ):
148- return []
149- try :
150- fd = open (self .manifest_path , "r" )
151- manifest = json .load (fd )
152- return manifest
153- except Exception as e :
154- logger .warn ("Failed to read manifest: {}" .format (e ))
155- return []
156-
157- def push (self , message ):
158- manifest = self .read_manifest ()
159- ident , handle = self .new_message ()
160- try :
161- handle .write (message )
162- handle .close ()
163- except Exception as e :
164- raise ReceptorBufferError ("Failed to write message file for {} {}: {}" .format (self .node_id , ident , e ))
165- manifest .append (ident )
166- self .write_manifest (manifest )
167-
168- def read (self , ident , remove = False ):
169- manifest = self .read_manifest ()
170- message = self .read_message (ident , remove = remove )
171- if remove :
172- manifest .remove (ident )
173- self .write_manifest (manifest )
174- return message
175-
176- def pop (self ):
177- manifest = self .read_manifest ()
178- item = self .read_message (manifest .pop (0 ))
179- self .write_manifest (manifest )
180- return item
91+ path = os .path .join (os .path .expanduser (receptor .config .default_data_dir ))
92+ return self ._buffers .setdefault (node_id , DurableBuffer (path , node_id , asyncio .get_event_loop ()))
0 commit comments