##// END OF EJS Templates
pidlock: use fstring where aplicable
super-admin -
r5021:a562499c default
parent child Browse files
Show More
@@ -1,148 +1,146 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
3 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import os
22 import errno
22 import errno
23
23
24 from multiprocessing.util import Finalize
24 from multiprocessing.util import Finalize
25
25
26
26
27
28 class LockHeld(Exception):
27 class LockHeld(Exception):
29 pass
28 pass
30
29
31
30
32 class DaemonLock(object):
31 class DaemonLock(object):
33 """daemon locking
32 """daemon locking
34 USAGE:
33 USAGE:
35 try:
34 try:
36 l = DaemonLock(file_='/path/tolockfile',desc='test lock')
35 l = DaemonLock(file_='/path/tolockfile',desc='test lock')
37 main()
36 main()
38 l.release()
37 l.release()
39 except LockHeld:
38 except LockHeld:
40 sys.exit(1)
39 sys.exit(1)
41 """
40 """
42
41
43 def __init__(self, file_=None, callbackfn=None,
42 def __init__(self, file_=None, callbackfn=None,
44 desc='daemon lock', debug=False):
43 desc='daemon lock', debug=False):
45
44
46 lock_name = os.path.join(os.path.dirname(__file__), 'running.lock')
45 lock_name = os.path.join(os.path.dirname(__file__), 'running.lock')
47 self.pidfile = file_ if file_ else lock_name
46 self.pidfile = file_ if file_ else lock_name
48 self.callbackfn = callbackfn
47 self.callbackfn = callbackfn
49 self.desc = desc
48 self.desc = desc
50 self.debug = debug
49 self.debug = debug
51 self.held = False
50 self.held = False
52 #run the lock automatically !
51 # run the lock automatically !
53 self.lock()
52 self.lock()
54 self._finalize = Finalize(self, DaemonLock._on_finalize,
53 self._finalize = Finalize(self, DaemonLock._on_finalize,
55 args=(self, debug), exitpriority=10)
54 args=(self, debug), exitpriority=10)
56
55
57 @staticmethod
56 @staticmethod
58 def _on_finalize(lock, debug):
57 def _on_finalize(lock, debug):
59 if lock.held:
58 if lock.held:
60 if debug:
59 if debug:
61 print('leck held finilazing and running lock.release()')
60 print('lock held finalazing and running lock.release()')
62 lock.release()
61 lock.release()
63
62
64 def lock(self):
63 def lock(self):
65 """
64 """
66 locking function, if lock is present it
65 locking function, if lock is present it
67 will raise LockHeld exception
66 will raise LockHeld exception
68 """
67 """
69 lockname = '%s' % (os.getpid())
68 lockname = f'{os.getpid()}'
70 if self.debug:
69 if self.debug:
71 print('running lock')
70 print('running lock')
72 self.trylock()
71 self.trylock()
73 self.makelock(lockname, self.pidfile)
72 self.makelock(lockname, self.pidfile)
74 return True
73 return True
75
74
76 def trylock(self):
75 def trylock(self):
77 running_pid = False
76 running_pid = False
78 if self.debug:
77 if self.debug:
79 print('checking for already running process')
78 print('checking for already running process')
80 try:
79 try:
81 with open(self.pidfile, 'r') as f:
80 with open(self.pidfile, 'r') as f:
82 try:
81 try:
83 running_pid = int(f.readline())
82 running_pid = int(f.readline())
84 except ValueError:
83 except ValueError:
85 running_pid = -1
84 running_pid = -1
86
85
87 if self.debug:
86 if self.debug:
88 print('lock file present running_pid: %s, '
87 print(f'lock file present running_pid: {running_pid}, '
89 'checking for execution' % (running_pid,))
88 f'checking for execution')
90 # Now we check the PID from lock file matches to the current
89 # Now we check the PID from lock file matches to the current
91 # process PID
90 # process PID
92 if running_pid:
91 if running_pid:
93 try:
92 try:
94 os.kill(running_pid, 0)
93 os.kill(running_pid, 0)
95 except OSError as exc:
94 except OSError as exc:
96 if exc.errno in (errno.ESRCH, errno.EPERM):
95 if exc.errno in (errno.ESRCH, errno.EPERM):
97 print("Lock File is there but"
96 print("Lock File is there but the program is not running")
98 " the program is not running")
97 print(f"Removing lock file for the: {running_pid}")
99 print("Removing lock file for the: %s" % running_pid)
100 self.release()
98 self.release()
101 else:
99 else:
102 raise
100 raise
103 else:
101 else:
104 print("You already have an instance of the program running")
102 print("You already have an instance of the program running")
105 print("It is running as process %s" % running_pid)
103 print(f"It is running as process {running_pid}")
106 raise LockHeld()
104 raise LockHeld()
107
105
108 except IOError as e:
106 except IOError as e:
109 if e.errno != 2:
107 if e.errno != 2:
110 raise
108 raise
111
109
112 def release(self):
110 def release(self):
113 """releases the pid by removing the pidfile
111 """releases the pid by removing the pidfile
114 """
112 """
115 if self.debug:
113 if self.debug:
116 print('trying to release the pidlock')
114 print('trying to release the pidlock')
117
115
118 if self.callbackfn:
116 if self.callbackfn:
119 # execute callback function on release
117 # execute callback function on release
120 if self.debug:
118 if self.debug:
121 print('executing callback function %s' % self.callbackfn)
119 print(f'executing callback function {self.callbackfn}')
122 self.callbackfn()
120 self.callbackfn()
123 try:
121 try:
124 if self.debug:
122 if self.debug:
125 print('removing pidfile %s' % self.pidfile)
123 print(f'removing pidfile {self.pidfile}')
126 os.remove(self.pidfile)
124 os.remove(self.pidfile)
127 self.held = False
125 self.held = False
128 except OSError as e:
126 except OSError as e:
129 if self.debug:
127 if self.debug:
130 print('removing pidfile failed %s' % e)
128 print(f'removing pidfile failed {e}')
131 pass
129 pass
132
130
133 def makelock(self, lockname, pidfile):
131 def makelock(self, lockname, pidfile):
134 """
132 """
135 this function will make an actual lock
133 this function will make an actual lock
136
134
137 :param lockname: acctual pid of file
135 :param lockname: acctual pid of file
138 :param pidfile: the file to write the pid in
136 :param pidfile: the file to write the pid in
139 """
137 """
140 if self.debug:
138 if self.debug:
141 print('creating a file %s and pid: %s' % (pidfile, lockname))
139 print(f'creating a file {lockname} and pid: {pidfile}')
142
140
143 dir_, file_ = os.path.split(pidfile)
141 dir_, file_ = os.path.split(pidfile)
144 if not os.path.isdir(dir_):
142 if not os.path.isdir(dir_):
145 os.makedirs(dir_)
143 os.makedirs(dir_)
146 with open(self.pidfile, 'wb') as f:
144 with open(self.pidfile, 'wb') as f:
147 f.write(lockname)
145 f.write(lockname)
148 self.held = True
146 self.held = True
General Comments 0
You need to be logged in to leave comments. Login now