Skip to content

Commit 3fa8edd

Browse files
committed
Merge branch 'master' of https://github.com/AcademySoftwareFoundation/OpenCue into rqd-cuda
2 parents e05eb27 + 0d3cc69 commit 3fa8edd

File tree

18 files changed

+287
-96
lines changed

18 files changed

+287
-96
lines changed

cuebot/src/main/java/com/imageworks/spcue/dao/postgres/DispatchQuery.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ public class DispatchQuery {
4444
"AND folder.pk_dept = point.pk_dept " +
4545
"AND folder.pk_show = point.pk_show " +
4646
"AND job.pk_job = layer.pk_job " +
47-
"AND job_resource.pk_job = job.pk_job " +
4847
"AND (CASE WHEN layer_stat.int_waiting_count > 0 THEN layer_stat.pk_layer ELSE NULL END) = layer.pk_layer " +
4948
"AND " +
5049
"(" +
@@ -139,7 +138,6 @@ public class DispatchQuery {
139138
"AND folder.pk_dept = point.pk_dept " +
140139
"AND folder.pk_show = point.pk_show " +
141140
"AND job.pk_job = layer.pk_job " +
142-
"AND job_resource.pk_job = job.pk_job " +
143141
"AND (CASE WHEN layer_stat.int_waiting_count > 0 THEN layer_stat.pk_layer ELSE NULL END) = layer.pk_layer " +
144142
"AND " +
145143
"(" +

cuebot/src/main/java/com/imageworks/spcue/servant/ManageServiceOverride.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
import io.grpc.stub.StreamObserver;
2525

26-
import com.imageworks.spcue.ServiceEntity;
26+
import com.imageworks.spcue.ServiceOverrideEntity;
2727
import com.imageworks.spcue.grpc.service.Service;
2828
import com.imageworks.spcue.grpc.service.ServiceOverrideDeleteRequest;
2929
import com.imageworks.spcue.grpc.service.ServiceOverrideDeleteResponse;
@@ -39,15 +39,17 @@ public class ManageServiceOverride extends ServiceOverrideInterfaceGrpc.ServiceO
3939
@Override
4040
public void delete(ServiceOverrideDeleteRequest request,
4141
StreamObserver<ServiceOverrideDeleteResponse> responseObserver) {
42-
serviceManager.deleteService(toServiceEntity(request.getService()));
42+
// Passing null on showId as the interface doesn't require a showId in this situation
43+
serviceManager.deleteService(toServiceOverrideEntity(request.getService(), null));
4344
responseObserver.onNext(ServiceOverrideDeleteResponse.newBuilder().build());
4445
responseObserver.onCompleted();
4546
}
4647

4748
@Override
4849
public void update(ServiceOverrideUpdateRequest request,
4950
StreamObserver<ServiceOverrideUpdateResponse> responseObserver) {
50-
serviceManager.updateService(toServiceEntity(request.getService()));
51+
// Passing null on showId as the interface doesn't require a showId in this situation
52+
serviceManager.updateService(toServiceOverrideEntity(request.getService(), null));
5153
responseObserver.onNext(ServiceOverrideUpdateResponse.newBuilder().build());
5254
responseObserver.onCompleted();
5355
}
@@ -60,8 +62,8 @@ public void setServiceManager(ServiceManager serviceManager) {
6062
this.serviceManager = serviceManager;
6163
}
6264

63-
private ServiceEntity toServiceEntity(Service service) {
64-
ServiceEntity entity = new ServiceEntity();
65+
private ServiceOverrideEntity toServiceOverrideEntity(Service service, String showId){
66+
ServiceOverrideEntity entity = new ServiceOverrideEntity();
6567
entity.id = service.getId();
6668
entity.name = service.getName();
6769
entity.minCores = service.getMinCores();
@@ -72,6 +74,7 @@ private ServiceEntity toServiceEntity(Service service) {
7274
entity.minGpuMemory = service.getMinGpuMemory();
7375
entity.tags = new LinkedHashSet<>(service.getTagsList());
7476
entity.threadable = service.getThreadable();
77+
entity.showId = showId;
7578
entity.timeout = service.getTimeout();
7679
entity.timeout_llu = service.getTimeoutLlu();
7780
entity.minMemoryIncrease = service.getMinMemoryIncrease();
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
--Performance issue, Created new index on column int_gpus_min
3+
4+
5+
CREATE INDEX IF NOT EXISTS i_layer_int_gpu_mem_min
6+
ON public.layer USING btree
7+
(int_gpus_min ASC NULLS LAST)
8+
TABLESPACE pg_default;
9+
10+
11+
CREATE INDEX IF NOT EXISTS i_layer_int_gpu_mem_min_1
12+
ON public.layer USING btree
13+
(int_gpu_min ASC NULLS LAST)
14+
TABLESPACE pg_default;
15+
16+
17+
create index concurrently i_layer_int_cores_max on layer(int_cores_max);
18+
19+
create index concurrently i_job_resource_int_priority on job_resource(int_priority);
20+
21+
create index concurrently i_job_int_min_cores on job(int_min_cores);
22+
23+
create index concurrently i_layer_limit_pk_layer on layer_limit(pk_layer);
24+
25+
create index concurrently i_folder_resource_int_cores on folder_resource(int_cores);
26+
27+
create index concurrently i_job_ts_updated on job(ts_updated);
28+
29+
create index concurrently i_layer_str_tags on layer(str_tags);

cuegui/cuegui/JobMonitorTree.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ def _getUpdate(self):
494494
# an empty list for the id argument!
495495
if not ids:
496496
continue
497-
tmp = opencue.api.getJobs(id=ids, all=True)
497+
tmp = opencue.api.getJobs(id=ids, include_finished=True)
498498
self.__dependentJobs[job] = tmp
499499

500500
if self.__loadMine:

cuegui/cuegui/Main.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ def startup(app_name, app_version, argv):
9292
app.aboutToQuit.connect(closingTime) # pylint: disable=no-member
9393
app.exec_()
9494

95-
9695
def closingTime():
9796
"""Window close callback."""
9897
logger.info("Closing all threads...")

cuegui/cuegui/ServiceDialog.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import cuegui.Constants
3232
import cuegui.TagsWidget
3333
import cuegui.Utils
34+
from opencue.wrappers.service import ServiceOverride
3435

3536

3637
class ServiceForm(QtWidgets.QWidget):
@@ -124,13 +125,13 @@ def setService(self, service):
124125
"""
125126
self.__service = service
126127
self.__buttons.setDisabled(False)
127-
self.name.setText(service.data.name)
128-
self.threadable.setChecked(service.data.threadable)
129-
self.min_cores.setValue(service.data.min_cores)
130-
self.max_cores.setValue(service.data.max_cores)
131-
self.min_memory.setValue(service.data.min_memory // 1024)
128+
self.name.setText(service.name())
129+
self.threadable.setChecked(service.threadable())
130+
self.min_cores.setValue(service.minCores())
131+
self.max_cores.setValue(service.maxCores())
132132
self.min_gpu_memory.setValue(service.data.min_gpu_memory // 1024)
133-
self._tags_w.set_tags(service.data.tags)
133+
self.min_memory.setValue(service.minMemory() // 1024)
134+
self._tags_w.set_tags(service.tags())
134135
self.timeout.setValue(service.data.timeout)
135136
self.timeout_llu.setValue(service.data.timeout_llu)
136137
self.min_memory_increase.setValue(service.data.min_memory_increase // 1024)
@@ -263,11 +264,16 @@ def saved(self, service):
263264

264265
if self.__new_service:
265266
if self.__show:
266-
self.__show.createServiceOverride(service.data)
267+
serviceOverride = self.__show.createServiceOverride(service.data)
267268
else:
268269
opencue.api.createService(service.data)
269270
else:
270-
service.update()
271+
if self.__show:
272+
serviceOverride = ServiceOverride(service)
273+
serviceOverride.id = service.id()
274+
serviceOverride.update()
275+
else:
276+
service.update()
271277

272278
self.refresh()
273279
self.__new_service = False

cuegui/cuegui/plugins/LogViewPlugin.py

Lines changed: 97 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
import os
2626
import re
2727
import string
28+
import sys
2829
import time
30+
import traceback
2931

3032
from qtpy import QtGui
3133
from qtpy import QtCore
@@ -292,10 +294,40 @@ def line_number_area_paint_event(self, event):
292294
bottom = top + self.blockBoundingRect(block).height()
293295
block_number += 1
294296

297+
class LogLoadSignals(QtCore.QObject):
298+
"""Signals for the LoadLog action"""
299+
SIG_LOG_LOAD_ERROR = QtCore.Signal(tuple)
300+
SIG_LOG_LOAD_RESULT = QtCore.Signal(str, str)
301+
SIG_LOG_LOAD_FINISHED = QtCore.Signal()
302+
303+
class LogLoader(QtCore.QRunnable):
304+
"""A thread to load logs"""
305+
def __init__(self, fn, *args, **kwargs):
306+
super(LogLoader, self).__init__()
307+
self.fn = fn
308+
self.args = args
309+
self.kwargs = kwargs
310+
self.signals = LogLoadSignals()
311+
312+
@QtCore.Slot()
313+
def run(self):
314+
# pylint: disable=bare-except
315+
try:
316+
content, log_mtime = self.fn(*self.args, **self.kwargs)
317+
except:
318+
exctype, value = sys.exc_info()[:2]
319+
self.signals.SIG_LOG_LOAD_ERROR.emit(
320+
(exctype, value, traceback.format_exc()))
321+
else:
322+
self.signals.SIG_LOG_LOAD_RESULT.emit(content, log_mtime)
323+
finally:
324+
self.signals.SIG_LOG_LOAD_FINISHED.emit()
295325

296326
class LogViewWidget(QtWidgets.QWidget):
297-
"""Displays the log file for the selected frame."""
298-
327+
"""
328+
Displays the log file for the selected frame
329+
"""
330+
SIG_CONTENT_UPDATED = QtCore.Signal(str, str)
299331
def __init__(self, parent=None):
300332
"""
301333
Create the UI elements
@@ -453,6 +485,9 @@ def __init__(self, parent=None):
453485
self._current_match = 0
454486
self._content_box.mousePressedSignal.connect(self._on_mouse_pressed)
455487

488+
self.SIG_CONTENT_UPDATED.connect(self._update_log_content)
489+
self.log_thread_pool = QtCore.QThreadPool()
490+
456491
def _on_mouse_pressed(self, pos):
457492
"""
458493
Mouse press event, to be called when the user scrolls by hand or moves
@@ -788,12 +823,56 @@ def _display_log_content(self):
788823
"""
789824

790825
try:
791-
self._update_log()
792-
self._new_log = False
826+
if not os.path.exists(self._log_file):
827+
self._log_file_exists = False
828+
content = 'Log file does not exist: %s' % self._log_file
829+
self._content_timestamp = time.time()
830+
self._update_log_content(content, self._log_mtime)
831+
else:
832+
# Creating the load logs process as qrunnables so
833+
# that they don't block the ui while loading
834+
log_loader = LogLoader(self._load_log, self._log_file,
835+
self._new_log, self._log_mtime)
836+
log_loader.signals.SIG_LOG_LOAD_RESULT.connect(
837+
self._receive_log_results)
838+
log_loader.setAutoDelete(True)
839+
self.log_thread_pool.start(log_loader)
840+
self.log_thread_pool.waitForDone()
841+
self._new_log = False
793842
finally:
794843
QtCore.QTimer.singleShot(5000, self._display_log_content)
795844

796-
def _update_log(self):
845+
# pylint: disable=no-self-use
846+
@QtCore.Slot()
847+
def _load_log(self, log_file, new_log, curr_log_mtime):
848+
content = None
849+
log_size = int(os.stat(log_file).st_size)
850+
if log_size > 1 * 1e6:
851+
content = ('Log file size (%0.1f MB) exceeds the size '
852+
'threshold (1.0 MB).'
853+
% float(log_size / (1024 * 1024)))
854+
elif not new_log and os.path.exists(log_file):
855+
log_mtime = os.path.getmtime(log_file)
856+
if log_mtime > curr_log_mtime:
857+
curr_log_mtime = log_mtime # no new updates
858+
content = ''
859+
860+
if content is None:
861+
content = ''
862+
try:
863+
with open(log_file, 'r') as f:
864+
content = f.read()
865+
except IOError:
866+
content = 'Can not access log file: %s' % log_file
867+
868+
return content, curr_log_mtime
869+
870+
@QtCore.Slot()
871+
def _receive_log_results(self, content, log_mtime):
872+
self.SIG_CONTENT_UPDATED.emit(content, log_mtime)
873+
874+
@QtCore.Slot(str, str)
875+
def _update_log_content(self, content, log_mtime):
797876
"""
798877
Updates the content of the content box with the content of the log
799878
file, if necessary. The full path to the log file will be populated in
@@ -813,49 +892,23 @@ def _update_log(self):
813892
(if necessary)
814893
"""
815894

816-
# Get the content of the log file
817-
if not self._log_file:
818-
return # There's no log file, nothing to do here!
819-
self._path.setText(self._log_file)
820-
content = None
821-
if not os.path.exists(self._log_file):
822-
self._log_file_exists = False
823-
content = 'Log file does not exist: %s' % self._log_file
824-
self._content_timestamp = time.time()
825-
else:
826-
log_size = int(os.stat(self._log_file).st_size)
827-
if log_size > 5 * 1e6:
828-
content = ('Log file size (%0.1f MB) exceeds the size '
829-
'threshold (5.0 MB).'
830-
% float(log_size / (1024 * 1024)))
831-
elif not self._new_log and os.path.exists(self._log_file):
832-
log_mtime = os.path.getmtime(self._log_file)
833-
if log_mtime > self._log_mtime:
834-
self._log_mtime = log_mtime # no new updates
835-
content = ''
836-
837-
if content is None:
838-
content = ''
839-
try:
840-
with open(self._log_file, 'r') as f:
841-
content = f.read()
842-
except IOError:
843-
content = 'Can not access log file: %s' % self._log_file
895+
self._log_mtime = log_mtime
844896

845-
# Do we need to scroll to the end?
846-
scroll_to_end = (self._scrollbar_max == self._scrollbar_value
847-
or self._new_log)
897+
self.app.processEvents()
848898

849899
# Update the content in the gui (if necessary)
850-
current_text = (self._content_box.toPlainText() or '')
851-
new_text = content.lstrip(str(current_text))
852-
if new_text:
853-
if self._new_log:
854-
self._content_box.setPlainText(content)
855-
else:
900+
if self._new_log:
901+
self._content_box.setPlainText(content)
902+
else:
903+
current_text = (self._content_box.toPlainText() or '')
904+
new_text = content.lstrip(str(current_text))
905+
if new_text:
856906
self._content_box.appendPlainText(new_text)
857-
self._content_timestamp = time.time()
858-
self.app.processEvents()
907+
self._content_timestamp = time.time()
908+
self._path.setText(self._log_file)
909+
910+
scroll_to_end = (self._scrollbar_max == self._scrollbar_value
911+
or self._new_log)
859912

860913
# Adjust scrollbar value (if necessary)
861914
self._scrollbar_max = self._log_scrollbar.maximum()

cuegui/cuegui/plugins/MonitorJobsPlugin.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -197,17 +197,17 @@ def _regexLoadJobsHandle(self):
197197

198198
self.jobMonitor.removeAllItems()
199199

200-
if cuegui.Utils.isStringId(substring):
201-
# If a uuid is provided, load it
202-
self.jobMonitor.addJob(substring)
203-
elif load_finished_jobs or re.search(
200+
if substring:
201+
if cuegui.Utils.isStringId(substring):
202+
# If a uuid is provided, load it
203+
self.jobMonitor.addJob(substring)
204+
elif load_finished_jobs or re.search(
204205
r"^([a-z0-9_]+)\-([a-z0-9\.]+)\-", substring, re.IGNORECASE):
205-
# If show and shot is provided, or if "load finished" checkbox is checked, load all jobs
206-
for job in opencue.api.getJobs(regex=[substring], include_finished=True):
207-
self.jobMonitor.addJob(job)
208-
else:
209-
# Otherwise, just load current matching jobs (except for the empty string)
210-
if substring:
206+
# Load all ff show and shot is provided or if "load finished" checkbox is checked
207+
for job in opencue.api.getJobs(regex=[substring], include_finished=True):
208+
self.jobMonitor.addJob(job)
209+
else:
210+
# Otherwise, just load current matching jobs (except for the empty string)
211211
for job in opencue.api.getJobs(regex=[substring]):
212212
self.jobMonitor.addJob(job)
213213

0 commit comments

Comments
 (0)