|
43 | 43 | from readthedocs.core.symlink import PublicSymlink, PrivateSymlink
|
44 | 44 | from readthedocs.core.utils import send_email, broadcast
|
45 | 45 | from readthedocs.doc_builder.config import load_yaml_config
|
| 46 | +from readthedocs.doc_builder.constants import DOCKER_LIMITS |
46 | 47 | from readthedocs.doc_builder.environments import (LocalEnvironment,
|
47 | 48 | DockerEnvironment)
|
48 | 49 | from readthedocs.doc_builder.exceptions import BuildEnvironmentError
|
@@ -1011,22 +1012,44 @@ def sync_callback(_, version_pk, commit, *args, **kwargs):
|
1011 | 1012 |
|
1012 | 1013 | @app.task()
|
1013 | 1014 | def finish_inactive_builds():
|
1014 |
| - delta = datetime.timedelta(hours=1, minutes=30) |
| 1015 | + """ |
| 1016 | + Finish inactive builds. |
| 1017 | +
|
| 1018 | + A build is consider inactive if it's not in ``FINISHED`` state and it has been |
| 1019 | + "running" for more time that the allowed one (``Project.container_time_limit`` |
| 1020 | + or ``DOCKER_LIMITS['time']`` plus a 20% of it). |
| 1021 | +
|
| 1022 | + These inactive builds will be marked as ``success`` and ``FINISHED`` with an |
| 1023 | + ``error`` to be communicated to the user. |
| 1024 | + """ |
| 1025 | + time_limit = int(DOCKER_LIMITS['time'] * 1.2) |
| 1026 | + delta = datetime.timedelta(minutes=time_limit) |
1015 | 1027 | query = (~Q(state=BUILD_STATE_FINISHED) &
|
1016 | 1028 | Q(date__lte=datetime.datetime.now() - delta))
|
1017 | 1029 |
|
| 1030 | + builds_finished = 0 |
1018 | 1031 | builds = Build.objects.filter(query)[:50]
|
1019 | 1032 | for build in builds:
|
| 1033 | + |
| 1034 | + if build.project.container_time_limit: |
| 1035 | + custom_delta = datetime.timedelta( |
| 1036 | + minutes=int(build.project.container_time_limit)) |
| 1037 | + if build.date + custom_delta > datetime.datetime.now(): |
| 1038 | + # Do not mark as FINISHED builds with a custom time limit that wasn't |
| 1039 | + # expired yet (they are still building the project version) |
| 1040 | + continue |
| 1041 | + |
1020 | 1042 | build.success = False
|
1021 | 1043 | build.state = BUILD_STATE_FINISHED
|
1022 |
| - build.error = ( |
| 1044 | + build.error = _( |
1023 | 1045 | 'This build was terminated due to inactivity. If you '
|
1024 | 1046 | 'continue to encounter this error, file a support '
|
1025 | 1047 | 'request with and reference this build id ({0}).'.format(build.pk)
|
1026 | 1048 | )
|
1027 | 1049 | build.save()
|
| 1050 | + builds_finished += 1 |
1028 | 1051 |
|
1029 | 1052 | log.info(
|
1030 | 1053 | 'Builds marked as "Terminated due inactivity": %s',
|
1031 |
| - builds.count(), |
| 1054 | + builds_finished, |
1032 | 1055 | )
|
0 commit comments