Browse Source
* async fs context manager * ServerMessage class and using it * handle resps * requests to node & file saving ++ * fx FILE_GET -> FILE_LOAD * ds usage * basic files savingpull/1/head
11 changed files with 312 additions and 58 deletions
@ -1,2 +1,2 @@ |
|||||||
from services.server_service import ServerService |
from services.server_service import ServerService, ServerMessage |
||||||
from services.data_service import DataService |
from services.data_service import DataService |
||||||
|
@ -1,9 +1,87 @@ |
|||||||
|
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: |
class DataService: |
||||||
def __init__(self, server_service): |
|
||||||
|
def __init__(self, server_service: ServerService): |
||||||
|
"""Creates fs over network via server_service""" |
||||||
self.server_service = 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) |
||||||
|
|
||||||
async def safe_file(filename, content): |
|
||||||
pass |
|
||||||
|
|
||||||
async def load_file(filename, content): |
|
||||||
pass |
|
Loading…
Reference in new issue