You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.7 KiB

from services.server_service import ServerMessage, ServerService
import json
import asyncio
"""
This is how you can save a file:
async def test_file_save():
async with data_service.open('filename') as f:
print('write content')
await f.write('test string')
async with data_service.open('filename') as f:
content = await f.load()
print(content)
print('test file ok')
"""
LOCK_WAIT_SLEEP_TIMESPAN = 100 # mc
class FileDescriptor:
def __init__(self, filename: str, data_service):
self.filename = filename
self.data_service = data_service
async def write(self, content: str):
await self.data_service.save_file_content(self, content)
async def load(self) -> str:
return await self.data_service.load_file_content(self)
async def __aenter__(self):
await self.data_service.wait_and_lock(self)
return self
async def __aexit__(self, *exc):
await self.data_service.unlock(self)
class DataService:
def __init__(self, server_service: ServerService):
"""Creates fs over network via server_service"""
self.server_service = server_service
self.locks = set()
def open(self, filename: str) -> FileDescriptor:
return FileDescriptor(filename, self)
async def wait_and_lock(self, file_descriptor: FileDescriptor):
filename = file_descriptor.filename
while True:
if filename in self.locks:
asyncio.sleep(LOCK_WAIT_SLEEP_TIMESPAN)
continue
else:
self.locks.add(filename)
break
async def unlock(self, file_descriptor: FileDescriptor):
filename = file_descriptor.filename
self.locks.remove(filename)
async def save_file_content(self, file_descriptor: FileDescriptor, content: str):
""" Saves json - serializable obj with file_descriptor.filename """
self.__check_lock(file_descriptor)
message_payload = {
'filename': file_descriptor.filename,
'content': content
}
message = ServerMessage('FILE_SAVE', message_payload)
await self.server_service.send_request(message)
async def load_file_content(self, file_descriptor: FileDescriptor) -> str:
self.__check_lock(file_descriptor)
message_payload = { 'filename': file_descriptor.filename }
message = ServerMessage('FILE_LOAD', message_payload)
return await self.server_service.send_request(message)
def __check_lock(self, file_descriptor: FileDescriptor):
filename = file_descriptor.filename
if filename not in self.locks:
raise RuntimeError('No lock for file %s' % filename)