* Core: lazy-load worlds in unpickler this should hopefully fix customserver's memory consumption * WebHost: move imports around to save memory in MP * MultiServer: prefer loading _speedups without pyximport This saves ~15MB per MP and speeds up module import if it was built in-place. * Tests: fix tests for changed WebHost imports * CustomServer: run GC after setup * CustomServer: cleanup exception handling
		
			
				
	
	
		
			52 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			52 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import os
 | 
						|
import sys
 | 
						|
 | 
						|
 | 
						|
class CommonLocker:
 | 
						|
    """Uses a file lock to signal that something is already running"""
 | 
						|
    lock_folder = "file_locks"
 | 
						|
 | 
						|
    def __init__(self, lockname: str, folder=None):
 | 
						|
        if folder:
 | 
						|
            self.lock_folder = folder
 | 
						|
        os.makedirs(self.lock_folder, exist_ok=True)
 | 
						|
        self.lockname = lockname
 | 
						|
        self.lockfile = os.path.join(self.lock_folder, f"{self.lockname}.lck")
 | 
						|
 | 
						|
 | 
						|
class AlreadyRunningException(Exception):
 | 
						|
    pass
 | 
						|
 | 
						|
 | 
						|
if sys.platform == 'win32':
 | 
						|
    class Locker(CommonLocker):
 | 
						|
        def __enter__(self):
 | 
						|
            try:
 | 
						|
                if os.path.exists(self.lockfile):
 | 
						|
                    os.unlink(self.lockfile)
 | 
						|
                self.fp = os.open(
 | 
						|
                    self.lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR)
 | 
						|
            except OSError as e:
 | 
						|
                raise AlreadyRunningException() from e
 | 
						|
 | 
						|
        def __exit__(self, _type, value, tb):
 | 
						|
            fp = getattr(self, "fp", None)
 | 
						|
            if fp:
 | 
						|
                os.close(self.fp)
 | 
						|
                os.unlink(self.lockfile)
 | 
						|
else:  # unix
 | 
						|
    import fcntl
 | 
						|
 | 
						|
 | 
						|
    class Locker(CommonLocker):
 | 
						|
        def __enter__(self):
 | 
						|
            try:
 | 
						|
                self.fp = open(self.lockfile, "wb")
 | 
						|
                fcntl.flock(self.fp.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
 | 
						|
            except OSError as e:
 | 
						|
                raise AlreadyRunningException() from e
 | 
						|
 | 
						|
        def __exit__(self, _type, value, tb):
 | 
						|
            fcntl.flock(self.fp.fileno(), fcntl.LOCK_UN)
 | 
						|
            self.fp.close()
 |