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 |
||||
|
@ -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: |
||||
def __init__(self, server_service): |
||||
|
||||
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) |
||||
|
||||
async def safe_file(filename, content): |
||||
pass |
||||
|
||||
async def load_file(filename, content): |
||||
pass |
Loading…
Reference in new issue