From a483759760e5e81e12ab9e1b571d61be180f626d Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sat, 9 Feb 2013 23:42:32 +0000 Subject: [PATCH] repo: update sync algorithm. fewer threads, less complexity --- SparkleLib/Git/SparkleRepoGit.cs | 24 ----- SparkleLib/SparkleRepoBase.cs | 129 +++++++++---------------- SparkleShare/Linux/SparkleUIHelpers.cs | 2 - 3 files changed, 48 insertions(+), 107 deletions(-) diff --git a/SparkleLib/Git/SparkleRepoGit.cs b/SparkleLib/Git/SparkleRepoGit.cs index 947165fe..7814fe75 100644 --- a/SparkleLib/Git/SparkleRepoGit.cs +++ b/SparkleLib/Git/SparkleRepoGit.cs @@ -161,30 +161,6 @@ namespace SparkleLib.Git { File.WriteAllText (size_file_path, size.ToString ()); File.WriteAllText (history_size_file_path, history_size.ToString ()); } - - - public override string [] UnsyncedFilePaths { - get { - List file_paths = new List (); - SparkleGit git = new SparkleGit (LocalPath, "status --porcelain"); - string output = git.StartAndReadStandardOutput (); - string [] lines = output.Split ("\n".ToCharArray ()); - - foreach (string line in lines) { - if (line [1].ToString ().Equals ("M") || - line [1].ToString ().Equals ("?") || - line [1].ToString ().Equals ("A")) { - - string path = line.Substring (3); - path = path.Trim ("\"".ToCharArray ()); - - file_paths.Add (path); - } - } - - return file_paths.ToArray (); - } - } public override string CurrentRevision { diff --git a/SparkleLib/SparkleRepoBase.cs b/SparkleLib/SparkleRepoBase.cs index 0c15e048..5de23235 100755 --- a/SparkleLib/SparkleRepoBase.cs +++ b/SparkleLib/SparkleRepoBase.cs @@ -45,20 +45,25 @@ namespace SparkleLib { public abstract class SparkleRepoBase { - public static bool UseCustomWatcher = false; + + public abstract bool SyncUp (); + public abstract bool SyncDown (); + public abstract void RestoreFile (string path, string revision, string target_file_path); + public abstract bool HasUnsyncedChanges { get; set; } + public abstract bool HasLocalChanges { get; } + public abstract bool HasRemoteChanges { get; } public abstract string CurrentRevision { get; } public abstract double Size { get; } public abstract double HistorySize { get; } + public abstract List ExcludePaths { get; } - public abstract bool HasUnsyncedChanges { get; set; } - public abstract bool HasLocalChanges { get; } - public abstract bool HasRemoteChanges { get; } - public abstract bool SyncUp (); - public abstract bool SyncDown (); public abstract List GetChangeSets (); public abstract List GetChangeSets (string path); - public abstract void RestoreFile (string path, string revision, string target_file_path); + + + public static bool UseCustomWatcher = false; + public event SyncStatusChangedEventHandler SyncStatusChanged = delegate { }; public delegate void SyncStatusChangedEventHandler (SyncStatus new_status); @@ -114,12 +119,6 @@ namespace SparkleLib { } } - public virtual string [] UnsyncedFilePaths { - get { - return new string [0]; - } - } - protected SparkleConfig local_config; @@ -127,16 +126,13 @@ namespace SparkleLib { private string identifier; private SparkleListenerBase listener; private SparkleWatcher watcher; - private TimeSpan poll_interval = PollInterval.Short; - private DateTime last_poll = DateTime.Now; - private DateTime progress_last_change = DateTime.Now; - private TimeSpan progress_change_interval = new TimeSpan (0, 0, 0, 1); - private Timers.Timer remote_timer = new Timers.Timer () { Interval = 5000 }; + private TimeSpan poll_interval = PollInterval.Short; + private DateTime last_poll = DateTime.Now; + private DateTime progress_last_change = DateTime.Now; + private Timers.Timer remote_timer = new Timers.Timer () { Interval = 5000 }; private bool is_syncing { - get { - return (Status == SyncStatus.SyncUp || Status == SyncStatus.SyncDown || IsBuffering); - } + get { return (Status == SyncStatus.SyncUp || Status == SyncStatus.SyncDown || IsBuffering); } } private static class PollInterval { @@ -162,9 +158,7 @@ namespace SparkleLib { string identifier_file_path = Path.Combine (LocalPath, ".sparkleshare"); File.SetAttributes (identifier_file_path, FileAttributes.Hidden); - SyncStatusChanged += delegate (SyncStatus status) { - Status = status; - }; + SyncStatusChanged += delegate (SyncStatus status) { Status = status; }; if (!UseCustomWatcher) this.watcher = new SparkleWatcher (LocalPath); @@ -176,20 +170,23 @@ namespace SparkleLib { return; int time_comparison = DateTime.Compare (this.last_poll, DateTime.Now.Subtract (this.poll_interval)); - bool time_to_poll = (time_comparison < 0); - if (time_to_poll && !is_syncing) { + if (time_comparison < 0) { + if (HasUnsyncedChanges && !this.is_syncing) + SyncUpBase (); + this.last_poll = DateTime.Now; - if (HasRemoteChanges) { - this.poll_interval = PollInterval.Long; + if (HasRemoteChanges && !this.is_syncing) SyncDownBase (); - } + + if (this.listener.IsConnected) + this.poll_interval = PollInterval.Long; } // In the unlikely case that we haven't synced up our // changes or the server was down, sync up again - if (HasUnsyncedChanges && !is_syncing && Error == ErrorStatus.None) + if (HasUnsyncedChanges && !this.is_syncing && Error == ErrorStatus.None) SyncUpBase (); }; } @@ -197,18 +194,20 @@ namespace SparkleLib { public void Initialize () { - if (!UseCustomWatcher) - this.watcher.ChangeEvent += OnFileActivity; - - // Sync up everything that changed - // since we've been offline + // Sync up everything that changed since we've been offline new Thread (() => { - if (!this.is_syncing && (HasUnsyncedChanges || HasLocalChanges)) { + if (HasRemoteChanges) + SyncDownBase (); + + if (HasUnsyncedChanges || HasLocalChanges) { do { SyncUpBase (); - } while (!this.is_syncing && HasLocalChanges); + } while (HasLocalChanges); } + + if (!UseCustomWatcher) + this.watcher.ChangeEvent += OnFileActivity; this.remote_timer.Start (); @@ -306,7 +305,7 @@ namespace SparkleLib { return; // Only trigger the ProgressChanged event once per second - if (DateTime.Compare (this.progress_last_change, DateTime.Now.Subtract (this.progress_change_interval)) >= 0) + if (DateTime.Compare (this.progress_last_change, DateTime.Now.Subtract (new TimeSpan (0, 0, 0, 1))) >= 0) return; if (progress_percentage == 100.0) @@ -350,8 +349,8 @@ namespace SparkleLib { if (Error == ErrorStatus.None && SyncUp ()) { HasUnsyncedChanges = false; - SyncStatusChanged (SyncStatus.Idle); this.listener.Announce (new SparkleAnnouncement (Identifier, CurrentRevision)); + SyncStatusChanged (SyncStatus.Idle); } else { this.poll_interval = PollInterval.Short; @@ -409,8 +408,8 @@ namespace SparkleLib { if (HasUnsyncedChanges) { SyncStatusChanged (SyncStatus.SyncUp); - SyncUp (); - HasUnsyncedChanges = false; + if (SyncUp ()) + HasUnsyncedChanges = false; } SyncStatusChanged (SyncStatus.Idle); @@ -425,10 +424,10 @@ namespace SparkleLib { ProgressPercentage = 0.0; ProgressSpeed = 0.0; + SyncStatusChanged (SyncStatus.Idle); + if (!UseCustomWatcher) this.watcher.Enable (); - - SyncStatusChanged (SyncStatus.Idle); } @@ -436,69 +435,38 @@ namespace SparkleLib { { this.listener = SparkleListenerFactory.CreateListener (Name, Identifier); - if (this.listener.IsConnected) { + if (this.listener.IsConnected) this.poll_interval = PollInterval.Long; - new Thread (() => { - if (!this.is_syncing && !HasLocalChanges && HasRemoteChanges) - SyncDownBase (); - - }).Start (); - } - - this.listener.Connected += ListenerConnectedDelegate; this.listener.Disconnected += ListenerDisconnectedDelegate; this.listener.AnnouncementReceived += ListenerAnnouncementReceivedDelegate; - // Start listening if (!this.listener.IsConnected && !this.listener.IsConnecting) this.listener.Connect (); } - // Stop polling when the connection to the irc channel is succesful - private void ListenerConnectedDelegate () - { - this.poll_interval = PollInterval.Long; - this.last_poll = DateTime.Now; - - if (!this.is_syncing) { - // Check for changes manually one more time - if (HasRemoteChanges) - SyncDownBase (); - - // Push changes that were made since the last disconnect - if (HasUnsyncedChanges) - SyncUpBase (); - } - } - - - // Start polling when the connection to the channel is lost private void ListenerDisconnectedDelegate () { this.poll_interval = PollInterval.Short; - SparkleLogger.LogInfo (Name, "Falling back to polling"); + SparkleLogger.LogInfo (Name, "Falling back to regular polling"); } - // Fetch changes when there is an announcement private void ListenerAnnouncementReceivedDelegate (SparkleAnnouncement announcement) { string identifier = Identifier; - if (announcement.FolderIdentifier.Equals (identifier) && - !announcement.Message.Equals (CurrentRevision)) { - + if (!announcement.FolderIdentifier.Equals (identifier)) + return; + + if (!announcement.Message.Equals (CurrentRevision)) { while (this.is_syncing) Thread.Sleep (100); SparkleLogger.LogInfo (Name, "Syncing due to announcement"); SyncDownBase (); - } else { - if (announcement.FolderIdentifier.Equals (identifier)) - SparkleLogger.LogInfo (Name, "Not syncing, message is for current revision"); } } @@ -531,7 +499,6 @@ namespace SparkleLib { this.remote_timer.Stop (); this.remote_timer.Dispose (); - this.listener.Connected -= ListenerConnectedDelegate; this.listener.Disconnected -= ListenerDisconnectedDelegate; this.listener.AnnouncementReceived -= ListenerAnnouncementReceivedDelegate; diff --git a/SparkleShare/Linux/SparkleUIHelpers.cs b/SparkleShare/Linux/SparkleUIHelpers.cs index cfa3a450..c631cf2f 100755 --- a/SparkleShare/Linux/SparkleUIHelpers.cs +++ b/SparkleShare/Linux/SparkleUIHelpers.cs @@ -23,7 +23,6 @@ namespace SparkleShare { public static class SparkleUIHelpers { - // Looks up an icon from the system's theme public static Gdk.Pixbuf GetIcon (string name, int size) { IconTheme icon_theme = new IconTheme (); @@ -36,7 +35,6 @@ namespace SparkleShare { icon_theme.AppendSearchPath ("/usr/share/icons"); icon_theme.AppendSearchPath ("/usr/local/share/icons"); icon_theme.AppendSearchPath ("/opt/local/share/icons"); - icon_theme.AppendSearchPath (Path.Combine (SparkleUI.AssetsPath, "icons")); try {