Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: MythTV: Dev

Convoluted program expiry and deletion

 

 

MythTV dev RSS feed   Index | Next | Previous | View Threaded


ian at beware

May 10, 2012, 6:55 AM

Post #1 of 4 (330 views)
Permalink
Convoluted program expiry and deletion

I have been trying to debug the program deletion code (Ticket #10704).
However, this post is really about how convoluted the program deletion
actually has become and some suggestions for small improvement.

As I was debugging I took some notes about how the process works (or
doesn't). It looks to me like the "Change delete behaviour so that we
always use the deleted recording group" commit
f78f9992d754390fa42f109e5139b8eaf224d076, has left some artefacts which
may have made sense once, but now seem pointless. The whole process
seems excessively complicated.

Here are the notes I made. Sorry that they are long. That is the point
really. The following is just the main path, not all the branches to
deal with corner cases etc. Also this analysis stops at the point where
the actual DeleteThread is started (and so doesn't address the "slow
truncate" code).

The processing bounces between threads, processes (and hosts).

On Master
Autoexpire thread runs continuously sleeping periodically:
1. Autoexpire::RunExpirer(): loops every 60 seconds. Call
UpdateDontExpireSet(). If time to run autoexpire has expired, check
programs in the deleted group and deletes the files and database
entries (if they have aged enough, depending on settings) and
eventually calls ExpireRecordings().

2. Autoexpire::ExpireRecordings(): constructs expireList (an ordered
list of expirable programs)

3. Autoexpire::ExpireRecordings(): loops through expireList, pushing
programs onto deleteList until enough free space is predicted to
occur when the programs are eventually deleted.

4. Autoexpire::ExpireRecordings(): calls SendDeleteMessages()

5. AutoExpire::SendDeleteMessages(): raise an AUTO_EXPIRE event for
each program and record a key for the program in deleted_set.

Main event handler
6. MainServer::customEvent(): AUTO_EXPIRE events cause call to DoHandleDeleteRecording()

7. MainServer::DoHandleDeleteRecording(): justexpire is set because
programs are not yet in "Deleted" group.

8. MainServer::DoHandleDeleteRecording(): If on a master backend
signal the slave to delete the program with DELETE_RECORDINGS commands.

On slave

9. MainServer::HandleDeleteRecording(): calls DoHandleDeleteRecording()

10. MainServer::DoHandleDeleteRecording(): justexpire is still true

11. MainServer::DoHandleDeleteRecording(): put program in "Deleted"
group and set autoexpire to 9999 reply to master and return. These
programs should be (really) deleted the next time the autoexpire thread runs.

Actual deletion of the files and database entries for the deleted
programs occurs as follows:

On Master

12. AutoExpire::ExpireQuickDeleted() or ExpireOldDeleted(): Calls
FillDBOrdered to create an expireList.

13. AutoExpire::FillDBOrdered(): queries the database to get all the
programs in the "Deleted" group, but then calls IsInDontExpireSet()
to determine whether to skip the program.

14. AutoExpire::IsInDontExpireSet(): checks if key is in dont_expire_set

15. AutoExpire::ExpireQuickDeleted() or ExpireOldDeleted(): Calls SendDeleteMessages()

16. AutoExpire::SendDeleteMessages(): raise an AUTO_EXPIRE event for
each program and record a key for the program in deleted_set.

Main event handler
17. MainServer::customEvent(): AUTO_EXPIRE events cause call to DoHandleDeleteRecording()

18. MainServer::DoHandleDeleteRecording(): justexpire is false this
time through because the program is in the "Deleted" group.

19. MainServer::DoHandleDeleteRecording(): If on a master backend
signal the slave to delete the program with DELETE_RECORDINGS commands.

On slave

20. MainServer::HandleDeleteRecording(): calls DoHandleDeleteRecording()

21. MainServer::DoHandleDeleteRecording(): justexpire is still false and
we are not a master so fall through and start the actual delete thread.


Notes:

a) This two phase process of sticking the programs in the "Deleted"
group, then actually deleting the file and removing the database
entry some time later is broken when the master and slave are the
same on the same hostname. In this case MainServer::DoHandleDeleteRecording()
after testing if the recording hostname is the same as the master
hostname execution falls through to start the delete thread and
programs are deleted without ever being stuck in the "Deleted"
recording group as is apparently intended.

b) The deletion of programs in the "Deleted" group in step 1 is broken.
This is because:

The dont_expire_set referred to in step 14 is initialized from
deleted_set when UpdateDontExpireSet() is run in step 1 above.

The deleted_set is is added to in step 5, above, but entries are
never removed. In fact as far as I can understand, deleted_set is
never initialised either. So programs are never actually deleted.

This is Ticket #10704

c) There is no point in going to the slave for steps 9-11. This is just
a database update and all the information needed is on the master.

The code to go to the slave the second time (steps 20,21) seems a bit
strange. Go to the slave if it is up, otherwise try and delete it from
the master. Why not "if the recording is available on the master,
delete it, otherwise go to the slave to delete it"?

d) It would be nice to have some consistent terminology/naming.
eg DoHandleDeleteRecording, the first time through is actually not
deleting anything it is expiring the recording. Even the second time
through it starts a new DeleteThread to do the deletion, so
DoHandleDeleteRecording is pretty much a misnomer.

I hope this is some use to someone. Is there some place where internals
are documented and stuff like this could be placed?

Regards,
Ian


--
Ian Dall <ian [at] beware>

_______________________________________________
mythtv-dev mailing list
mythtv-dev [at] mythtv
http://www.mythtv.org/mailman/listinfo/mythtv-dev


mtdean at thirdcontact

May 10, 2012, 7:37 AM

Post #2 of 4 (320 views)
Permalink
Re: Convoluted program expiry and deletion [In reply to]

On 05/10/2012 09:55 AM, Ian Dall wrote:
> I have been trying to debug the program deletion code (Ticket #10704).
> However, this post is really about how convoluted the program deletion
> actually has become and some suggestions for small improvement.
>
> As I was debugging I took some notes about how the process works (or
> doesn't). It looks to me like the "Change delete behaviour so that we
> always use the deleted recording group" commit
> f78f9992d754390fa42f109e5139b8eaf224d076, has left some artefacts which
> may have made sense once, but now seem pointless. The whole process
> seems excessively complicated.

We appreciate the work you've done on tracking the existing code, but I
thought I'd just send a quick e-mail to give you a bit of info on why
we're where we are.

In the past, we had an option that allowed users to decide whether to
delete recordings immediately or to just place them in the Deleted
recording group so that they would later be expired when the file system
was full. Recently, we also had a "user-experience" issue that cropped
up due to attempts to prevent problems like orphaned files and/or
metadata, where if a recording was in use for anything--including
preview creation (which is often run immediately after exiting a
recording--deletion wasn't permitted. This meant that in many cases,
users would attempt to delete a recording and be told they couldn't
because the recording was in use (meaning they'd have to wait until
later and try again).

Therefore, (very) shortly before the release of 0.25, we decided to
switch the code to always use the "delete to Deleted recording group"
approach (which can be done, even when the recording is in use). This
solved the major user-visible issue, but--as you've noticed--means that
our deletion code has a lot of unnecessary complexity.

The plan is to simplify the code, but we didn't have time to do so (let
alone time for fully testing a complex change) before 0.25 release.
Your e-mail should be very useful in helping to do so, once we get a
chance to work on it.

Mike
_______________________________________________
mythtv-dev mailing list
mythtv-dev [at] mythtv
http://www.mythtv.org/mailman/listinfo/mythtv-dev


ian at beware

May 10, 2012, 3:56 PM

Post #3 of 4 (309 views)
Permalink
Re: Convoluted program expiry and deletion [In reply to]

On Thu, 2012-05-10 at 10:37 -0400, Michael T. Dean wrote:
> On 05/10/2012 09:55 AM, Ian Dall wrote:
> > I have been trying to debug the program deletion code (Ticket #10704).
> > However, this post is really about how convoluted the program deletion
> > actually has become and some suggestions for small improvement.
> >
> > As I was debugging I took some notes about how the process works (or
> > doesn't). It looks to me like the "Change delete behaviour so that we
> > always use the deleted recording group" commit
> > f78f9992d754390fa42f109e5139b8eaf224d076, has left some artefacts which
> > may have made sense once, but now seem pointless. The whole process
> > seems excessively complicated.
>
> We appreciate the work you've done on tracking the existing code, but I
> thought I'd just send a quick e-mail to give you a bit of info on why
> we're where we are.
>
> [..]

Noted.

> The plan is to simplify the code, but we didn't have time to do so (let
> alone time for fully testing a complex change) before 0.25 release.

I am happy to take this on if it doesn't step on anyone's toes. I think
understanding the existing code was the hardest bit. After that the
places to clean up seem relatively obvious.

Regards,
Ian

--
Ian Dall <ian [at] beware>

_______________________________________________
mythtv-dev mailing list
mythtv-dev [at] mythtv
http://www.mythtv.org/mailman/listinfo/mythtv-dev


ian at beware

May 16, 2012, 2:45 AM

Post #4 of 4 (278 views)
Permalink
Re: Convoluted program expiry and deletion [In reply to]

Minor correction.

On Thu, 2012-05-10 at 23:25 +0930, Ian Dall wrote:
> [..]

> Main event handler
> 6. MainServer::customEvent(): AUTO_EXPIRE events cause call to DoHandleDeleteRecording()

with 'expirer' argument set to true.

> 7. MainServer::DoHandleDeleteRecording(): justexpire is set because
> programs are not yet in "Deleted" group.

This should be justexpire is set to false because expirer is true.

Ian

--
Ian Dall <ian [at] beware>

_______________________________________________
mythtv-dev mailing list
mythtv-dev [at] mythtv
http://www.mythtv.org/mailman/listinfo/mythtv-dev

MythTV dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.