Sun, 18 Dec 2022 19:33:46 +0100
Refactored the Utilities and Globals modules in order to enhance the maintainability.
7335 | 1 | # -*- coding: utf-8 -*- |
2 | ||
8881
54e42bc2437a
Updated copyright for 2022.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8650
diff
changeset
|
3 | # Copyright (c) 2019 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> |
7335 | 4 | # |
5 | ||
6 | """ | |
7 | Module implementing the syntax check for YAML. | |
8 | """ | |
9 | ||
9473
3f23dbf37dbe
Resorted the import statements using isort.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9292
diff
changeset
|
10 | import multiprocessing |
7335 | 11 | import queue |
12 | ||
13 | ||
14 | def initService(): | |
15 | """ | |
16 | Initialize the service and return the entry point. | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
17 | |
7335 | 18 | @return the entry point for the background client |
19 | @rtype func | |
20 | """ | |
21 | return yamlSyntaxCheck | |
22 | ||
23 | ||
24 | def initBatchService(): | |
25 | """ | |
26 | Initialize the batch service and return the entry point. | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
27 | |
7335 | 28 | @return the entry point for the background client |
29 | @rtype func | |
30 | """ | |
31 | return yamlSyntaxBatchCheck | |
32 | ||
33 | ||
34 | def yamlSyntaxCheck(file, codestring): | |
35 | """ | |
36 | Function to check a YAML source file for syntax errors. | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
37 | |
7335 | 38 | @param file source filename |
39 | @type str | |
40 | @param codestring string containing the code to check | |
41 | @type str | |
42 | @return dictionary with the keys 'error' and 'warnings' which | |
43 | hold a list containing details about the error/ warnings | |
44 | (file name, line number, column, codestring (only at syntax | |
45 | errors), the message, a list with arguments for the message) | |
46 | @rtype dict | |
47 | """ | |
48 | return __yamlSyntaxCheck(file, codestring) | |
49 | ||
50 | ||
51 | def yamlSyntaxBatchCheck(argumentsList, send, fx, cancelled, maxProcesses=0): | |
52 | """ | |
53 | Module function to check syntax for a batch of files. | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
54 | |
7335 | 55 | @param argumentsList list of arguments tuples as given for yamlSyntaxCheck |
56 | @type list | |
57 | @param send reference to send function | |
58 | @type func | |
59 | @param fx registered service name | |
60 | @type str | |
61 | @param cancelled reference to function checking for a cancellation | |
62 | @type func | |
63 | @param maxProcesses number of processes to be used | |
64 | @type int | |
65 | """ | |
66 | if maxProcesses == 0: | |
67 | # determine based on CPU count | |
68 | try: | |
69 | NumberOfProcesses = multiprocessing.cpu_count() | |
70 | if NumberOfProcesses >= 1: | |
71 | NumberOfProcesses -= 1 | |
72 | except NotImplementedError: | |
73 | NumberOfProcesses = 1 | |
74 | else: | |
75 | NumberOfProcesses = maxProcesses | |
76 | ||
77 | # Create queues | |
78 | taskQueue = multiprocessing.Queue() | |
79 | doneQueue = multiprocessing.Queue() | |
80 | ||
9289
ba49c41e8f63
Did some optimizations in the multiprocessing code.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9284
diff
changeset
|
81 | # Submit tasks (initially two times the number of processes) |
ba49c41e8f63
Did some optimizations in the multiprocessing code.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9284
diff
changeset
|
82 | tasks = len(argumentsList) |
9292
a5c8a0213fe3
Fixed an issue in the multiprocessing usage causing a traceback when then number of tasks is smaller than the number of worker processes.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9289
diff
changeset
|
83 | initialTasks = min(2 * NumberOfProcesses, tasks) |
9289
ba49c41e8f63
Did some optimizations in the multiprocessing code.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9284
diff
changeset
|
84 | for _ in range(initialTasks): |
ba49c41e8f63
Did some optimizations in the multiprocessing code.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9284
diff
changeset
|
85 | taskQueue.put(argumentsList.pop(0)) |
7335 | 86 | |
87 | # Start worker processes | |
8650
100726f55a9a
Changed the 'multiprocessing.Process()' code of the background batch services to (hopefully) cure the slow down when used multiple times.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8312
diff
changeset
|
88 | workers = [ |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
89 | multiprocessing.Process(target=workerTask, args=(taskQueue, doneQueue)) |
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
90 | for _ in range(NumberOfProcesses) |
8650
100726f55a9a
Changed the 'multiprocessing.Process()' code of the background batch services to (hopefully) cure the slow down when used multiple times.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8312
diff
changeset
|
91 | ] |
100726f55a9a
Changed the 'multiprocessing.Process()' code of the background batch services to (hopefully) cure the slow down when used multiple times.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8312
diff
changeset
|
92 | for worker in workers: |
100726f55a9a
Changed the 'multiprocessing.Process()' code of the background batch services to (hopefully) cure the slow down when used multiple times.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8312
diff
changeset
|
93 | worker.start() |
7335 | 94 | |
95 | # Get and send results | |
9289
ba49c41e8f63
Did some optimizations in the multiprocessing code.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9284
diff
changeset
|
96 | for _ in range(tasks): |
7335 | 97 | resultSent = False |
98 | wasCancelled = False | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
99 | |
7335 | 100 | while not resultSent: |
101 | try: | |
102 | # get result (waiting max. 3 seconds and send it to frontend | |
103 | filename, result = doneQueue.get() | |
104 | send(fx, filename, result) | |
105 | resultSent = True | |
106 | except queue.Empty: | |
107 | # ignore empty queue, just carry on | |
108 | if cancelled(): | |
109 | wasCancelled = True | |
110 | break | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
111 | |
7335 | 112 | if wasCancelled or cancelled(): |
113 | # just exit the loop ignoring the results of queued tasks | |
114 | break | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
115 | |
9289
ba49c41e8f63
Did some optimizations in the multiprocessing code.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9284
diff
changeset
|
116 | if argumentsList: |
ba49c41e8f63
Did some optimizations in the multiprocessing code.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9284
diff
changeset
|
117 | taskQueue.put(argumentsList.pop(0)) |
7335 | 118 | |
119 | # Tell child processes to stop | |
120 | for _ in range(NumberOfProcesses): | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
121 | taskQueue.put("STOP") |
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
122 | |
8650
100726f55a9a
Changed the 'multiprocessing.Process()' code of the background batch services to (hopefully) cure the slow down when used multiple times.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8312
diff
changeset
|
123 | for worker in workers: |
100726f55a9a
Changed the 'multiprocessing.Process()' code of the background batch services to (hopefully) cure the slow down when used multiple times.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8312
diff
changeset
|
124 | worker.join() |
100726f55a9a
Changed the 'multiprocessing.Process()' code of the background batch services to (hopefully) cure the slow down when used multiple times.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8312
diff
changeset
|
125 | worker.close() |
9284
3b3a4f659782
"Blacked" the sources.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9279
diff
changeset
|
126 | |
9279
e252f827aaa7
Added code to explicitly close the queues to/from the workers at the end of a batch check.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9221
diff
changeset
|
127 | taskQueue.close() |
e252f827aaa7
Added code to explicitly close the queues to/from the workers at the end of a batch check.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9221
diff
changeset
|
128 | doneQueue.close() |
7335 | 129 | |
130 | ||
8650
100726f55a9a
Changed the 'multiprocessing.Process()' code of the background batch services to (hopefully) cure the slow down when used multiple times.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
8312
diff
changeset
|
131 | def workerTask(inputQueue, outputQueue): |
7335 | 132 | """ |
133 | Module function acting as the parallel worker for the syntax check. | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
134 | |
7335 | 135 | @param inputQueue input queue |
136 | @type multiprocessing.Queue | |
137 | @param outputQueue output queue | |
138 | @type multiprocessing.Queue | |
139 | """ | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
140 | for filename, args in iter(inputQueue.get, "STOP"): |
7335 | 141 | source = args[0] |
142 | result = __yamlSyntaxCheck(filename, source) | |
143 | outputQueue.put((filename, result)) | |
144 | ||
145 | ||
146 | def __yamlSyntaxCheck(file, codestring): | |
147 | """ | |
148 | Function to check a YAML source file for syntax errors. | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
149 | |
7335 | 150 | @param file source filename |
151 | @type str | |
152 | @param codestring string containing the code to check | |
153 | @type str | |
154 | @return dictionary with the keys 'error' and 'warnings' which | |
155 | hold a list containing details about the error/ warnings | |
156 | (file name, line number, column, codestring (only at syntax | |
157 | errors), the message, a list with arguments for the message) | |
158 | @rtype dict | |
159 | """ | |
160 | try: | |
9482
a2bc06a54d9d
Corrected/acknowledged some bad import style and removed some obsolete code.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9473
diff
changeset
|
161 | from yaml import MarkedYAMLError, safe_load_all # __IGNORE_WARNING_I10__ |
7335 | 162 | except ImportError: |
163 | error = "pyyaml not available. Install it via the PyPI interface." | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
164 | return [{"error": (file, 0, 0, "", error)}] |
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
165 | |
7335 | 166 | try: |
167 | for _obj in safe_load_all(codestring): | |
168 | # do nothing with it, just to get parse errors | |
169 | pass | |
170 | except MarkedYAMLError as exc: | |
171 | if exc.problem_mark: | |
172 | line = exc.problem_mark.line + 1 | |
173 | column = exc.problem_mark.column | |
174 | else: | |
175 | line, column = 0, 0 | |
176 | error = exc.problem | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
177 | |
7335 | 178 | cline = min(len(codestring.splitlines()), int(line)) - 1 |
179 | code = codestring.splitlines()[cline] | |
9221
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
180 | |
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
181 | return [{"error": (file, line, column, code, error)}] |
bf71ee032bb4
Reformatted the source code using the 'Black' utility.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
9209
diff
changeset
|
182 | |
7335 | 183 | return [{}] |