7 Module implementing the VCS status monitor thread base class. |
7 Module implementing the VCS status monitor thread base class. |
8 """ |
8 """ |
9 |
9 |
10 import contextlib |
10 import contextlib |
11 |
11 |
12 from PyQt6.QtCore import ( |
12 from PyQt6.QtCore import QThread, QMutex, QWaitCondition, pyqtSignal, QCoreApplication |
13 QThread, QMutex, QWaitCondition, pyqtSignal, QCoreApplication |
|
14 ) |
|
15 |
13 |
16 |
14 |
17 class VcsStatusMonitorThread(QThread): |
15 class VcsStatusMonitorThread(QThread): |
18 """ |
16 """ |
19 Class implementing the VCS status monitor thread base class. |
17 Class implementing the VCS status monitor thread base class. |
20 |
18 |
21 @signal vcsStatusMonitorData(list of str) emitted to update the VCS status |
19 @signal vcsStatusMonitorData(list of str) emitted to update the VCS status |
22 @signal vcsStatusMonitorAllData(dict) emitted to signal all VCS status |
20 @signal vcsStatusMonitorAllData(dict) emitted to signal all VCS status |
23 (key is project relative file name, value is status) |
21 (key is project relative file name, value is status) |
24 @signal vcsStatusMonitorStatus(str, str) emitted to signal the status of |
22 @signal vcsStatusMonitorStatus(str, str) emitted to signal the status of |
25 the monitoring thread (ok, nok, op) and a status message |
23 the monitoring thread (ok, nok, op) and a status message |
26 @signal vcsStatusMonitorInfo(str) emitted to signal some info of the |
24 @signal vcsStatusMonitorInfo(str) emitted to signal some info of the |
27 monitoring thread |
25 monitoring thread |
28 """ |
26 """ |
|
27 |
29 vcsStatusMonitorData = pyqtSignal(list) |
28 vcsStatusMonitorData = pyqtSignal(list) |
30 vcsStatusMonitorAllData = pyqtSignal(dict) |
29 vcsStatusMonitorAllData = pyqtSignal(dict) |
31 vcsStatusMonitorStatus = pyqtSignal(str, str) |
30 vcsStatusMonitorStatus = pyqtSignal(str, str) |
32 vcsStatusMonitorInfo = pyqtSignal(str) |
31 vcsStatusMonitorInfo = pyqtSignal(str) |
33 |
32 |
34 def __init__(self, interval, project, vcs, parent=None): |
33 def __init__(self, interval, project, vcs, parent=None): |
35 """ |
34 """ |
36 Constructor |
35 Constructor |
37 |
36 |
38 @param interval new interval in seconds (integer) |
37 @param interval new interval in seconds (integer) |
39 @param project reference to the project object (Project) |
38 @param project reference to the project object (Project) |
40 @param vcs reference to the version control object |
39 @param vcs reference to the version control object |
41 @param parent reference to the parent object (QObject) |
40 @param parent reference to the parent object (QObject) |
42 """ |
41 """ |
43 super().__init__(parent) |
42 super().__init__(parent) |
44 self.setObjectName("VcsStatusMonitorThread") |
43 self.setObjectName("VcsStatusMonitorThread") |
45 |
44 |
46 self.setTerminationEnabled(True) |
45 self.setTerminationEnabled(True) |
47 |
46 |
48 self.projectDir = project.getProjectPath() |
47 self.projectDir = project.getProjectPath() |
49 self.project = project |
48 self.project = project |
50 self.vcs = vcs |
49 self.vcs = vcs |
51 |
50 |
52 self.interval = interval |
51 self.interval = interval |
53 self.autoUpdate = False |
52 self.autoUpdate = False |
54 |
53 |
55 self.statusList = [] |
54 self.statusList = [] |
56 self.reportedStates = {} |
55 self.reportedStates = {} |
57 self.shouldUpdate = False |
56 self.shouldUpdate = False |
58 |
57 |
59 self.monitorMutex = QMutex() |
58 self.monitorMutex = QMutex() |
60 self.monitorCondition = QWaitCondition() |
59 self.monitorCondition = QWaitCondition() |
61 self.__stopIt = False |
60 self.__stopIt = False |
62 |
61 |
63 def run(self): |
62 def run(self): |
64 """ |
63 """ |
65 Public method implementing the tasks action. |
64 Public method implementing the tasks action. |
66 """ |
65 """ |
67 while not self.__stopIt: |
66 while not self.__stopIt: |
68 # perform the checking task |
67 # perform the checking task |
69 self.statusList = [] |
68 self.statusList = [] |
70 self.vcsStatusMonitorStatus.emit( |
69 self.vcsStatusMonitorStatus.emit( |
71 "wait", QCoreApplication.translate( |
70 "wait", |
72 "VcsStatusMonitorThread", "Waiting for lock")) |
71 QCoreApplication.translate( |
|
72 "VcsStatusMonitorThread", "Waiting for lock" |
|
73 ), |
|
74 ) |
73 try: |
75 try: |
74 locked = self.vcs.vcsExecutionMutex.tryLock(5000) |
76 locked = self.vcs.vcsExecutionMutex.tryLock(5000) |
75 except TypeError: |
77 except TypeError: |
76 locked = self.vcs.vcsExecutionMutex.tryLock() |
78 locked = self.vcs.vcsExecutionMutex.tryLock() |
77 if locked: |
79 if locked: |
78 try: |
80 try: |
79 self.vcsStatusMonitorStatus.emit( |
81 self.vcsStatusMonitorStatus.emit( |
80 "op", QCoreApplication.translate( |
82 "op", |
81 "VcsStatusMonitorThread", |
83 QCoreApplication.translate( |
82 "Checking repository status")) |
84 "VcsStatusMonitorThread", "Checking repository status" |
|
85 ), |
|
86 ) |
83 res, statusMsg = self._performMonitor() |
87 res, statusMsg = self._performMonitor() |
84 infoMsg = self._getInfo() |
88 infoMsg = self._getInfo() |
85 finally: |
89 finally: |
86 self.vcs.vcsExecutionMutex.unlock() |
90 self.vcs.vcsExecutionMutex.unlock() |
87 if res: |
91 if res: |
88 status = "ok" |
92 status = "ok" |
89 else: |
93 else: |
90 status = "nok" |
94 status = "nok" |
91 self.vcsStatusMonitorStatus.emit( |
95 self.vcsStatusMonitorStatus.emit( |
92 "send", QCoreApplication.translate( |
96 "send", |
93 "VcsStatusMonitorThread", "Sending data")) |
97 QCoreApplication.translate( |
|
98 "VcsStatusMonitorThread", "Sending data" |
|
99 ), |
|
100 ) |
94 self.vcsStatusMonitorData.emit(self.statusList) |
101 self.vcsStatusMonitorData.emit(self.statusList) |
95 self.vcsStatusMonitorAllData.emit(self.reportedStates) |
102 self.vcsStatusMonitorAllData.emit(self.reportedStates) |
96 self.vcsStatusMonitorStatus.emit(status, statusMsg) |
103 self.vcsStatusMonitorStatus.emit(status, statusMsg) |
97 self.vcsStatusMonitorInfo.emit(infoMsg) |
104 self.vcsStatusMonitorInfo.emit(infoMsg) |
98 else: |
105 else: |
99 self.vcsStatusMonitorStatus.emit( |
106 self.vcsStatusMonitorStatus.emit( |
100 "timeout", QCoreApplication.translate( |
107 "timeout", |
101 "VcsStatusMonitorThread", |
108 QCoreApplication.translate( |
102 "Timed out waiting for lock")) |
109 "VcsStatusMonitorThread", "Timed out waiting for lock" |
|
110 ), |
|
111 ) |
103 self.vcsStatusMonitorInfo.emit("") |
112 self.vcsStatusMonitorInfo.emit("") |
104 |
113 |
105 if self.autoUpdate and self.shouldUpdate: |
114 if self.autoUpdate and self.shouldUpdate: |
106 self.vcs.vcsUpdate(self.projectDir, True) |
115 self.vcs.vcsUpdate(self.projectDir, True) |
107 continue # check again |
116 continue # check again |
108 self.shouldUpdate = False |
117 self.shouldUpdate = False |
109 |
118 |
110 # wait until interval has expired checking for a stop condition |
119 # wait until interval has expired checking for a stop condition |
111 self.monitorMutex.lock() |
120 self.monitorMutex.lock() |
112 if not self.__stopIt: |
121 if not self.__stopIt: |
113 self.monitorCondition.wait( |
122 self.monitorCondition.wait(self.monitorMutex, self.interval * 1000) |
114 self.monitorMutex, self.interval * 1000) |
123 self.monitorMutex.unlock() |
115 self.monitorMutex.unlock() |
124 |
116 |
|
117 self._shutdown() |
125 self._shutdown() |
118 self.exit() |
126 self.exit() |
119 |
127 |
120 def setInterval(self, interval): |
128 def setInterval(self, interval): |
121 """ |
129 """ |
122 Public method to change the monitor interval. |
130 Public method to change the monitor interval. |
123 |
131 |
124 @param interval new interval in seconds (integer) |
132 @param interval new interval in seconds (integer) |
125 """ |
133 """ |
126 locked = self.monitorMutex.tryLock() |
134 locked = self.monitorMutex.tryLock() |
127 self.interval = interval |
135 self.interval = interval |
128 self.monitorCondition.wakeAll() |
136 self.monitorCondition.wakeAll() |
129 if locked: |
137 if locked: |
130 self.monitorMutex.unlock() |
138 self.monitorMutex.unlock() |
131 |
139 |
132 def getInterval(self): |
140 def getInterval(self): |
133 """ |
141 """ |
134 Public method to get the monitor interval. |
142 Public method to get the monitor interval. |
135 |
143 |
136 @return interval in seconds (integer) |
144 @return interval in seconds (integer) |
137 """ |
145 """ |
138 return self.interval |
146 return self.interval |
139 |
147 |
140 def setAutoUpdate(self, auto): |
148 def setAutoUpdate(self, auto): |
141 """ |
149 """ |
142 Public method to enable the auto update function. |
150 Public method to enable the auto update function. |
143 |
151 |
144 @param auto status of the auto update function (boolean) |
152 @param auto status of the auto update function (boolean) |
145 """ |
153 """ |
146 self.autoUpdate = auto |
154 self.autoUpdate = auto |
147 |
155 |
148 def getAutoUpdate(self): |
156 def getAutoUpdate(self): |
149 """ |
157 """ |
150 Public method to retrieve the status of the auto update function. |
158 Public method to retrieve the status of the auto update function. |
151 |
159 |
152 @return status of the auto update function (boolean) |
160 @return status of the auto update function (boolean) |
153 """ |
161 """ |
154 return self.autoUpdate |
162 return self.autoUpdate |
155 |
163 |
156 def checkStatus(self): |
164 def checkStatus(self): |
157 """ |
165 """ |
158 Public method to wake up the status monitor thread. |
166 Public method to wake up the status monitor thread. |
159 """ |
167 """ |
160 locked = self.monitorMutex.tryLock() |
168 locked = self.monitorMutex.tryLock() |
161 self.monitorCondition.wakeAll() |
169 self.monitorCondition.wakeAll() |
162 if locked: |
170 if locked: |
163 self.monitorMutex.unlock() |
171 self.monitorMutex.unlock() |
164 |
172 |
165 def stop(self): |
173 def stop(self): |
166 """ |
174 """ |
167 Public method to stop the monitor thread. |
175 Public method to stop the monitor thread. |
168 """ |
176 """ |
169 locked = self.monitorMutex.tryLock() |
177 locked = self.monitorMutex.tryLock() |