Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
LOFAR
Manage
Activity
Members
Labels
Plan
Issues
Wiki
Jira issues
Open Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
RadioObservatory
LOFAR
Commits
5fb5ac97
Commit
5fb5ac97
authored
4 years ago
by
Jorrit Schaap
Browse files
Options
Downloads
Patches
Plain Diff
TMSS-190
: first step towards stategy pattern
parent
ce176ef1
No related branches found
No related tags found
1 merge request
!252
Resolve TMSS-190
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
SAS/TMSS/services/scheduling/lib/dynamic_scheduling.py
+58
-31
58 additions, 31 deletions
SAS/TMSS/services/scheduling/lib/dynamic_scheduling.py
SAS/TMSS/src/tmss/exceptions.py
+4
-0
4 additions, 0 deletions
SAS/TMSS/src/tmss/exceptions.py
with
62 additions
and
31 deletions
SAS/TMSS/services/scheduling/lib/dynamic_scheduling.py
+
58
−
31
View file @
5fb5ac97
...
@@ -43,7 +43,9 @@ from lofar.sas.tmss.tmss.tmssapp.conversions import LOFAR_CENTER_OBSERVER, Time,
...
@@ -43,7 +43,9 @@ from lofar.sas.tmss.tmss.tmssapp.conversions import LOFAR_CENTER_OBSERVER, Time,
def
get_schedulable_scheduling_units
()
->
[
models
.
SchedulingUnitBlueprint
]:
def
get_schedulable_scheduling_units
()
->
[
models
.
SchedulingUnitBlueprint
]:
'''
get a list of all schedulable scheduling_units
'''
'''
get a list of all schedulable scheduling_units
'''
defined_independend_subtasks
=
models
.
Subtask
.
independent_subtasks
().
filter
(
state__value
=
'
defined
'
)
defined_independend_subtasks
=
models
.
Subtask
.
independent_subtasks
().
filter
(
state__value
=
'
defined
'
)
scheduling_units
=
models
.
SchedulingUnitBlueprint
.
objects
.
filter
(
id__in
=
defined_independend_subtasks
.
values
(
'
task_blueprint__scheduling_unit_blueprint_id
'
).
distinct
()).
all
()
defined_independend_subtask_ids
=
defined_independend_subtasks
.
values
(
'
task_blueprint__scheduling_unit_blueprint_id
'
).
distinct
().
all
()
# TODO: prefetch related models, like draft, spec, templates, etc
scheduling_units
=
models
.
SchedulingUnitBlueprint
.
objects
.
filter
(
id__in
=
defined_independend_subtask_ids
).
all
()
return
[
su
for
su
in
scheduling_units
if
su
.
status
==
'
schedulable
'
]
return
[
su
for
su
in
scheduling_units
if
su
.
status
==
'
schedulable
'
]
...
@@ -56,37 +58,62 @@ def get_scheduled_scheduling_units(lower:datetime=None, upper:datetime=None) ->
...
@@ -56,37 +58,62 @@ def get_scheduled_scheduling_units(lower:datetime=None, upper:datetime=None) ->
scheduled_subtasks
=
scheduled_subtasks
.
filter
(
start_time__lte
=
upper
)
scheduled_subtasks
=
scheduled_subtasks
.
filter
(
start_time__lte
=
upper
)
return
list
(
models
.
SchedulingUnitBlueprint
.
objects
.
filter
(
id__in
=
scheduled_subtasks
.
values
(
'
task_blueprint__scheduling_unit_blueprint_id
'
).
distinct
()).
all
())
return
list
(
models
.
SchedulingUnitBlueprint
.
objects
.
filter
(
id__in
=
scheduled_subtasks
.
values
(
'
task_blueprint__scheduling_unit_blueprint_id
'
).
distinct
()).
all
())
def
can_run_within_timewindow
(
scheduling_unit
:
models
.
SchedulingUnitBlueprint
,
lower_bound
:
datetime
,
upper_bound
:
datetime
)
->
bool
:
constraints_template
=
scheduling_unit
.
draft
.
scheduling_constraints_template
if
constraints_template
.
name
==
'
constraints
'
:
if
constraints_template
.
version
==
1
:
return
can_run_within_timewindow_template_constraints_1
(
scheduling_unit
,
lower_bound
,
upper_bound
)
raise
UnknownTemplateException
(
"
Cannot check if scheduling_unit id=%s can run between
'
%s
'
and
'
%s
'
, because we have no constraint solver for scheduling constraints template
'
%s
'
version=%s
"
%
(
scheduling_unit
.
id
,
lower_bound
,
upper_bound
,
constraints_template
.
name
,
constraints_template
.
version
))
def
can_run_within_timewindow_template_constraints_1
(
scheduling_unit
:
models
.
SchedulingUnitBlueprint
,
lower_bound
:
datetime
,
upper_bound
:
datetime
)
->
bool
:
constraints
=
scheduling_unit
.
draft
.
scheduling_constraints_doc
return
can_run_within_timewindow_template_constraints_1_daily
(
scheduling_unit
,
lower_bound
,
upper_bound
)
def
can_run_within_timewindow_template_constraints_1_daily
(
scheduling_unit
:
models
.
SchedulingUnitBlueprint
,
lower_bound
:
datetime
,
upper_bound
:
datetime
)
->
bool
:
constraints
=
scheduling_unit
.
draft
.
scheduling_constraints_doc
if
not
(
constraints
[
'
daily
'
][
'
require_day
'
]
and
constraints
[
'
daily
'
][
'
require_night
'
]):
# no day/night restrictions, can run any time
return
True
if
constraints
[
'
daily
'
][
'
require_day
'
]
or
constraints
[
'
daily
'
][
'
require_night
'
]:
# TODO: TMSS-254 and TMSS-255
# TODO: take avoid_twilight into account
# Please note that this first crude proof of concept treats sunset/sunrise as 'events',
# whereas in our definition they are transition periods. See: TMSS-435
# Ugly code. Should be improved. Works for demo.
# create a series of timestamps in the window of opportunity, and evaluate of there are all during day or night
possible_start_time
=
get_first_possible_start_time
(
scheduling_unit
,
lower_bound
)
possible_stop_time
=
possible_start_time
+
scheduling_unit
.
duration
timestamps
=
[
possible_start_time
]
while
timestamps
[
-
1
]
<
possible_stop_time
-
timedelta
(
hours
=
8
):
timestamps
.
append
(
timestamps
[
-
1
]
+
timedelta
(
hours
=
8
))
timestamps
.
append
(
possible_stop_time
)
if
constraints
[
'
daily
'
][
'
require_night
'
]
and
all
(
LOFAR_CENTER_OBSERVER
.
is_night
(
timestamp
)
for
timestamp
in
timestamps
):
return
True
if
constraints
[
'
daily
'
][
'
require_day
'
]
and
all
(
not
LOFAR_CENTER_OBSERVER
.
is_night
(
timestamp
)
for
timestamp
in
timestamps
):
return
True
return
False
def
filter_scheduling_units_using_constraints
(
scheduling_units
:[
models
.
SchedulingUnitBlueprint
],
lower_bound_start_time
:
datetime
,
upper_bound_stop_time
:
datetime
)
->
[
models
.
SchedulingUnitBlueprint
]:
def
filter_scheduling_units_using_constraints
(
scheduling_units
:[
models
.
SchedulingUnitBlueprint
],
lower_bound_start_time
:
datetime
,
upper_bound_stop_time
:
datetime
)
->
[
models
.
SchedulingUnitBlueprint
]:
filtered_scheduling_units
=
[]
'''
return the schedulable scheduling_units which for which the constraints are
'
go
'
within the given timewindow
'''
for
scheduling_unit
in
scheduling_units
:
constraints
=
scheduling_unit
.
draft
.
scheduling_constraints_doc
def
can_run_within_timewindow_no_exception
(
scheduling_unit
,
lower_bound
,
upper_bound
):
try
:
if
not
constraints
:
return
can_run_within_timewindow
(
scheduling_unit
,
lower_bound
,
upper_bound
)
# accept any scheduling_unit with no constraints
except
UnknownTemplateException
as
e
:
filtered_scheduling_units
.
append
(
scheduling_unit
)
logger
.
warning
(
e
)
continue
return
False
# TODO: use factory to get filter function based on scheduling_constraints_template and/or constraint name
return
[
sub
for
sub
in
scheduling_units
# for now, assume there is only one template, allowing straightforward filtering.
if
can_run_within_timewindow_no_exception
(
sub
,
lower_bound_start_time
,
upper_bound_stop_time
)]
if
not
(
constraints
[
'
daily
'
][
'
require_day
'
]
and
constraints
[
'
daily
'
][
'
require_night
'
]):
filtered_scheduling_units
.
append
(
scheduling_unit
)
elif
constraints
[
'
daily
'
][
'
require_day
'
]
or
constraints
[
'
daily
'
][
'
require_night
'
]:
# TODO: take avoid_twilight into account
# Ugly code. Should be improved. Works for demo.
# create a series of timestamps in the window of opportunity, and evaluate of there are all during day or night
possible_start_time
=
get_first_possible_start_time
(
scheduling_unit
,
lower_bound_start_time
)
possible_stop_time
=
possible_start_time
+
scheduling_unit
.
duration
timestamps
=
[
possible_start_time
]
while
timestamps
[
-
1
]
<
possible_stop_time
-
timedelta
(
hours
=
8
):
timestamps
.
append
(
timestamps
[
-
1
]
+
timedelta
(
hours
=
8
))
timestamps
.
append
(
possible_stop_time
)
if
constraints
[
'
daily
'
][
'
require_night
'
]
and
all
(
LOFAR_CENTER_OBSERVER
.
is_night
(
timestamp
)
for
timestamp
in
timestamps
):
filtered_scheduling_units
.
append
(
scheduling_unit
)
elif
constraints
[
'
daily
'
][
'
require_day
'
]
and
all
(
not
LOFAR_CENTER_OBSERVER
.
is_night
(
timestamp
)
for
timestamp
in
timestamps
):
filtered_scheduling_units
.
append
(
scheduling_unit
)
return
filtered_scheduling_units
def
find_best_next_schedulable_unit
(
lower_bound_start_time
:
datetime
=
None
,
upper_bound_stop_time
:
datetime
=
None
,
scheduling_units
:[
models
.
SchedulingUnitBlueprint
]
=
None
)
->
(
models
.
SchedulingUnitBlueprint
,
datetime
):
def
find_best_next_schedulable_unit
(
lower_bound_start_time
:
datetime
=
None
,
upper_bound_stop_time
:
datetime
=
None
,
scheduling_units
:[
models
.
SchedulingUnitBlueprint
]
=
None
)
->
(
models
.
SchedulingUnitBlueprint
,
datetime
):
"""
"""
...
...
This diff is collapsed.
Click to expand it.
SAS/TMSS/src/tmss/exceptions.py
+
4
−
0
View file @
5fb5ac97
...
@@ -22,3 +22,7 @@ class SubtaskSchedulingException(SchedulingException):
...
@@ -22,3 +22,7 @@ class SubtaskSchedulingException(SchedulingException):
class
TaskSchedulingException
(
SchedulingException
):
class
TaskSchedulingException
(
SchedulingException
):
pass
pass
class
UnknownTemplateException
(
TMSSException
):
'''
raised when TMSS trying to base its processing routines on the chosen template, but this specific template is unknown.
'''
pass
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment