From d43b09ccd0c0428e9ee1e416ca5616dac6b646fa Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Fri, 26 Jan 2024 09:54:54 +0100 Subject: [PATCH 1/4] Disable tracking button if job limit is exceeded Tracking annotation button is disabled if there are already 10 jobs in the queue. Closes #609 --- .../Api/VideoAnnotationController.php | 1 + .../assets/js/videos/components/videoScreen.vue | 13 +++++++++++-- resources/assets/js/videos/videoContainer.vue | 17 ++++++++++++++++- resources/views/videos/show/content.blade.php | 1 + 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Api/VideoAnnotationController.php b/app/Http/Controllers/Api/VideoAnnotationController.php index 8e2972122..fc765ea30 100644 --- a/app/Http/Controllers/Api/VideoAnnotationController.php +++ b/app/Http/Controllers/Api/VideoAnnotationController.php @@ -240,6 +240,7 @@ public function store(StoreVideoAnnotation $request) $queue = config('videos.track_object_queue'); Queue::pushOn($queue, new TrackObject($annotation, $request->user())); Cache::increment(TrackObject::getRateLimitCacheKey($request->user())); + $annotation->trackedAnnotationRate = $currentJobs / (float) ($maxJobs-1); } $annotation->load('labels.label', 'labels.user'); diff --git a/resources/assets/js/videos/components/videoScreen.vue b/resources/assets/js/videos/components/videoScreen.vue index 89b6dc631..1acb99237 100644 --- a/resources/assets/js/videos/components/videoScreen.vue +++ b/resources/assets/js/videos/components/videoScreen.vue @@ -59,7 +59,8 @@ icon="fa-project-diagram" title="Finish and track the point annotation" v-on:click="finishTrackAnnotation" - :disabled="cantFinishTrackAnnotation" + :disabled="cantFinishTrackAnnotation || disableJobTracking" + :loading="disableJobTracking" > { + this.addCreatedAnnotation(res); + if (tmpAnnotation.track) { + // trackedAnnotationRate is the tracked annotation job occupancy rate + this.disableJobTracking = res.body.trackedAnnotationRate === 1; + } + }, (res) => { + handleErrorResponse(res); + this.disableJobTracking = res.status === 429; + }) .finally(() => { let index = this.annotations.indexOf(tmpAnnotation); if (index !== -1) { @@ -620,12 +633,14 @@ export default { handleSucceededTracking(event) { let annotation = this.annotations.find(a => a.id === event.annotation.id); if (annotation) { + this.disableJobTracking = false; annotation.finishTracking(event.annotation); } }, handleFailedTracking(event) { let annotation = this.annotations.find(a => a.id === event.annotation.id); if (annotation) { + this.disableJobTracking = false; annotation.failTracking(); } }, diff --git a/resources/views/videos/show/content.blade.php b/resources/views/videos/show/content.blade.php index b6cf7a816..9ee8d69d6 100644 --- a/resources/views/videos/show/content.blade.php +++ b/resources/views/videos/show/content.blade.php @@ -43,6 +43,7 @@ :show-prev-next="hasSiblingVideos" :has-error="hasError" :seeking="seeking" + :reached-tracked-annotation-limit="reachedTrackedAnnotationLimit" v-on:create-annotation="createAnnotation" v-on:track-annotation="trackAnnotation" v-on:split-annotation="splitAnnotation" From ad3f7b0b326dec89e9ec6e28521ace14fd5b2047 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Wed, 7 Feb 2024 07:36:00 +0100 Subject: [PATCH 2/4] Replace float by boolean Prevent rounding errors by using a boolean --- app/Http/Controllers/Api/VideoAnnotationController.php | 2 +- resources/assets/js/videos/videoContainer.vue | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Api/VideoAnnotationController.php b/app/Http/Controllers/Api/VideoAnnotationController.php index fc765ea30..ff6a17446 100644 --- a/app/Http/Controllers/Api/VideoAnnotationController.php +++ b/app/Http/Controllers/Api/VideoAnnotationController.php @@ -240,7 +240,7 @@ public function store(StoreVideoAnnotation $request) $queue = config('videos.track_object_queue'); Queue::pushOn($queue, new TrackObject($annotation, $request->user())); Cache::increment(TrackObject::getRateLimitCacheKey($request->user())); - $annotation->trackedAnnotationRate = $currentJobs / (float) ($maxJobs-1); + $annotation->trackingJobLimitReached = $currentJobs === ($maxJobs - 1); } $annotation->load('labels.label', 'labels.user'); diff --git a/resources/assets/js/videos/videoContainer.vue b/resources/assets/js/videos/videoContainer.vue index a4bf60b5a..6922bb3be 100644 --- a/resources/assets/js/videos/videoContainer.vue +++ b/resources/assets/js/videos/videoContainer.vue @@ -288,8 +288,7 @@ export default { .then((res) => { this.addCreatedAnnotation(res); if (tmpAnnotation.track) { - // trackedAnnotationRate is the tracked annotation job occupancy rate - this.disableJobTracking = res.body.trackedAnnotationRate === 1; + this.disableJobTracking = res.body.trackingJobLimitReached; } }, (res) => { handleErrorResponse(res); From 8022937fe0abe0cb9d18c6f7186281b1aac9c2c4 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Wed, 7 Feb 2024 07:58:45 +0100 Subject: [PATCH 3/4] Update test --- .../Api/VideoAnnotationControllerTest.php | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/php/Http/Controllers/Api/VideoAnnotationControllerTest.php b/tests/php/Http/Controllers/Api/VideoAnnotationControllerTest.php index 5fecf71da..24cf0c561 100644 --- a/tests/php/Http/Controllers/Api/VideoAnnotationControllerTest.php +++ b/tests/php/Http/Controllers/Api/VideoAnnotationControllerTest.php @@ -553,6 +553,36 @@ public function testStoreAndTrackRestrictRateLimit() } + public function testTrackingJobLimit() + { + Queue::fake(); + $this->beEditor(); + $res = $this + ->postJson("/api/v1/videos/{$this->video->id}/annotations", [ + 'shape_id' => Shape::pointId(), + 'label_id' => $this->labelRoot()->id, + 'points' => [[10, 11]], + 'frames' => [0.0], + 'track' => true, + ])->assertSuccessful(); + + $this->assertEquals(1, Cache::get(TrackObject::getRateLimitCacheKey($this->editor()))); + $this->assertFalse($res->json()['trackingJobLimitReached']); + + Cache::set(TrackObject::getRateLimitCacheKey($this->editor()), 9); + $res = $this + ->postJson("/api/v1/videos/{$this->video->id}/annotations", [ + 'shape_id' => Shape::pointId(), + 'label_id' => $this->labelRoot()->id, + 'points' => [[10, 11]], + 'frames' => [0.0], + 'track' => true, + ])->assertSuccessful(); + + $this->assertEquals(10, Cache::get(TrackObject::getRateLimitCacheKey($this->editor()))); + $this->assertTrue($res->json()['trackingJobLimitReached']); + } + public function testStoreWholeFrameAnnotation() { $this->beEditor(); From 3f53748bd1b8963fe81ebaea3f9acce36ab53f46 Mon Sep 17 00:00:00 2001 From: Leane Schlundt Date: Fri, 16 Feb 2024 09:20:04 +0100 Subject: [PATCH 4/4] Add missing return statement --- resources/assets/js/videos/videoContainer.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/assets/js/videos/videoContainer.vue b/resources/assets/js/videos/videoContainer.vue index 6922bb3be..bd59567ad 100644 --- a/resources/assets/js/videos/videoContainer.vue +++ b/resources/assets/js/videos/videoContainer.vue @@ -286,10 +286,10 @@ export default { return VideoAnnotationApi.save({id: this.videoId}, annotation) .then((res) => { - this.addCreatedAnnotation(res); if (tmpAnnotation.track) { this.disableJobTracking = res.body.trackingJobLimitReached; } + return this.addCreatedAnnotation(res); }, (res) => { handleErrorResponse(res); this.disableJobTracking = res.status === 429;