-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cancel obsolete requests #268
base: main
Are you sure you want to change the base?
Changes from all commits
c1bc989
88da07e
4e58dfb
d8e05ef
03c8fb5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
* text=auto eol=lf | ||
*.py eol=lf diff=python |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,7 +39,7 @@ | |
# PyQt | ||
from PyQt5.QtCore import QRect, QRectF, QMutex, QObject, pyqtSignal | ||
from PyQt5.QtWidgets import QGraphicsItem | ||
from PyQt5.QtGui import QImage, QPainter, QTransform | ||
from PyQt5.QtGui import QImage, QPainter, QTransform, QColor | ||
|
||
# volumina | ||
from volumina.patchAccessor import PatchAccessor | ||
|
@@ -248,11 +248,11 @@ def __init__(self, tiling, stackedImageSources, cache_size: int = 100) -> None: | |
cache_size -- maximal number of encountered stacks | ||
to cache, i.e. slices if the imagesources | ||
draw from slicesources (default 10) | ||
parent -- QObject | ||
|
||
""" | ||
|
||
QObject.__init__(self, parent=None) | ||
self._current_requests = {} | ||
|
||
self.tiling = tiling | ||
self.axesSwapped = False | ||
|
@@ -303,6 +303,8 @@ def waitForTiles(self, rectF=QRectF()): | |
while not finished: | ||
finished = True | ||
tiles = self.getTiles(rectF) | ||
while self._current_requests: | ||
time.sleep(0.01) | ||
for tile in tiles: | ||
finished &= tile.progress >= 1.0 | ||
|
||
|
@@ -315,6 +317,12 @@ def requestRefresh(self, rectF, stack_id=None, prefetch=False, layer_indexes=Non | |
""" | ||
stack_id = stack_id or self._current_stack_id | ||
tile_nos = self.tiling.intersected(rectF) | ||
to_cancel = self._current_requests | ||
self._current_requests = {} | ||
|
||
for id_, rq in to_cancel.items(): | ||
rq.cancel() | ||
|
||
for tile_no in tile_nos: | ||
self._refreshTile(stack_id, tile_no, prefetch, layer_indexes) | ||
|
||
|
@@ -405,6 +413,7 @@ def _refreshTile(self, stack_id, tile_no, prefetch=False, layer_indexes=None): | |
try: | ||
# Create the request object right now, from the main thread. | ||
ims_req = ims.request(dataRect, stack_id[1]) | ||
self._current_requests[(stack_id[1], ims, tile_no)] = ims_req | ||
except IndeterminateRequestError: | ||
# In ilastik, the viewer is still churning even as the user might be changing settings in the UI. | ||
# Settings changes can cause 'slot not ready' errors during graph setup. | ||
|
@@ -413,7 +422,7 @@ def _refreshTile(self, stack_id, tile_no, prefetch=False, layer_indexes=None): | |
logger.debug("Failed to create layer tile request", exc_info=True) | ||
continue | ||
|
||
timestamp = time.time() | ||
timestamp = time.monotonic() | ||
fetch_fn = partial( | ||
self._fetch_layer_tile, timestamp, ims, transform, tile_no, stack_id, ims_req, self._cache | ||
) | ||
|
@@ -449,6 +458,7 @@ def _blendTile(self, stack_id, tile_nr): | |
""" | ||
qimg = None | ||
p = None | ||
|
||
for i, (visible, layerOpacity, layerImageSource) in enumerate(reversed(self._sims)): | ||
image_type = layerImageSource.image_type() | ||
if issubclass(image_type, QGraphicsItem): | ||
|
@@ -552,6 +562,11 @@ def _fetch_layer_tile(self, timestamp, ims, transform, tile_nr, stack_id, ims_re | |
|
||
if stack_id == self._current_stack_id and cache is self._cache: | ||
self.sceneRectChanged.emit(tile_rect) | ||
else: | ||
ims_req.cancel() | ||
|
||
self._current_requests.pop((stack_id[1], ims, tile_nr), None) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you using This kinda makes me think if it would be possible for a request to overwrite an older one; If I, say, load an image in a layer, make a request, drop that layer, then load another image and make another request, is it possible for the second request to overwrite the previous one? Even worse, is it possible for the second one to be cancelled when we meant to cancel the first? |
||
|
||
except BaseException: | ||
logger.debug("Failed to fetch layer tile", exc_info=True) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Volumina's code is kinda hard to navigate, so I'd love to see some type annotations like
self._current_requests: Mapping[Tuple[LAYER_ID, ImageSource, REQUEST_ID], ArrayRequest] = {}