Skip to content

Commit

Permalink
Merge pull request #25 from uclouvain/0.6
Browse files Browse the repository at this point in the history
[0.6] Display progressbar in red when task in error
  • Loading branch information
albrugnetti authored Aug 9, 2023
2 parents c3ed769 + b292807 commit 9743a4d
Show file tree
Hide file tree
Showing 11 changed files with 14,543 additions and 17,400 deletions.
26 changes: 25 additions & 1 deletion frontend/components/AsyncTask.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* The core business involves the administration of students, teachers,
* courses, programs and so on.
*
* Copyright (C) 2015-2021 Université catholique de Louvain (http://www.uclouvain.be)
* Copyright (C) 2015-2023 Université catholique de Louvain (http://www.uclouvain.be)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -48,6 +48,16 @@ const doneAsyncTaskData = {
startedAt: Date.now().toString(),
completedAt: Date.now().toString(),
};
const errorAsyncTaskData = {
uuid: '1445bb87-4965-44a5-9889-1b82f49166ec',
name: 'errorAsyncTaskData',
description: '',
state: 'ERROR',
progression: 0,
createdAt: Date.now().toString(),
startedAt: Date.now().toString(),
completedAt: Date.now().toString(),
};

describe('component lifecycle', () => {
it('should mount', () => {
Expand Down Expand Up @@ -98,3 +108,17 @@ describe('async task display', () => {
expect(textSpan.classes()).not.toContain('font-bold');
});
});

describe('async task display error', () => {
it('changes when task is in error', () => {
const wrapper = mount(AsyncTask, {
props: {
...errorAsyncTaskData,
},
});

// progress bar must be in red
const progressBar = wrapper.find('.progress-bar');
expect(progressBar.classes()).toContain('progress-bar-danger');
});
});
21 changes: 16 additions & 5 deletions frontend/components/AsyncTask.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
- The core business involves the administration of students, teachers,
- courses, programs and so on.
-
- Copyright (C) 2015-2021 Université catholique de Louvain (http://www.uclouvain.be)
- Copyright (C) 2015-2023 Université catholique de Louvain (http://www.uclouvain.be)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -44,14 +44,19 @@
<div class="progress">
<div
class="progress-bar progress-bar-striped"
:class="{ 'active': isProcessing, 'progress-bar-success': isDone }"
:class="{ 'active': isProcessing, 'progress-bar-success': isDone, 'progress-bar-danger': isInError }"
role="progressbar"
:aria-valuenow="progression"
:aria-valuenow="computedProgression"
aria-valuemin="0"
aria-valuemax="100"
:style="{ width: progression + '%' }"
:style="{ width: computedProgression + '%' }"
>
{{ progression }}%
<template v-if="isInError">
{{ $t('async_task.error_task') }}
</template>
<template v-if="!isInError">
{{ computedProgression }}%
</template>
</div>
</div>
</div>
Expand Down Expand Up @@ -106,6 +111,12 @@ export default defineComponent({
isDone: function () {
return this.state === 'DONE';
},
isInError: function () {
return this.state === 'ERROR';
},
computedProgression: function () {
return (this.isInError) ? 100: this.progression;
},
asyncDate: function () {
if (this.completedAt) {
return `${this.$t('async_task.completed_at')} : ${this.completedAt}`;
Expand Down
1 change: 1 addition & 0 deletions frontend/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ export default {
created_at: 'created at',
started_at: 'started at',
completed_at: 'completed at',
error_task: 'An error occurred while running task',
},
};
1 change: 1 addition & 0 deletions frontend/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ export default {
created_at: 'demandée le',
started_at: 'débutée le',
completed_at: 'terminée le',
error_task: 'Une erreur s\'est produite lors de l\'exécution de la tâche.',
},
};
Empty file.
Empty file.
63 changes: 63 additions & 0 deletions osis_async/management/commands/check_async_task_ttl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# ##############################################################################
#
# OSIS stands for Open Student Information System. It's an application
# designed to manage the core business of higher education institutions,
# such as universities, faculties, institutes and professional schools.
# The core business involves the administration of students, teachers,
# courses, programs and so on.
#
# Copyright (C) 2015-2023 Université catholique de Louvain (http://www.uclouvain.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of this license - GNU General Public License - is available
# at the root of the source code of this program. If not,
# see http://www.gnu.org/licenses/.
#
# ##############################################################################
import datetime
import logging

from django.conf import settings
from django.core.management.base import BaseCommand
from django.db.models import F, ExpressionWrapper, DateTimeField
from osis_async.models.task import AsyncTask
from osis_async.models.enums import TaskState


logger = logging.getLogger(settings.DEFAULT_LOGGER)


class Command(BaseCommand):
help = "Set running tasks out of date (TTL expired) in error"

def handle(self, *args, **options):
logger.info(f"[OSIS-Async] Check async task TTL.")

out_of_date_tasks = AsyncTask.objects.filter(
started_at__isnull=False,
state=TaskState.PROCESSING.name
).annotate(
expiration_date=ExpressionWrapper(
F('started_at') + datetime.timedelta(seconds=60) * F('time_to_live'),
output_field=DateTimeField(),
)
).filter(
expiration_date__lt=datetime.datetime.today()
)

for out_of_date_task in out_of_date_tasks:
logger.warning(f"[OSIS-Async] Tasks ({out_of_date_task.uuid}) - '{out_of_date_task.name}' out of date. "
f"Cause: TTL Reached")
out_of_date_task.state = TaskState.ERROR.name
out_of_date_task.progression = 0
out_of_date_task.completed_at = datetime.datetime.today()
out_of_date_task.save()
Loading

0 comments on commit 9743a4d

Please sign in to comment.