tessl install tessl/pypi-pyfuse3@3.4.0Python 3 bindings for libfuse 3 with async I/O support
Guide to thread safety, async operations, and cross-thread communication in pyfuse3.
trio.Lock or asyncio.Lock, not threading.Locktrio.from_thread for calls from other threadstrio.from_thread to call pyfuse3 functionsimport trio
class ThreadSafeFS(pyfuse3.Operations):
def __init__(self):
super().__init__()
self.inode_locks = {} # Per-inode locks
self.global_lock = trio.Lock()
async def write(self, fh, offset, buf):
"""Write with per-inode locking."""
inode = self.open_files[fh]
# Get or create lock for this inode
if inode not in self.inode_locks:
async with self.global_lock:
if inode not in self.inode_locks:
self.inode_locks[inode] = trio.Lock()
# Perform write under lock
async with self.inode_locks[inode]:
data = self.inodes[inode]['data']
# ... write logic ...
self.inodes[inode]['data'] = new_data
return len(buf)import trio
import trio.from_thread
import pyfuse3
import signal
async def run_filesystem():
fs = MyFS()
def signal_handler(signum, frame):
"""Signal handler - runs in different thread."""
logger.info(f"Received signal {signum}")
# CORRECT: Use trio.from_thread
trio.from_thread.run_sync(
pyfuse3.terminate,
trio_token=pyfuse3.trio_token
)
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
pyfuse3.init(fs, '/mnt/myfs')
await pyfuse3.main()import asyncio
import pyfuse3
import signal
async def run_filesystem():
fs = MyFS()
def signal_handler(signum, frame):
"""Signal handler - runs in different thread."""
logger.info(f"Received signal {signum}")
# CORRECT: Use call_soon_threadsafe
loop = asyncio.get_event_loop()
loop.call_soon_threadsafe(pyfuse3.terminate)
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
pyfuse3.init(fs, '/mnt/myfs')
await pyfuse3.main()def signal_handler(signum, frame):
# WRONG - Direct call from signal handler
pyfuse3.terminate() # May deadlock or crash!import threading
# WRONG
class BadFS(pyfuse3.Operations):
def __init__(self):
self.lock = threading.Lock() # Don't use threading locks!
async def write(self, fh, offset, buf):
with self.lock: # This will block the async task!
# ...
# CORRECT
import trio
class GoodFS(pyfuse3.Operations):
def __init__(self):
self.lock = trio.Lock() # Use async lock
async def write(self, fh, offset, buf):
async with self.lock: # Async context manager
# ...# WRONG
async def read(self, fh, offset, size):
import time
time.sleep(1) # Blocks entire worker task!
return self.data[offset:offset + size]
# CORRECT
async def read(self, fh, offset, size):
await trio.sleep(1) # Yields to other tasks
return self.data[offset:offset + size]