]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
dvr: Mark dvr entries as duplicates early to avoid logging.
authorE.Smith <31170571+azlm8t@users.noreply.github.com>
Fri, 21 Sep 2018 10:01:09 +0000 (11:01 +0100)
committerperexg <perex@perex.cz>
Wed, 26 Sep 2018 15:30:47 +0000 (17:30 +0200)
When autorecs are modified, we can do an async reschedule to ensure
recordings are correctly updated in case the autorecs interact.
However this can cause excessve logging in some circumstances.

Effectively, if there is a recording on disk and the autorec matches
the same recording in the future then the dvr_entry_create_by_autorec
can exit the "bcast" loop with no match at all (since entry on disk
frequently, but not always, has a null de_bcast).

This then means we create the dvr_entry, and, if the programme is
broadcasting now, then we immediately schedule a timer to start the
recording and log an info to say scheduled. We then immediately cancel
the recording, delete the dvr_entry, which then causes us do an async
schedule. But this async schedule realizes the autorec matches the
broadcast, so we go through the process again.

So, first stage is to delete the duplicate before we do any logging.
Unfortunately, due to the way dup matching works (only dvr entry vs
dvr entry, not vs bcast), we have to create a dvr_entry to do the
matching.

We also need to check duplicate event after it is inserted in to
de_global_link (to avoid assertion fault).

src/dvr/dvr_db.c

index 4c91620bce7c47004f3ff31137303dd1aba6c7cf..9a1232386c00a196c54514eec22cbf44e31489a7 100644 (file)
@@ -999,6 +999,26 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf, int clone)
 
   LIST_INSERT_HEAD(&dvrentries, de, de_global_link);
 
+  /* We do early duplicate checking. Otherwise we have the scenario
+   * where we have a dvr entry already on disk and an autorec creates
+   * an entry that matches the same programme details in the future (a
+   * repeat), but we still create a dvr_entry for that schedule and
+   * then immediately cancel it when the start time arrives. So,
+   * instead, we cancel that duplicate here and now.
+   *
+   * Note: this check has to be done _after_ insert in to de_global_link
+   * otherwise the destroy will abort.
+   */
+  if (_dvr_duplicate_event(de)) {
+      tvhtrace(LS_DVR, "Entry was duplicate for %s \"%s\" on \"%s\" start time %"PRId64", "
+          "scheduled for recording by \"%s\"",
+          idnode_uuid_as_str(&de->de_id, ubuf),
+          lang_str_get(de->de_title, NULL), DVR_CH_NAME(de),
+          (int64_t)de->de_start, de->de_creator ?: "");
+      dvr_entry_destroy(de, 1);
+      return NULL;
+  }
+
   if (de->de_channel && !de->de_dont_reschedule && !clone) {
     LIST_FOREACH(de2, &de->de_channel->ch_dvrs, de_channel_link)
       if(de2 != de &&