private bool TryReduce(FileSystemEventArgs ev) { bool applied = false; var curIdx = Events.Count - 1; var prevIdx = Events.Count - 2; while (Events.Count > 1 && Events[prevIdx].FullPath == Events[curIdx].FullPath) { var prev = Events[prevIdx]; var cur = Events[curIdx]; if (prev.ChangeType == cur.ChangeType) { Log.Debug("IN: Skip duplicate: {0} => {1}", prev.FullPath, cur.FullPath); } else if (prev.ChangeType == Changes.Deleted && cur.ChangeType != Changes.Deleted) { Log.Debug("IN: Rewrite deletion for update: {0} => {1}", prev.FullPath, cur.FullPath); } else if ((prev.ChangeType & (Changes.Changed | Changes.Created)) != 0) { if (cur.ChangeType == Changes.Renamed) { Log.Debug("IN: Rewrite rename for update: {0} => {1}", prev.FullPath, cur.FullPath); } else if ((cur.ChangeType & (Changes.Changed | Changes.Created)) != 0) { Log.Debug("IN: Rewrite create for update: {0} => {1}", prev.FullPath, cur.FullPath); } } else if (prev.ChangeType != Changes.Deleted && cur.ChangeType == Changes.Deleted) { Log.Debug("IN: Rewrite update for deletion: {0} => {1}", prev.FullPath, cur.FullPath); } else { return(false); } applied = true; Events[prevIdx] = Events[curIdx]; Events.RemoveAt(curIdx); LogEventsNoLock(); if (prevIdx == 0) { return(true); } --prevIdx; --curIdx; } return(applied); }
public void WaitChanges(ChangesMonitor source, Predicate cancelPoller) { SourcePath = source.SourcePath; BashSourcePath = Utils.ToBashPath(SourcePath); BashExePath = Utils.TryBashExePath(); var sessionOptions = CreateSessionOptions(); var transferOptions = CreateTransferOptions(); Session.Timeout = Timeout; IsCancel = cancelPoller; while (!IsCancel()) { try { OpenSession(sessionOptions); while (!IsCancel()) { var changes = RetrieveChanges(source); OnChangesStart(); if (changes == null) { return; } TransferAll(changes, transferOptions); OnChangesFinish(); } } catch (SessionRemoteException err) { Log.Error("Remote failure: {0}", err); } catch (TimeoutException) { Log.Error("Session timeout. Retryng to connect..."); } catch (InvalidOperationException err) { Log.Error("Remote failure: {0}", err); } catch (SessionLocalException err) { Log.Error("Local failure: {0}", err); } catch (Exception err) { Log.Error("UNKNOWN EXCEPTION: {0}. Yury, you MUST fix it!", err); if (LostLifeChanges.Count > 0) { var first = LostLifeChanges[0]; Log.Debug("Skip problem change: {0} {1}", first.ChangeType, first.FullPath); LostLifeChanges.RemoveAt(0); } Thread.Sleep(1000); } finally { CloseSession(); } } }