diff --git a/config/sample-development.engine.ini b/config/sample-development.engine.ini index e854ad7af1701ed789616a2188a5806103998dd0..ad0932818150d71ee437356af6359f321332a4e3 100644 --- a/config/sample-development.engine.ini +++ b/config/sample-development.engine.ini @@ -86,23 +86,14 @@ api_engine_store_health="http://localhost:8008/api/v1/source/health/${ENGINE_NUM # How often should the calendar be fetched in seconds. This determines the time of the last changes applied, before a specific show aired fetching_frequency=30 -# The scheduling window defines when the entries of each timeslot are queued for play-out in an ideal scenario. - -# The actual window (scheduling_window_start - scheduling_window_end) should be higher then the `fetching_frequency` to allow proper queuing. -# Otherwise the fetch might never hit the scheduling window, because the scheduling logic is attached to the fetching logic. -# -# Following operations are related to the scheduling window: -# -# - Deletion of timeslots: Those are only accepted until the **start** of the scheduling window -# - Update/Delete/Assignment of playlists and entries: Those are accepted until the **end** of the the scheduling window; existing queued entries are updated -# -# After the end of the scheduling window the pre-loading phase starts. -# Note, the values for windows is defined as a offset minus the actual start of the timeslot in seconds. -scheduling_window_start=120 -scheduling_window_end=15 +# The scheduling window defines when the entries of each timeslot are queued for play-out. The windows start at (timeslot.start - window_start) seconds +# and ends at (timeslot.end - window.end) seconds. Its also worth noting, that timeslots can only be deleted before the start of the window. +scheduling_window_start=60 +scheduling_window_end=60 # How many seconds before the actual schedule time the entry should be pre-rolled. Note to provide enough timeout for -# contents which take longer to load (big files, bad connectivity to streams etc.) -preload_offset=10 +# contents which take longer to load (big files, bad connectivity to streams etc.). If the planned start time is in +# the past the offset is ignored and the entry is played as soon as possible +preload_offset=15 # Sometimes it might take longer to get a stream connected. Here you can define a viable length. # But note, that this may affect the preloading time (see `preload_offset`), hence affecting the diff --git a/config/sample-docker.engine.ini b/config/sample-docker.engine.ini index 72973b2c47b41a76c7b16e013dc1f9e754803396..cb5991293d327e7551d24879eb18d797cb3ed03b 100644 --- a/config/sample-docker.engine.ini +++ b/config/sample-docker.engine.ini @@ -86,23 +86,14 @@ api_engine_store_health="http://127.0.0.1:8008/api/v1/source/health/${ENGINE_NUM # How often should the calendar be fetched in seconds. This determines the time of the last changes applied, before a specific show aired fetching_frequency=300 -# The scheduling window defines when the entries of each timeslot are queued for play-out in an ideal scenario. - -# The actual window (scheduling_window_start - scheduling_window_end) should be higher then the `fetching_frequency` to allow proper queuing. -# Otherwise the fetch might never hit the scheduling window, because the scheduling logic is attached to the fetching logic. -# -# Following operations are related to the scheduling window: -# -# - Deletion of timeslots: Those are only accepted until the **start** of the scheduling window -# - Update/Delete/Assignment of playlists and entries: Those are accepted until the **end** of the the scheduling window; existing queued entries are updated -# -# After the end of the scheduling window the pre-loading phase starts. -# Note, the values for windows is defined as a offset minus the actual start of the timeslot in seconds. -scheduling_window_start=600 +# The scheduling window defines when the entries of each timeslot are queued for play-out. The windows start at (timeslot.start - window_start) seconds +# and ends at (timeslot.end - window.end) seconds. Its also worth noting, that timeslots can only be deleted before the start of the window. +scheduling_window_start=60 scheduling_window_end=60 # How many seconds before the actual schedule time the entry should be pre-rolled. Note to provide enough timeout for -# contents which take longer to load (big files, bad connectivity to streams etc.) -preload_offset=30 +# contents which take longer to load (big files, bad connectivity to streams etc.). If the planned start time is in +# the past the offset is ignored and the entry is played as soon as possible +preload_offset=15 # Sometimes it might take longer to get a stream connected. Here you can define a viable length. # But note, that this may affect the preloading time (see `preload_offset`), hence affecting the diff --git a/config/sample-production.engine.ini b/config/sample-production.engine.ini index ddc7038456d198935294cd5cd199761685d4a65e..2a2f1becb1f0fe72d88485b6a1c0fe3819df04f5 100644 --- a/config/sample-production.engine.ini +++ b/config/sample-production.engine.ini @@ -86,23 +86,14 @@ api_engine_store_health="http://localhost:8008/api/v1/source/health/${ENGINE_NUM # How often should the calendar be fetched in seconds. This determines the time of the last changes applied, before a specific show aired fetching_frequency=300 -# The scheduling window defines when the entries of each timeslot are queued for play-out in an ideal scenario. - -# The actual window (scheduling_window_start - scheduling_window_end) should be higher then the `fetching_frequency` to allow proper queuing. -# Otherwise the fetch might never hit the scheduling window, because the scheduling logic is attached to the fetching logic. -# -# Following operations are related to the scheduling window: -# -# - Deletion of timeslots: Those are only accepted until the **start** of the scheduling window -# - Update/Delete/Assignment of playlists and entries: Those are accepted until the **end** of the the scheduling window; existing queued entries are updated -# -# After the end of the scheduling window the pre-loading phase starts. -# Note, the values for windows is defined as a offset minus the actual start of the timeslot in seconds. -scheduling_window_start=600 +# The scheduling window defines when the entries of each timeslot are queued for play-out. The windows start at (timeslot.start - window_start) seconds +# and ends at (timeslot.end - window.end) seconds. Its also worth noting, that timeslots can only be deleted before the start of the window. +scheduling_window_start=60 scheduling_window_end=60 # How many seconds before the actual schedule time the entry should be pre-rolled. Note to provide enough timeout for -# contents which take longer to load (big files, bad connectivity to streams etc.) -preload_offset=30 +# contents which take longer to load (big files, bad connectivity to streams etc.). If the planned start time is in +# the past the offset is ignored and the entry is played as soon as possible +preload_offset=15 # Sometimes it might take longer to get a stream connected. Here you can define a viable length. # But note, that this may affect the preloading time (see `preload_offset`), hence affecting the diff --git a/docs/engine-features.md b/docs/engine-features.md index d6d291428ddc2f5bc41ad97fc8f68e0924352c2c..724cdc1efc00967f0bfbf696e2bf556045f97a8a 100644 --- a/docs/engine-features.md +++ b/docs/engine-features.md @@ -66,7 +66,7 @@ point in time and the involved phase before: - **Scheduling Window**: Within the scheduling window any commands for controlling the mixer of the soundsystem are prepared and queued. - Until the start of the window, timeslot can be added or removed via external API Endpoints + Only until the start of the window, timeslots can be updated or removed via external API Endpoints (e.g. using Steering or Dashboard). Until here any changes on the timeslot itself will be reflected in the actual play-out. This only affects the start and end time of the "timeslot" itself. It does not involve related playlists and their entries. Those can still be modified after the @@ -74,7 +74,8 @@ point in time and the involved phase before: The start and the end of the window is defined by the start of the timeslot minus a configured amount of seconds (see `scheduling_window_start` and `scheduling_window_end` - in `engine.ini`). + in `engine.ini`). The actual start of the window is calcuated by (timeslot start - window start) + and the end by (timeslot end - window end) During the scheduling window, the external API Endpoints are pulled continiously, to check for updated timeslots and related playlists. Also, any changes to playlists and @@ -88,8 +89,13 @@ point in time and the involved phase before: the scheduled play-out time to avoid any delays in timing. Set the maximum time reserved for pre-loading in your configuration (compare `preload_offset`in `engine.ini`). - > Important: The offset should not exceed the time between the end of the scheduling-window and the - start of the actual timeslot playout. + If there is not enough time to reserve the given amount of time for preloading (i.e. some entry + should have started in the past already) the offset is ignored and the entry is played as soon as possible. + + > Important: To ensure proper timings, the offset should not exceed the time between the start of + the scheduling-window and the start of the actual timeslot playout. Practically, of course there + are scenario where playout start later than planned e.g. during startup of the engine during a timeslot + or due to some severe connectivity issues to some external stream. - **Play-out**: Finally the actual play-out is happening. The faders of the virtual mixers are pushed all the way up, as soon it's "time to play" for one of the pre-loaded entries. diff --git a/src/scheduling/scheduler.py b/src/scheduling/scheduler.py index c50b888c98838ed48ff4bcadb4f128c7b27f5764..b32b3f3097b40aacc1a5abfc37815931df86f3c5 100644 --- a/src/scheduling/scheduler.py +++ b/src/scheduling/scheduler.py @@ -35,7 +35,6 @@ from src.core.resources import ResourceClass, ResourceUtil from src.scheduling.utils import TimeslotRenderer from src.scheduling.programme import ProgrammeService -from src.scheduling.models import Playlist class AuraScheduler(threading.Thread): @@ -357,9 +356,19 @@ class AuraScheduler(threading.Thread): def filter_scheduling_window(self, timeslots): """ - Ignore timeslots which are beyond the scheduling window. The end of the scheduling window - is defined by the config option `scheduling_window_end`. This value defines the seconds - minus the actual start time of the timeslot. + Ignore timeslots which are before the start of scheduling window (start of timeslot - `scheduling_window_start`) + or after the end of the scheduling window (end of timeslot -`scheduling_window_end`). + + Before the scheduling window: + - Timeslots can still be deleted in Steering and the playout will respect this + + During the scheduling window: + - Timeslots and it's playlists are queued as timed commands + + After the scheduling window: + - Such timeslots are ignored, because it doesn't make sense anymore to schedule them before the next + timeslot starts + """ if not timeslots: return timeslots @@ -368,9 +377,9 @@ class AuraScheduler(threading.Thread): len_before = len(timeslots) window_start = self.config.get("scheduling_window_start") window_end = self.config.get("scheduling_window_end") - timeslots = list(filter(lambda s: (s.start_unix - window_end) > now_unix and (s.start_unix - window_start) < now_unix, timeslots)) + timeslots = list(filter(lambda t: (t.start_unix - window_start) < now_unix and now_unix < (t.end_unix - window_end), timeslots)) len_after = len(timeslots) - self.logger.info("For now, skipped %s future timeslot(s) which are out of the scheduling window (T-%ss to T-%ss)" % ((len_before - len_after), window_start, window_end)) + self.logger.info("For now, skipped %s future timeslot(s) which are out of the scheduling window (T¹-%ss to T²-%ss)" % ((len_before - len_after), window_start, window_end)) return timeslots