Amulet-Core
Amulet-Core copied to clipboard
[Feature Request] Improved Threading
Feature Request
The Problem
The current implementation of Amulet was not really designed with threading in mind. I think we need to rewrite the API to be more thread safe in an environment where some users are unaware of threads and locks.
Feature Description
Instead of the get and set methods returning the object stored internally they should return a deep copy of the data. This means that when a thread gets a chunk it is the only thread that is modifying that chunk object. When setting the data back it is deep copied again so that the thread does not hold a reference to the internal data. We should also add an edit context manager so that multiple threads can work around each other while editing the same object.
Code
from threading import RLock
from copy import deepcopy
from contextlib import contextmanager
import numpy
class Chunk:
def __init__(self):
self.data = numpy.zeros((16, 16, 16))
class Level:
def __init__(self):
self._chunk = Chunk()
self._lock = RLock()
def get_chunk(self) -> Chunk:
"""
Get a deep copy of the chunk data.
If you want to edit the chunk use :meth:`edit_chunk` instead.
"""
return deepcopy(self._chunk)
def set_chunk(self, chunk: Chunk):
"""
Overwrite the chunk data.
If you want to edit the chunk use :meth:`edit_chunk` instead.
:param chunk: The chunk data to set.
"""
self._chunk = deepcopy(chunk)
@contextmanager
def edit_chunk(self):
"""
Lock and edit a chunk.
>>> with level.edit_chunk() as chunk:
>>> # Edit the chunk data
>>> # No other threads can edit the chunk while in this with block.
>>> # When the with block exits the edited chunk will be automatically set if no exception occurred.
"""
with self._lock:
chunk = self.get_chunk()
yield chunk
self.set_chunk(chunk)
Additional context
This has effects on Amulet-Team/Amulet-Core#256 and Amulet-Team/Amulet-Core#257 We would also need to think about how the history system would work if two operations were running at the same time but this is a baby step towards that.