Skip to content

Commit 6edc504

Browse files
authored
Merge branch 'master' into TP2000-1668-override
2 parents f0662c7 + 0deec32 commit 6edc504

File tree

2 files changed

+326
-49
lines changed

2 files changed

+326
-49
lines changed

publishing/models/packaged_workbasket.py

+78-49
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from notifications.models import EnvelopeRejectedNotification
3232
from notifications.models import NotificationLog
3333
from publishing import models as publishing_models
34+
from publishing.models.decorators import refresh_after
3435
from publishing.models.decorators import save_after
3536
from publishing.models.decorators import skip_notifications_if_disabled
3637
from publishing.models.state import ProcessingState
@@ -437,6 +438,7 @@ def begin_processing_condition_at_position_1(self) -> bool:
437438
"""Django FSM condition: Instance must be at position 1 in order to
438439
complete the begin_processing transition to CURRENTLY_PROCESSING."""
439440

441+
self.refresh_from_db(fields=["position"])
440442
return self.position == 1
441443

442444
def begin_processing_condition_no_instances_currently_processing(self) -> bool:
@@ -476,7 +478,9 @@ def begin_processing(self):
476478
multiple instances it's necessary for this method to perform a save()
477479
operation upon successful transitions.
478480
"""
479-
PackagedWorkBasket.objects.select_for_update(nowait=True).get(pk=self.pk)
481+
PackagedWorkBasket.objects.select_for_update(nowait=True).get(
482+
pk=self.pk,
483+
)
480484
self.processing_started_at = make_aware(datetime.now())
481485
self.save()
482486

@@ -618,6 +622,7 @@ def cds_notified_notification_log(self) -> NotificationLog:
618622

619623
@atomic
620624
@create_envelope_on_new_top
625+
@refresh_after
621626
def pop_top(self) -> "PackagedWorkBasket":
622627
"""
623628
Pop the top-most instance, shuffling all remaining queued instances
@@ -626,23 +631,34 @@ def pop_top(self) -> "PackagedWorkBasket":
626631
Management of the popped instance's `processing_state` is not altered by
627632
this function and should be managed separately by the caller.
628633
"""
629-
if self.position != 1:
634+
635+
instance = PackagedWorkBasket.objects.select_for_update(nowait=True).get(
636+
pk=self.pk,
637+
)
638+
639+
if instance.position != 1:
630640
raise PackagedWorkBasketInvalidQueueOperation(
631-
"Unable to pop instance at position {self.position} in queue "
641+
"Unable to pop instance at position {instance.position} in queue "
632642
"because it is not at position 1.",
633643
)
634644

635-
PackagedWorkBasket.objects.select_for_update(nowait=True).filter(
636-
position__gt=0,
637-
).update(
645+
instance.position = 0
646+
instance.save()
647+
648+
to_update = list(
649+
PackagedWorkBasket.objects.select_for_update(nowait=True)
650+
.filter(position__gt=1)
651+
.values_list("pk", flat=True),
652+
)
653+
PackagedWorkBasket.objects.filter(pk__in=to_update).update(
638654
position=F("position") - 1,
639655
)
640-
self.refresh_from_db()
641656

642-
return self
657+
return instance
643658

644659
@atomic
645660
@create_envelope_on_new_top
661+
@refresh_after
646662
def remove_from_queue(self) -> "PackagedWorkBasket":
647663
"""
648664
Remove instance from the queue, shuffling all successive queued
@@ -652,98 +668,111 @@ def remove_from_queue(self) -> "PackagedWorkBasket":
652668
this function and should be managed separately by the caller.
653669
"""
654670

655-
PackagedWorkBasket.objects.select_for_update(nowait=True).get(pk=self.pk)
656-
self.refresh_from_db()
671+
instance = PackagedWorkBasket.objects.select_for_update(nowait=True).get(
672+
pk=self.pk,
673+
)
657674

658-
if self.position == 0:
675+
if instance.position == 0:
659676
raise PackagedWorkBasketInvalidQueueOperation(
660677
"Unable to remove instance with a position value of 0 from "
661678
"queue because 0 indicates that it is not a queue member.",
662679
)
663680

664-
current_position = self.position
665-
self.position = 0
666-
self.save()
681+
current_position = instance.position
682+
instance.position = 0
683+
instance.save()
667684

668-
PackagedWorkBasket.objects.select_for_update(nowait=True).filter(
669-
position__gt=current_position,
670-
).update(
685+
to_update = list(
686+
PackagedWorkBasket.objects.select_for_update(nowait=True)
687+
.filter(position__gt=current_position)
688+
.values_list("pk", flat=True),
689+
)
690+
PackagedWorkBasket.objects.filter(pk__in=to_update).update(
671691
position=F("position") - 1,
672692
)
673-
self.refresh_from_db()
674693

675-
return self
694+
return instance
676695

677696
@atomic
678697
@create_envelope_on_new_top
698+
@refresh_after
679699
def promote_to_top_position(self) -> "PackagedWorkBasket":
680700
"""Promote the instance to the top position of the package processing
681701
queue so that it occupies position 1."""
682702

683-
PackagedWorkBasket.objects.select_for_update(nowait=True).get(pk=self.pk)
684-
self.refresh_from_db()
703+
instance = PackagedWorkBasket.objects.select_for_update(nowait=True).get(
704+
pk=self.pk,
705+
)
685706

686-
if self.position <= 1:
687-
return self
707+
if instance.position <= 1:
708+
return instance
688709

689-
position = self.position
710+
current_position = instance.position
690711

691-
PackagedWorkBasket.objects.select_for_update(nowait=True).filter(
692-
Q(position__gte=1) & Q(position__lt=position),
693-
).update(position=F("position") + 1)
712+
to_update = list(
713+
PackagedWorkBasket.objects.select_for_update(nowait=True)
714+
.filter(Q(position__gte=1) & Q(position__lt=current_position))
715+
.values_list("pk", flat=True),
716+
)
717+
PackagedWorkBasket.objects.filter(pk__in=to_update).update(
718+
position=F("position") + 1,
719+
)
694720

695-
self.position = 1
696-
self.save()
697-
self.refresh_from_db()
721+
instance.position = 1
722+
instance.save()
698723

699-
return self
724+
return instance
700725

701726
@atomic
702727
@create_envelope_on_new_top
728+
@refresh_after
703729
def promote_position(self) -> "PackagedWorkBasket":
704730
"""Promote the instance by one position up the package processing
705731
queue."""
706732

707-
PackagedWorkBasket.objects.select_for_update(nowait=True).get(pk=self.pk)
708-
self.refresh_from_db()
733+
instance = PackagedWorkBasket.objects.select_for_update(nowait=True).get(
734+
pk=self.pk,
735+
)
709736

710-
if self.position <= 1:
711-
return self
737+
if instance.position <= 1:
738+
return instance
712739

713740
obj_to_swap = PackagedWorkBasket.objects.select_for_update(nowait=True).get(
714-
position=self.position - 1,
741+
position=instance.position - 1,
715742
)
716743
obj_to_swap.position += 1
717-
self.position -= 1
744+
instance.position -= 1
745+
718746
PackagedWorkBasket.objects.bulk_update(
719-
[self, obj_to_swap],
747+
[instance, obj_to_swap],
720748
["position"],
721749
)
722-
self.refresh_from_db()
723750

724-
return self
751+
return instance
725752

726753
@atomic
727754
@create_envelope_on_new_top
755+
@refresh_after
728756
def demote_position(self) -> "PackagedWorkBasket":
729757
"""Demote the instance by one position down the package processing
730758
queue."""
731759

732-
PackagedWorkBasket.objects.select_for_update(nowait=True).get(pk=self.pk)
733-
self.refresh_from_db()
760+
instance = PackagedWorkBasket.objects.select_for_update(nowait=True).get(
761+
pk=self.pk,
762+
)
734763

735-
if self.position in {0, PackagedWorkBasket.objects.max_position()}:
736-
return self
764+
if instance.position in {0, PackagedWorkBasket.objects.max_position()}:
765+
return instance
737766

738767
obj_to_swap = PackagedWorkBasket.objects.select_for_update(nowait=True).get(
739-
position=self.position + 1,
768+
position=instance.position + 1,
740769
)
741770
obj_to_swap.position -= 1
742-
self.position += 1
771+
instance.position += 1
772+
743773
PackagedWorkBasket.objects.bulk_update(
744-
[self, obj_to_swap],
774+
[instance, obj_to_swap],
745775
["position"],
746776
)
747-
self.refresh_from_db()
748777

749-
return self
778+
return instance

0 commit comments

Comments
 (0)