[banshee] LibraryWatcher: avoid importing incomplete files
- From: Bertrand Lorentz <blorentz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [banshee] LibraryWatcher: avoid importing incomplete files
- Date: Wed, 22 Feb 2012 20:11:49 +0000 (UTC)
commit cf2346be3df5ec3f196d4129e288214aeacd56e5
Author: Andres G. Aragoneses <knocte gmail com>
Date: Tue Feb 21 01:25:07 2012 +0000
LibraryWatcher: avoid importing incomplete files
LibraryWatcher had a bug that is usually found in any library that uses
FileSystemWatcher API: handling files at the Creation event rather than
at the last Changed one (when the file transfer/creation has really been
finished in the watched folder). In Banshee this could have the effect
of trying to import incomplete files and not reading their tags
correctly obviously. This bug manifested itself much more clearly when
the new feature in bgo#664079 was implemented: warning when the user
tried to import an empty file (as this was implemented raising an
exception from the importing logic), causing the symptoms described in
bgo#666981.
With this fix we introduce a timer to delay the handling of the FSW
event just a small amount of time (10s), and we reset the timer every
time a Changed event happens, in order to handle the Create event
only at the last Changed event. This patch may even fix the broader
bug filed at bgo#655752.
Signed-off-by: Bertrand Lorentz <bertrand lorentz gmail com>
.../Banshee.LibraryWatcher/SourceWatcher.cs | 60 ++++++++++++++++++-
1 files changed, 56 insertions(+), 4 deletions(-)
---
diff --git a/src/Extensions/Banshee.LibraryWatcher/Banshee.LibraryWatcher/SourceWatcher.cs b/src/Extensions/Banshee.LibraryWatcher/Banshee.LibraryWatcher/SourceWatcher.cs
index 859e05f..8bcba5d 100644
--- a/src/Extensions/Banshee.LibraryWatcher/Banshee.LibraryWatcher/SourceWatcher.cs
+++ b/src/Extensions/Banshee.LibraryWatcher/Banshee.LibraryWatcher/SourceWatcher.cs
@@ -135,8 +135,62 @@ namespace Banshee.LibraryWatcher
#region Private Methods
+ private readonly double MAX_TIME_BETWEEN_CHANGED_EVENTS = TimeSpan.FromSeconds (10).TotalMilliseconds;
+
+ Dictionary<string, System.Timers.Timer> created_items_bag = new Dictionary<string, System.Timers.Timer> ();
+
+ private System.Timers.Timer CreateTimer (string fullpath)
+ {
+ var timer = new System.Timers.Timer (MAX_TIME_BETWEEN_CHANGED_EVENTS);
+ timer.Elapsed += (sender, e) => TimeUpForChangedEvent (fullpath);
+ return timer;
+ }
+
+ private void OnCreation (string fullpath)
+ {
+ var timer = CreateTimer (fullpath);
+ lock (created_items_bag) {
+ created_items_bag [fullpath] = timer;
+ }
+ timer.AutoReset = false;
+ timer.Start ();
+ }
+
+ private void TimeUpForChangedEvent (string fullpath)
+ {
+ lock (created_items_bag) {
+ created_items_bag [fullpath].Stop ();
+ created_items_bag [fullpath].Dispose ();
+ created_items_bag.Remove (fullpath);
+ }
+ var fake_args = new FileSystemEventArgs (WatcherChangeTypes.Created,
+ System.IO.Path.GetDirectoryName (fullpath),
+ System.IO.Path.GetFileName (fullpath));
+ EnqueueAffectedElement (fake_args);
+ }
+
private void OnModified (object source, FileSystemEventArgs args)
{
+ if (args.ChangeType == WatcherChangeTypes.Created) {
+ OnCreation (args.FullPath);
+ return;
+ } else if (args.ChangeType == WatcherChangeTypes.Changed) {
+ lock (created_items_bag) {
+ System.Timers.Timer timer;
+ if (created_items_bag.TryGetValue (args.FullPath, out timer)) {
+ // A file we saw being created was modified, restart the timer
+ timer.Stop ();
+ timer.Start ();
+ return;
+ }
+ }
+ }
+
+ EnqueueAffectedElement (args);
+ }
+
+ private void EnqueueAffectedElement (FileSystemEventArgs args)
+ {
var item = new QueueItem {
When = DateTime.Now,
ChangeType = args.ChangeType,
@@ -149,10 +203,8 @@ namespace Banshee.LibraryWatcher
}
handle.Set ();
- if (args.ChangeType != WatcherChangeTypes.Changed) {
- Hyena.Log.DebugFormat ("Watcher: {0} {1}{2}",
- item.ChangeType, args is RenamedEventArgs ? item.OldFullPath + " => " : "", item.FullPath);
- }
+ Hyena.Log.DebugFormat ("Watcher: {0} {1}{2}",
+ item.ChangeType, args is RenamedEventArgs ? item.OldFullPath + " => " : "", item.FullPath);
}
private void Watch ()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]