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 \
|
SparkleRepoBase.cs \
|
||||||
SparkleUser.cs \
|
SparkleUser.cs \
|
||||||
SparkleWatcher.cs \
|
SparkleWatcher.cs \
|
||||||
|
SparkleWatcherFactory.cs \
|
||||||
SparkleWrappers.cs
|
SparkleWrappers.cs
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ namespace SparkleLib {
|
||||||
this.identifier = Identifier;
|
this.identifier = Identifier;
|
||||||
|
|
||||||
ChangeSets = GetChangeSets ();
|
ChangeSets = GetChangeSets ();
|
||||||
this.watcher = CreateWatcher ();
|
this.watcher = SparkleWatcherFactory.CreateWatcher (this);
|
||||||
|
|
||||||
new Thread (
|
new Thread (
|
||||||
new ThreadStart (delegate {
|
new ThreadStart (delegate {
|
||||||
|
@ -201,11 +201,6 @@ namespace SparkleLib {
|
||||||
|
|
||||||
public void OnFileActivity (FileSystemEventArgs args)
|
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) {
|
lock (this.change_lock) {
|
||||||
this.remote_timer.Stop ();
|
this.remote_timer.Stop ();
|
||||||
|
|
||||||
|
@ -220,7 +215,6 @@ namespace SparkleLib {
|
||||||
|
|
||||||
if (!IsBuffering && HasLocalChanges) {
|
if (!IsBuffering && HasLocalChanges) {
|
||||||
IsBuffering = true;
|
IsBuffering = true;
|
||||||
this.watcher.Disable ();
|
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Local", Name + " | Activity detected, waiting for it to settle...");
|
SparkleHelpers.DebugInfo ("Local", Name + " | Activity detected, waiting for it to settle...");
|
||||||
|
|
||||||
|
@ -244,10 +238,8 @@ namespace SparkleLib {
|
||||||
SparkleHelpers.DebugInfo ("Local", Name + " | Activity has settled");
|
SparkleHelpers.DebugInfo ("Local", Name + " | Activity has settled");
|
||||||
IsBuffering = false;
|
IsBuffering = false;
|
||||||
|
|
||||||
this.watcher.Disable ();
|
|
||||||
while (HasLocalChanges)
|
while (HasLocalChanges)
|
||||||
SyncUpBase ();
|
SyncUpBase ();
|
||||||
this.watcher.Enable ();
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Thread.Sleep (500);
|
Thread.Sleep (500);
|
||||||
|
@ -271,7 +263,6 @@ namespace SparkleLib {
|
||||||
private void SyncUpBase ()
|
private void SyncUpBase ()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
this.watcher.Disable ();
|
|
||||||
this.remote_timer.Stop ();
|
this.remote_timer.Stop ();
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("SyncUp", Name + " | Initiated");
|
SparkleHelpers.DebugInfo ("SyncUp", Name + " | Initiated");
|
||||||
|
@ -294,7 +285,6 @@ namespace SparkleLib {
|
||||||
|
|
||||||
HasUnsyncedChanges = true;
|
HasUnsyncedChanges = true;
|
||||||
SyncDownBase ();
|
SyncDownBase ();
|
||||||
this.watcher.Disable ();
|
|
||||||
|
|
||||||
if (ServerOnline && SyncUp ()) {
|
if (ServerOnline && SyncUp ()) {
|
||||||
HasUnsyncedChanges = false;
|
HasUnsyncedChanges = false;
|
||||||
|
@ -314,7 +304,6 @@ namespace SparkleLib {
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
this.remote_timer.Start ();
|
this.remote_timer.Start ();
|
||||||
this.watcher.Enable ();
|
|
||||||
|
|
||||||
ProgressPercentage = 0.0;
|
ProgressPercentage = 0.0;
|
||||||
ProgressSpeed = "";
|
ProgressSpeed = "";
|
||||||
|
@ -326,7 +315,6 @@ namespace SparkleLib {
|
||||||
{
|
{
|
||||||
SparkleHelpers.DebugInfo ("SyncDown", Name + " | Initiated");
|
SparkleHelpers.DebugInfo ("SyncDown", Name + " | Initiated");
|
||||||
this.remote_timer.Stop ();
|
this.remote_timer.Stop ();
|
||||||
this.watcher.Disable ();
|
|
||||||
|
|
||||||
if (SyncStatusChanged != null)
|
if (SyncStatusChanged != null)
|
||||||
SyncStatusChanged (SyncStatus.SyncDown);
|
SyncStatusChanged (SyncStatus.SyncDown);
|
||||||
|
@ -380,19 +368,6 @@ namespace SparkleLib {
|
||||||
SyncStatusChanged (SyncStatus.Idle);
|
SyncStatusChanged (SyncStatus.Idle);
|
||||||
|
|
||||||
this.remote_timer.Start ();
|
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)) {
|
!announcement.Message.Equals (CurrentRevision)) {
|
||||||
|
|
||||||
while (this.is_syncing)
|
while (this.is_syncing)
|
||||||
System.Threading.Thread.Sleep (100);
|
Thread.Sleep (100);
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Listener", "Syncing due to announcement");
|
SparkleHelpers.DebugInfo ("Listener", "Syncing due to announcement");
|
||||||
SyncDownBase ();
|
SyncDownBase ();
|
||||||
|
|
|
@ -16,57 +16,60 @@
|
||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
using IO = System.IO;
|
||||||
|
|
||||||
namespace SparkleLib {
|
namespace SparkleLib {
|
||||||
|
|
||||||
public class SparkleWatcher : FileSystemWatcher {
|
public class SparkleWatcher : IO.FileSystemWatcher {
|
||||||
|
|
||||||
public delegate void ChangeEventEventHandler (FileSystemEventArgs args);
|
public List<SparkleRepoBase> ReposToNotify = new List<SparkleRepoBase> ();
|
||||||
public event ChangeEventEventHandler ChangeEvent;
|
|
||||||
|
|
||||||
private Object thread_lock = new Object ();
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
IncludeSubdirectories = true;
|
||||||
EnableRaisingEvents = 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)
|
char separator = IO.Path.DirectorySeparatorChar;
|
||||||
EnableRaisingEvents = true;
|
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 ()
|
string repo_name = relative_path.Substring (0, relative_path.IndexOf (separator));
|
||||||
{
|
|
||||||
lock (this.thread_lock)
|
foreach (SparkleRepoBase repo in ReposToNotify) {
|
||||||
EnableRaisingEvents = false;
|
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 {
|
namespace SparkleLib {
|
||||||
|
|
||||||
public static class SparkleListenerFactory {
|
public static class SparkleWatcherFactory {
|
||||||
|
|
||||||
private static List<SparkleWatcher> watchers = new List<SparkleWatcher> ();
|
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) {
|
foreach (SparkleWatcher watcher in watchers) {
|
||||||
if (watcher.Path.Equals (path_to_watch)) {
|
foreach (SparkleRepoBase repo in watcher.ReposToNotify) {
|
||||||
SparkleHelpers.DebugInfo ("WatcherFactory",
|
string path_to_watch = Path.GetDirectoryName (repo_to_watch.LocalPath);
|
||||||
"Refered to existing watcher for " + path_to_watch);
|
|
||||||
|
|
||||||
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",
|
SparkleHelpers.DebugInfo ("WatcherFactory", "Issued new watcher for " + repo_to_watch.Name);
|
||||||
"Issued new watcher for " + path_to_watch);
|
|
||||||
|
|
||||||
return watchers [watchers.Count - 1];
|
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
|
// Let's use the bundled git first
|
||||||
SparkleLib.Git.SparkleGit.GitPath =
|
SparkleLib.Git.SparkleGit.GitPath =
|
||||||
Path.Combine (NSBundle.MainBundle.ResourcePath,
|
Path.Combine (NSBundle.MainBundle.ResourcePath, "git", "libexec", "git-core", "git");
|
||||||
"git", "libexec", "git-core", "git");
|
|
||||||
|
|
||||||
SparkleLib.Git.SparkleGit.ExecPath =
|
SparkleLib.Git.SparkleGit.ExecPath =
|
||||||
Path.Combine (NSBundle.MainBundle.ResourcePath,
|
Path.Combine (NSBundle.MainBundle.ResourcePath, "git", "libexec", "git-core");
|
||||||
"git", "libexec", "git-core");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,36 +68,13 @@ namespace SparkleShare {
|
||||||
{
|
{
|
||||||
base.Initialize ();
|
base.Initialize ();
|
||||||
|
|
||||||
this.watcher.Changed += delegate (object sender, SparkleMacWatcherEventArgs args) {
|
this.watcher.Changed += delegate (string path) {
|
||||||
string path = args.Path;
|
string full_path = Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, path + "/something");
|
||||||
|
|
||||||
// Don't even bother with paths in .git/
|
FileSystemEventArgs event_args = new FileSystemEventArgs (WatcherChangeTypes.Changed,
|
||||||
if (path.Contains (".git"))
|
Path.GetDirectoryName (full_path), Path.GetFileName (full_path));
|
||||||
return;
|
|
||||||
|
|
||||||
string repo_name;
|
SparkleWatcherFactory.TriggerWatcherManually (event_args);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,25 +53,14 @@ using MonoMac.Foundation;
|
||||||
|
|
||||||
namespace SparkleShare {
|
namespace SparkleShare {
|
||||||
|
|
||||||
[Serializable]
|
public sealed class SparkleMacWatcher : IDisposable {
|
||||||
public sealed class SparkleMacWatcherEventArgs : EventArgs {
|
|
||||||
|
public delegate void ChangedEventHandler (string path);
|
||||||
|
public event ChangedEventHandler Changed;
|
||||||
|
|
||||||
public string Path { get; private set; }
|
public string Path { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
public SparkleMacWatcherEventArgs (string path)
|
|
||||||
{
|
|
||||||
Path = path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public sealed class SparkleMacWatcher : IDisposable
|
|
||||||
{
|
|
||||||
public event EventHandler<SparkleMacWatcherEventArgs> Changed;
|
|
||||||
public string Path { get; private set; }
|
|
||||||
|
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
[Serializable]
|
[Serializable]
|
||||||
private enum FSEventStreamCreateFlags : uint
|
private enum FSEventStreamCreateFlags : uint
|
||||||
|
@ -186,7 +175,7 @@ namespace SparkleShare {
|
||||||
string path = paths [0];
|
string path = paths [0];
|
||||||
path = path.Substring (Path.Length);
|
path = path.Substring (Path.Length);
|
||||||
path = path.Trim ("/".ToCharArray ());
|
path = path.Trim ("/".ToCharArray ());
|
||||||
handler (this, new SparkleMacWatcherEventArgs (path));
|
handler (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
GC.KeepAlive (this);
|
GC.KeepAlive (this);
|
||||||
|
|
|
@ -284,6 +284,12 @@ namespace SparkleShare {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (Directory.Exists (args.FullPath) &&
|
||||||
|
args.ChangeType == WatcherChangeTypes.Created) {
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CheckRepositories ();
|
CheckRepositories ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue