Skip to content

Instantly share code, notes, and snippets.

@juancarlospaco
Last active April 6, 2018 19:25
Show Gist options
  • Save juancarlospaco/60e9d29b7119db3105cf to your computer and use it in GitHub Desktop.
Save juancarlospaco/60e9d29b7119db3105cf to your computer and use it in GitHub Desktop.
Single Instance App Singleton.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys, os, socket
import logging as log
def set_single_instance(name, single_instance=True, port=8888):
"""Set process name and cpu priority, return socket.socket object or None.
>>> isinstance(set_single_instance("test"), socket.socket)
True
"""
__lock = None
if single_instance:
try: # Single instance app ~crossplatform, uses udp socket.
log.info("Creating Abstract UDP Socket Lock for Single Instance.")
__lock = socket.socket(
socket.AF_UNIX if sys.platform.startswith("linux")
else socket.AF_INET, socket.SOCK_STREAM)
__lock.bind(
"\0_{name}__lock".format(name=str(name).lower().strip())
if sys.platform.startswith("linux") else ("127.0.0.1", port))
except socket.error as e:
log.warning(e)
else:
log.info("Socket Lock for Single Instance: {}.".format(__lock))
else: # if multiple instance want to touch same file bad things can happen
log.warning("Multiple instance on same file can cause Race Condition.")
return __lock
if __name__ in '__main__':
log.basicConfig(level=-1) # basic logger
set_single_instance("your_app_name_here")
__import__("doctest").testmod(verbose=True, report=True, exclude_empty=1)
@juancarlospaco
Copy link
Author

No multiple instances:

juan@z:~$ python prueba.py
Simulating an App running, run multiple instances to try.
juan@z:~$ python prueba.py
App already running, ([Errno 98] Address already in use,Reboot to Fix). Exiting.

juan@z:~$ 
juan@z:~$ python3 temp.py 
Creating Abstract UDP Socket Lock for Single Instance.
Socket Lock for Single Instance: <socket.socket fd=3, family=AddressFamily.AF_UNIX, type=SocketType.SOCK_STREAM, proto=0, laddr=b'\x00_your_app_name_here__lock'>.
Trying:
    isinstance(set_single_instance(), socket.socket)
Expecting:
    True
Creating Abstract UDP Socket Lock for Single Instance.
Socket Lock for Single Instance: <socket.socket fd=3, family=AddressFamily.AF_UNIX, type=SocketType.SOCK_STREAM, proto=0, laddr=b'\x00_your_app_name_here__lock'>.
ok
1 items passed all tests:
   1 tests in __main__.set_single_instance
1 tests in 1 items.
1 passed and 0 failed.
Test passed.

juan@z:~$ python2 temp.py
Creating Abstract UDP Socket Lock for Single Instance.
Socket Lock for Single Instance: <socket._socketobject object at 0x7f64886d3280>.
Trying:
    isinstance(set_single_instance(), socket.socket)
Expecting:
    True
Creating Abstract UDP Socket Lock for Single Instance.
Socket Lock for Single Instance: <socket._socketobject object at 0x7f6488585ec0>.
ok
1 items passed all tests:
   1 tests in __main__.set_single_instance
1 tests in 1 items.
1 passed and 0 failed.
Test passed.

juan@z:~/code$

Note:

  • Edit the string "\0_your_app_name_here_lock", but do NOT remove the \0_ at the beginning 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment