ATF safety
Jeff Mitchell
kde-dev at emailgoeshere.com
Thu Aug 17 12:44:33 UTC 2006
On Thursday 17 August 2006 02:08, Martin Aumueller wrote:
> If such a data corruption as some ATF users experienced happened to me, I'd
> be pissed. If turning this feature on would have been recommended by the
> program that caused the corruption, then doubly so. And even more so, if
> its developers continuously insist on it being safe despite I having proof
> of the opposite.
>
> Thus I suggest that we:
> - leave ATF disabled by default (probably forever)
Already done -- it was always off by default
> - remove any ATF recommendation in Amarok's config dialog
Also already done -- it just says "see Information" which has suitably obvious
warnings when clicked, with a PLEASE NOTE in big red letters.
> - stop insisting on its safety
Rest assured that I do take this corruption issue seriously. However, out of
all the various issues people have tried to pin on ATF there has been one
single issue that has been its fault -- this possible corner case that can
cause corruption, and the semantics of it are such that it is/was not likely
to happen to many people. I didn't plan for it because I thought taglib
would (as you recommended below) do file locking itself when it was writing
to a file. (Scott will be including a warning in the API docs of the next
version of TagLib explicitly stating that this is not the case).
All the other problems have been either taglib problems or someone else
changing my code and breaking it. Statistically speaking, ~jefferai is still
true :-)
> - and please try to make the code easier to understand more safe
? I don't think the code is that hard to understand. The process in
collectiondb for instance is more well documented than the much of the code
in amarok (see playlist.cpp, for instance), and the stuff in MetaBundle is
fairly straighforward. It's the algorithms that are hard to understand. And
we're always trying to make Amarok code more safe, aren't we...don't think I
haven't seen all your commits with the DeepCopys :-)
> * we should properly lock files that any Amarok process writes to
> (imagine a writable collection shared by several users - this is not only
> ATF related)
You can't do this, really. Scott and I had a very long discussion about it.
The problem is that flock and fcntl either don't work at all or are very
broken with files on network file systems, including NFS and Samba -- and
many, many people fall into this realm. So you have to get around this. You
can either try per-file lockfiles, which have lots of problems, or a global
lockfile, which also has problems, and doesn't allow for tag edits to be done
during a scan. I've discussed these options at length with Ian.
If you've seen my recent commits, you'll see I'm taking another approach --
adding the ability to a) find the instance of a running ScanController, and
b) pause the collectionscanner. So if you want to do tag editing, instead of
calling save() on the TagLib::File, you pass it into a function which checks
to see if a scanner is running. If so, you pause it, *wait for
confirmation*, do the write, then unpause it. If confirmation never comes,
you abort the tag writing. In addition, make sure when
amarokcollectionscanner is starting that no other processes are still
existing/running -- if so kill them, and if you can't (owned by another user,
or something else) then abort the scany. Crashing amarokapp with a running
scanner, then starting again was one reason the earlier problem could occur.
It is true that this won't handle the case of a networked filesystem with
multiple users all scanning at the same time, all with ATF turned on. There
really isn't a good way to handle this that I've seen, and it's not even
limited to ATF: you can run into the same problem if you and someone else
both try to update the tags of a file at the same time, even with ATF off.
Again, it's just a case where ATF makes it more likely because it's dealing
with so many files that first scan. So perhaps putting a warning in the
Information dialog about this case in the big red PLEASE NOTE section would
be good, telling users to scan from a single computer first (and then
possibly make the collection read-only for most users -- this is a good idea
even without ATF), or use a single computer's database, or etc.
> * do not make the behaviour of MetaBundle dependent on a
> process name (this is not very transparent to the caller, and some day, the
> process names might change and ATF will stop working)
And you suggest what, instead?
> * avoid code that needs triple WARNINGs in the comments (some setUniqueId
> that we have right now) - the code should be easily understandable by all
> developers
Yes. The warning is very easy to understand. It says, don't set the uniqueid
manually. Because you shouldn't be doing it unless you have a good reason --
you should be letting the scanner and database handle this work. This is not
a dangerous case, it's just not something you want to be doing unless you are
sure you are associating the correct UID with the correct MetaBundle. Parts
of the code that do this use this function.
> * limit the locations where meta data writes are triggered to as few
> places as possible and make it more clear when this happens
It already only happens in a few places. We just need to update all the
file->save() commands to use the new function.
> * make the ATF related parts of the MetaBundle API behave just as the
> rest of MetaBundle - Amarok developers are already familiar with this
> pattern: + a setUniqueId(QString) call that sets the unique id *only in
> memory* + a uniqueId() call for querying the unique id
That's already the current behavior.
> + write the unique id together with the other tags in
> MetaBundle::save() + perhaps provide a saveUniqueId() as an optimization
> for only writing the unique id to the file
Won't be necessary once the new save function is implemented -- everything
will use that.
> * with this changed API, the collection scanner could just call
> bundle->setUniqueId(somerandomid); bundle->saveUniqueId() - no need for
> special casing MetaBundle for processes having a certain name
No, you can't do that, first because the scanner has to use an ID if it
already exists, which requires a lot of various logic and taglib stuff, and
second because there are other times when UIDs can be set (or unset -- you
have to allow for stripping as well). These functions are implemented
outside the scanner, for instance through DCOP.
--Jeff
More information about the Amarok
mailing list