@@ -211,7 +211,7 @@ def __init__( # noqa: PLR0915
211211 ##############
212212
213213 if pagination_args is not None :
214- pagination_args ["size" ] = graphene_settings . RELAY_CONNECTION_MAX_LIMIT
214+ pagination_args ["size" ] = reservation_unit_queryset . count ()
215215 qs_slice = calculate_queryset_slice (** pagination_args )
216216 self .start_offset = qs_slice .start
217217 self .stop_offset = qs_slice .stop
@@ -245,7 +245,7 @@ def __init__( # noqa: PLR0915
245245
246246 self .first_reservable_times = {}
247247 self .reservation_unit_closed_statuses = {}
248- self .cached_value_validity = {}
248+ self .cached_value_validity : dict [ int , datetime . datetime ] = {}
249249
250250 # Closed time spans that are shared by all ReservationUnits
251251 self .shared_hard_closed_time_spans = self ._get_shared_hard_closed_time_spans ()
@@ -277,20 +277,23 @@ def calculate_all_first_reservable_times(self) -> None:
277277 # If we already have cached FRT results for enough reservation units to fill the page
278278 # AND all the previous pages, then we don't need to calculate anything.
279279 # NOTE: This does not support different orderings of the same queryset!
280- required = (
280+ # TODO: This doesn't work for the last page if it's not full!
281+ cached = (
281282 sum (1 for frt in self .first_reservable_times .values () if frt is not None )
282283 if self .show_only_reservable
283284 else len (self .first_reservable_times )
284285 )
285- if required >= self .stop_offset :
286+ if cached >= self .stop_offset :
286287 return
287288
288- # Otherwise, we can still skip looping through the previous pages.
289- qs = qs [self .start_offset :]
290- self .start_offset = 0 # Remove offset since we skip the previous pages
289+ # Otherwise, we should still have valid results for the previous pages.
290+ # We can start calculating after the last cached result.
291+ qs = qs [len (self .first_reservable_times ) :]
292+ # We also don't need to skip any results that are not already cached.
293+ self .start_offset = 0
291294
292295 # If we don't have valid results, and this is not the first page,
293- # we should fetch the current and previous pages in on chunk. The next chunk
296+ # we should fetch the current and previous pages in one chunk. The next chunk
294297 # will also be bigger (if needed), but likely small enough (<100) not to cause any problems.
295298 elif self .start_offset > 0 :
296299 self .chunk_size = self .stop_offset
@@ -303,15 +306,14 @@ def calculate_all_first_reservable_times(self) -> None:
303306 self .reservation_unit_closed_statuses [reservation_unit .pk ] = is_closed
304307 self .first_reservable_times [reservation_unit .pk ] = first_reservable_time
305308
306- # Start offset should exist only if we need to recalculate previous pages.
307- # -> Don't count the result for the current page.
308- if self .start_offset > 0 :
309- self .start_offset -= 1
310- continue
311-
312309 # If we should only show reservable reservation units, then we should count the result for the
313310 # current page only if there is a first reservable time.
314311 if not self .show_only_reservable or first_reservable_time is not None :
312+ # Start offset should exist only if we need to recalculate previous pages.
313+ # -> Don't count the result for the current page.
314+ if self .start_offset > 0 :
315+ self .start_offset -= 1
316+ continue
315317 results += 1
316318
317319 # This only really matters when showing only reservable reservation units,
@@ -327,9 +329,9 @@ def _read_cached_results(self) -> bool:
327329
328330 Check that we have valid results for all the previous pages.
329331 If not, we must recalculate results for all previous pages, since they might be different
330- if one FRT has changed to None or from None to a valid value .
332+ if one FRT has changed from a datetime to None or vice versa .
331333 """
332- cached_data : dict [ReservationUnitPK , dict [str , Any ]] = json .loads (cache .get (self .cache_key , "{}" ))
334+ cached_data : dict [str , dict [str , Any ]] = json .loads (cache .get (self .cache_key , "{}" ))
333335
334336 has_valid_results_for_previous_pages = bool (cached_data )
335337 for pk , item in cached_data .items ():
@@ -339,21 +341,22 @@ def _read_cached_results(self) -> bool:
339341 self .first_reservable_times .clear ()
340342 return False
341343
342- self .reservation_unit_closed_statuses [pk ] = cached_result .closed
343- self .first_reservable_times [pk ] = cached_result .frt
344- self .cached_value_validity [pk ] = cached_result .valid_until
344+ self .reservation_unit_closed_statuses [int ( pk ) ] = cached_result .closed
345+ self .first_reservable_times [int ( pk ) ] = cached_result .frt
346+ self .cached_value_validity [int ( pk ) ] = cached_result .valid_until
345347
346348 return has_valid_results_for_previous_pages
347349
348350 def _cache_results (self ) -> None :
349- """Save the calculated results to the cache."""
350- cached_data : dict [ReservationUnitPK , dict [str , Any ]] = {}
351+ """Save the calculated FRT results to the cache."""
352+ cached_data : dict [str , dict [str , Any ]] = {}
351353 new_valid_until = self .now + datetime .timedelta (minutes = 2 )
352354
353355 for pk , frt in self .first_reservable_times .items ():
354356 is_closed = self .reservation_unit_closed_statuses [pk ]
357+ # If FRT was not calculated in this request, use the previous 'valid_until' value.
355358 valid_until = self .cached_value_validity .get (pk , new_valid_until )
356- cached_data [pk ] = CachedReservableTime (frt = frt , closed = is_closed , valid_until = valid_until ).to_dict ()
359+ cached_data [str ( pk ) ] = CachedReservableTime (frt = frt , closed = is_closed , valid_until = valid_until ).to_dict ()
357360
358361 cache .set (self .cache_key , json .dumps (cached_data ), timeout = 120 )
359362
0 commit comments