Use only a single watcher to monitor the SparkleShare folder
This commit is contained in:
parent
e20dcd55ea
commit
ca22672842
|
@ -16,6 +16,7 @@ SOURCES = \
|
|||
SparkleRepoBase.cs \
|
||||
SparkleUser.cs \
|
||||
SparkleWatcher.cs \
|
||||
SparkleWatcherFactory.cs \
|
||||
SparkleWrappers.cs
|
||||
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ namespace SparkleLib {
|
|||
this.identifier = Identifier;
|
||||
|
||||
ChangeSets = GetChangeSets ();
|
||||
this.watcher = CreateWatcher ();
|
||||
this.watcher = SparkleWatcherFactory.CreateWatcher (this);
|
||||
|
||||
new Thread (
|
||||
new ThreadStart (delegate {
|
||||
|
@ -201,11 +201,6 @@ namespace SparkleLib {
|
|||
|
||||
public void OnFileActivity (FileSystemEventArgs args)
|
||||
{
|
||||
// Check the watcher for the occasions where this
|
||||
// method is called directly
|
||||
if (!this.watcher.EnableRaisingEvents || IsBuffering)
|
||||
return;
|
||||
|
||||
lock (this.change_lock) {
|
||||
this.remote_timer.Stop ();
|
||||
|
||||
|
@ -220,7 +215,6 @@ namespace SparkleLib {
|
|||
|
||||
if (!IsBuffering && HasLocalChanges) {
|
||||
IsBuffering = true;
|
||||
this.watcher.Disable ();
|
||||
|
||||
SparkleHelpers.DebugInfo ("Local", Name + " | Activity detected, waiting for it to settle...");
|
||||
|
||||
|
@ -244,10 +238,8 @@ namespace SparkleLib {
|
|||
SparkleHelpers.DebugInfo ("Local", Name + " | Activity has settled");
|
||||
IsBuffering = false;
|
||||
|
||||
this.watcher.Disable ();
|
||||
while (HasLocalChanges)
|
||||
SyncUpBase ();
|
||||
this.watcher.Enable ();
|
||||
|
||||
} else {
|
||||
Thread.Sleep (500);
|
||||
|
@ -271,7 +263,6 @@ namespace SparkleLib {
|
|||
private void SyncUpBase ()
|
||||
{
|
||||
try {
|
||||
this.watcher.Disable ();
|
||||
this.remote_timer.Stop ();
|
||||
|
||||
SparkleHelpers.DebugInfo ("SyncUp", Name + " | Initiated");
|
||||
|
@ -294,7 +285,6 @@ namespace SparkleLib {
|
|||
|
||||
HasUnsyncedChanges = true;
|
||||
SyncDownBase ();
|
||||
this.watcher.Disable ();
|
||||
|
||||
if (ServerOnline && SyncUp ()) {
|
||||
HasUnsyncedChanges = false;
|
||||
|
@ -314,7 +304,6 @@ namespace SparkleLib {
|
|||
|
||||
} finally {
|
||||
this.remote_timer.Start ();
|
||||
this.watcher.Enable ();
|
||||
|
||||
ProgressPercentage = 0.0;
|
||||
ProgressSpeed = "";
|
||||
|
@ -326,7 +315,6 @@ namespace SparkleLib {
|
|||
{
|
||||
SparkleHelpers.DebugInfo ("SyncDown", Name + " | Initiated");
|
||||
this.remote_timer.Stop ();
|
||||
this.watcher.Disable ();
|
||||
|
||||
if (SyncStatusChanged != null)
|
||||
SyncStatusChanged (SyncStatus.SyncDown);
|
||||
|
@ -380,19 +368,6 @@ namespace SparkleLib {
|
|||
SyncStatusChanged (SyncStatus.Idle);
|
||||
|
||||
this.remote_timer.Start ();
|
||||
this.watcher.Enable ();
|
||||
}
|
||||
|
||||
|
||||
private SparkleWatcher CreateWatcher ()
|
||||
{
|
||||
SparkleWatcher watcher = new SparkleWatcher (LocalPath);
|
||||
|
||||
watcher.ChangeEvent += delegate (FileSystemEventArgs args) {
|
||||
OnFileActivity (args);
|
||||
};
|
||||
|
||||
return watcher;
|
||||
}
|
||||
|
||||
|
||||
|
@ -456,7 +431,7 @@ namespace SparkleLib {
|
|||
!announcement.Message.Equals (CurrentRevision)) {
|
||||
|
||||
while (this.is_syncing)
|
||||
System.Threading.Thread.Sleep (100);
|
||||
Thread.Sleep (100);
|
||||
|
||||
SparkleHelpers.DebugInfo ("Listener", "Syncing due to announcement");
|
||||
SyncDownBase ();
|
||||
|
|
|
@ -16,57 +16,60 @@
|
|||
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
using IO = System.IO;
|
||||
|
||||
namespace SparkleLib {
|
||||
|
||||
public class SparkleWatcher : FileSystemWatcher {
|
||||
public class SparkleWatcher : IO.FileSystemWatcher {
|
||||
|
||||
public delegate void ChangeEventEventHandler (FileSystemEventArgs args);
|
||||
public event ChangeEventEventHandler ChangeEvent;
|
||||
|
||||
private Object thread_lock = new Object ();
|
||||
public List<SparkleRepoBase> ReposToNotify = new List<SparkleRepoBase> ();
|
||||
|
||||
|
||||
public SparkleWatcher (string path) : base (path)
|
||||
public SparkleWatcher (SparkleRepoBase repo)
|
||||
{
|
||||
ReposToNotify.Add (repo);
|
||||
|
||||
Changed += Notify;
|
||||
Created += Notify;
|
||||
Deleted += Notify;
|
||||
Renamed += Notify;
|
||||
|
||||
Filter = "*";
|
||||
Path = IO.Path.GetDirectoryName (repo.LocalPath);
|
||||
|
||||
IncludeSubdirectories = true;
|
||||
EnableRaisingEvents = true;
|
||||
Filter = "*";
|
||||
|
||||
Changed += delegate (object o, FileSystemEventArgs args) {
|
||||
if (ChangeEvent != null)
|
||||
ChangeEvent (args);
|
||||
};
|
||||
|
||||
Created += delegate (object o, FileSystemEventArgs args) {
|
||||
if (ChangeEvent != null)
|
||||
ChangeEvent (args);
|
||||
};
|
||||
|
||||
Deleted += delegate (object o, FileSystemEventArgs args) {
|
||||
if (ChangeEvent != null)
|
||||
ChangeEvent (args);
|
||||
};
|
||||
|
||||
Renamed += delegate (object o, RenamedEventArgs args) {
|
||||
if (ChangeEvent != null)
|
||||
ChangeEvent (args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void Enable ()
|
||||
public void Notify (object sender, IO.FileSystemEventArgs args)
|
||||
{
|
||||
lock (this.thread_lock)
|
||||
EnableRaisingEvents = true;
|
||||
}
|
||||
char separator = IO.Path.DirectorySeparatorChar;
|
||||
string relative_path = args.FullPath.Substring (Path.Length);
|
||||
relative_path = relative_path.Trim (new char [] {' ', separator});
|
||||
|
||||
// Ignore changes that happened in the parent path
|
||||
if (!relative_path.Contains (separator.ToString ()))
|
||||
return;
|
||||
|
||||
public void Disable ()
|
||||
{
|
||||
lock (this.thread_lock)
|
||||
EnableRaisingEvents = false;
|
||||
string repo_name = relative_path.Substring (0, relative_path.IndexOf (separator));
|
||||
|
||||
foreach (SparkleRepoBase repo in ReposToNotify) {
|
||||
if (repo.Name.Equals (repo_name) && !repo.IsBuffering &&
|
||||
(repo.Status != SyncStatus.SyncUp && repo.Status != SyncStatus.SyncDown)) {
|
||||
|
||||
Thread thread = new Thread (
|
||||
new ThreadStart (delegate {
|
||||
repo.OnFileActivity (args);
|
||||
})
|
||||
);
|
||||
|
||||
thread.Start ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,30 +21,43 @@ using System.IO;
|
|||
|
||||
namespace SparkleLib {
|
||||
|
||||
public static class SparkleListenerFactory {
|
||||
public static class SparkleWatcherFactory {
|
||||
|
||||
private static List<SparkleWatcher> watchers = new List<SparkleWatcher> ();
|
||||
|
||||
|
||||
public static SparkleWatcher CreateWatcher (string path_to_watch)
|
||||
public static SparkleWatcher CreateWatcher (SparkleRepoBase repo_to_watch)
|
||||
{
|
||||
path_to_watch = Path.GetDirectoryName (path_to_watch);
|
||||
|
||||
foreach (SparkleWatcher watcher in watchers) {
|
||||
if (watcher.Path.Equals (path_to_watch)) {
|
||||
SparkleHelpers.DebugInfo ("WatcherFactory",
|
||||
"Refered to existing watcher for " + path_to_watch);
|
||||
foreach (SparkleRepoBase repo in watcher.ReposToNotify) {
|
||||
string path_to_watch = Path.GetDirectoryName (repo_to_watch.LocalPath);
|
||||
|
||||
return watcher;
|
||||
if (watcher.Path.Equals (path_to_watch)) {
|
||||
watcher.ReposToNotify.Add (repo_to_watch);
|
||||
SparkleHelpers.DebugInfo ("WatcherFactory", "Refered to existing watcher for " + path_to_watch);
|
||||
|
||||
return watcher;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watchers.Add (new SparkleWatcher (path_to_watch));
|
||||
SparkleWatcher new_watcher = new SparkleWatcher (repo_to_watch);
|
||||
watchers.Add (new_watcher);
|
||||
|
||||
SparkleHelpers.DebugInfo ("WatcherFactory",
|
||||
"Issued new watcher for " + path_to_watch);
|
||||
SparkleHelpers.DebugInfo ("WatcherFactory", "Issued new watcher for " + repo_to_watch.Name);
|
||||
|
||||
return watchers [watchers.Count - 1];
|
||||
}
|
||||
|
||||
|
||||
public static void TriggerWatcherManually (FileSystemEventArgs args)
|
||||
{
|
||||
foreach (SparkleWatcher watcher in watchers) {
|
||||
if (args.FullPath.StartsWith (watcher.Path)) {
|
||||
watcher.Notify (null, args);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,12 +57,10 @@ namespace SparkleShare {
|
|||
|
||||
// Let's use the bundled git first
|
||||
SparkleLib.Git.SparkleGit.GitPath =
|
||||
Path.Combine (NSBundle.MainBundle.ResourcePath,
|
||||
"git", "libexec", "git-core", "git");
|
||||
Path.Combine (NSBundle.MainBundle.ResourcePath, "git", "libexec", "git-core", "git");
|
||||
|
||||
SparkleLib.Git.SparkleGit.ExecPath =
|
||||
Path.Combine (NSBundle.MainBundle.ResourcePath,
|
||||
"git", "libexec", "git-core");
|
||||
Path.Combine (NSBundle.MainBundle.ResourcePath, "git", "libexec", "git-core");
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,36 +68,13 @@ namespace SparkleShare {
|
|||
{
|
||||
base.Initialize ();
|
||||
|
||||
this.watcher.Changed += delegate (object sender, SparkleMacWatcherEventArgs args) {
|
||||
string path = args.Path;
|
||||
this.watcher.Changed += delegate (string path) {
|
||||
string full_path = Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, path + "/something");
|
||||
|
||||
// Don't even bother with paths in .git/
|
||||
if (path.Contains (".git"))
|
||||
return;
|
||||
FileSystemEventArgs event_args = new FileSystemEventArgs (WatcherChangeTypes.Changed,
|
||||
Path.GetDirectoryName (full_path), Path.GetFileName (full_path));
|
||||
|
||||
string repo_name;
|
||||
|
||||
if (path.Contains ("/"))
|
||||
repo_name = path.Substring (0, path.IndexOf ("/"));
|
||||
else
|
||||
repo_name = path;
|
||||
|
||||
// Ignore changes in the root of each subfolder, these
|
||||
// are already handled by the repository
|
||||
if (Path.GetFileNameWithoutExtension (path).Equals (repo_name))
|
||||
return;
|
||||
|
||||
repo_name = repo_name.Trim ("/".ToCharArray ());
|
||||
FileSystemEventArgs fse_args = new FileSystemEventArgs (
|
||||
WatcherChangeTypes.Changed,
|
||||
Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, path),
|
||||
Path.GetFileName (path)
|
||||
);
|
||||
|
||||
foreach (SparkleRepoBase repo in Repositories) {
|
||||
if (repo.Name.Equals (repo_name))
|
||||
repo.OnFileActivity (fse_args);
|
||||
}
|
||||
SparkleWatcherFactory.TriggerWatcherManually (event_args);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -53,22 +53,11 @@ using MonoMac.Foundation;
|
|||
|
||||
namespace SparkleShare {
|
||||
|
||||
[Serializable]
|
||||
public sealed class SparkleMacWatcherEventArgs : EventArgs {
|
||||
public sealed class SparkleMacWatcher : IDisposable {
|
||||
|
||||
public string Path { get; private set; }
|
||||
public delegate void ChangedEventHandler (string path);
|
||||
public event ChangedEventHandler Changed;
|
||||
|
||||
|
||||
public SparkleMacWatcherEventArgs (string path)
|
||||
{
|
||||
Path = path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public sealed class SparkleMacWatcher : IDisposable
|
||||
{
|
||||
public event EventHandler<SparkleMacWatcherEventArgs> Changed;
|
||||
public string Path { get; private set; }
|
||||
|
||||
|
||||
|
@ -186,7 +175,7 @@ namespace SparkleShare {
|
|||
string path = paths [0];
|
||||
path = path.Substring (Path.Length);
|
||||
path = path.Trim ("/".ToCharArray ());
|
||||
handler (this, new SparkleMacWatcherEventArgs (path));
|
||||
handler (path);
|
||||
}
|
||||
|
||||
GC.KeepAlive (this);
|
||||
|
|
|
@ -284,6 +284,12 @@ namespace SparkleShare {
|
|||
return;
|
||||
|
||||
} else {
|
||||
if (Directory.Exists (args.FullPath) &&
|
||||
args.ChangeType == WatcherChangeTypes.Created) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CheckRepositories ();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue