Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import os 

2import socket 

3import inspect 

4import time 

5 

6SOCKDIR = "/run/fairlock" 

7START_SERVICE_TIMEOUT_SECS = 2 

8 

9class SingletonWithArgs(type): 

10 _instances = {} 

11 _init = {} 

12 

13 def __init__(cls, name, bases, dct): 

14 cls._init[cls] = dct.get('__init__', None) 

15 

16 def __call__(cls, *args, **kwargs): 

17 init = cls._init[cls] 

18 if init is not None: 18 ↛ 22line 18 didn't jump to line 22, because the condition on line 18 was never false

19 key = (cls, frozenset( 

20 inspect.getcallargs(init, None, *args, **kwargs).items())) 

21 else: 

22 key = cls 

23 

24 if key not in cls._instances: 

25 cls._instances[key] = super(SingletonWithArgs, cls).__call__(*args, **kwargs) 

26 return cls._instances[key] 

27 

28class FairlockDeadlock(Exception): 

29 pass 

30 

31class FairlockServiceTimeout(Exception): 

32 pass 

33 

34class Fairlock(metaclass=SingletonWithArgs): 

35 def __init__(self, name): 

36 self.name = name 

37 self.sockname = os.path.join(SOCKDIR, name) 

38 self.connected = False 

39 

40 def _ensure_service(self): 

41 service=f"fairlock@{self.name}.service" 

42 os.system(f"/usr/bin/systemctl start {service}") 

43 timeout = time.time() + START_SERVICE_TIMEOUT_SECS 

44 time.sleep(0.1) 

45 while os.system(f"/usr/bin/systemctl --quiet is-active {service}") != 0: 

46 time.sleep(0.1) 

47 if time.time() > timeout: 

48 raise FairlockServiceTimeout(f"Timed out starting service {service}") 

49 

50 def __enter__(self): 

51 if self.connected: 

52 raise FairlockDeadlock(f"Deadlock on Fairlock resource '{self.name}'") 

53 

54 self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 

55 try: 

56 self.sock.connect(self.sockname) 

57 except (FileNotFoundError, ConnectionRefusedError): 

58 self._ensure_service() 

59 self.sock.connect(self.sockname) 

60 

61 self.sock.send(f'{os.getpid()} - {time.monotonic()}'.encode()) 

62 self.connected = True 

63 return self 

64 

65 def __exit__(self, type, value, traceback): 

66 self.sock.close() 

67 self.connected = False 

68 return False 

69