private void UploadNotes(List <Tuple <INote, INote> > notesToUpload, List <Tuple <INote, INote> > notesToResetRemoteDirty, ref List <Tuple <string, Exception> > errors) { foreach (var notetuple in notesToUpload) { var realnote = notetuple.Item1; var clonenote = notetuple.Item2; _log.Info("Sync", string.Format("Upload note {0}", clonenote.UniqueName)); try { if (!clonenote.IsLocalSaved) { dispatcher.Invoke(() => { if (!realnote.IsLocalSaved) { repo.SaveNote(realnote); } }); } var result = repo.Connection.UploadNoteToRemote(ref clonenote, out var conflictnote, conflictStrategy); switch (result) { case RemoteUploadResult.UpToDate: case RemoteUploadResult.Uploaded: dispatcher.Invoke(() => { if (realnote.IsLocalSaved) { realnote.OnAfterUpload(clonenote); realnote.ResetRemoteDirty(); repo.SaveNote(realnote); } }); break; case RemoteUploadResult.Merged: dispatcher.Invoke(() => { realnote.ApplyUpdatedData(clonenote); realnote.TriggerOnChanged(true); realnote.SetLocalDirty(); realnote.ResetRemoteDirty(); }); break; case RemoteUploadResult.Conflict: _log.Warn("Sync", "Uploading note " + clonenote.UniqueName + " resulted in conflict"); ResolveUploadConflict(realnote, clonenote, conflictnote); break; default: throw new ArgumentOutOfRangeException(); } } catch (Exception e) { var message = string.Format("Could not upload note '{2}' ({0}) cause of {1}", clonenote.UniqueName, e.Message, clonenote.Title); _log.Error("Sync", message, e); errors.Add(Tuple.Create(message, e)); } } foreach (var notetuple in notesToResetRemoteDirty) { var realnote = notetuple.Item1; var clonenote = notetuple.Item2; _log.Info("Sync", string.Format("Reset remote dirty of note {0} (no upload needed)", clonenote.UniqueName)); try { if (!clonenote.IsLocalSaved) { dispatcher.Invoke(() => { if (!realnote.IsLocalSaved) { repo.SaveNote(realnote); } }); } dispatcher.Invoke(() => { if (realnote.IsLocalSaved) { realnote.ResetRemoteDirty(); repo.SaveNote(realnote); } }); } catch (Exception e) { var message = string.Format("Could not reset remote dirty note '{2}' ({0}) cause of {1}", clonenote.UniqueName, e.Message, clonenote.Title); _log.Error("Sync", message, e); errors.Add(Tuple.Create(message, e)); } } }
private void UploadNotes(IReadOnlyCollection <Tuple <INote, INote> > notesToUpload, IEnumerable <Tuple <INote, INote> > notesToResetRemoteDirty, ICollection <Tuple <string, Exception> > errors) { ExecuteInParallel( _log, "UploadNotes", _noteUploadEnableMultithreading, notesToUpload, _noteUploadParallelismLevel, _noteUploadParallelismThreshold, (e, notetuple) => { var message = string.Format("Could not upload note '{2}' ({0}) cause of {1}", notetuple.Item2.UniqueName, e.Message, notetuple.Item2.Title); _log.Error("Sync", message, e); errors.Add(Tuple.Create(message, e)); return(true); }, notetuple => { var realnote = notetuple.Item1; var clonenote = notetuple.Item2; _log.Info("Sync", string.Format("Upload note {0}", clonenote.UniqueName)); if (!realnote.IsLocalSaved) { _dispatcher.Invoke(() => { if (!realnote.IsLocalSaved) { _repo.SaveNote(realnote); } }); } var result = _repo.Connection.UploadNoteToRemote(ref clonenote, out var conflictnote, _conflictStrategy); switch (result) { case RemoteUploadResult.UpToDate: case RemoteUploadResult.Uploaded: _dispatcher.Invoke(() => { if (realnote.IsLocalSaved) { realnote.OnAfterUpload(clonenote); realnote.ResetRemoteDirty("Note was successfully uploaded (no conflict)"); _repo.SaveNote(realnote); } }); break; case RemoteUploadResult.Merged: _dispatcher.Invoke(() => { realnote.ApplyUpdatedData(clonenote); realnote.TriggerOnChanged(true); realnote.SetLocalDirty("Note was uploaded and a merge has happened"); realnote.ResetRemoteDirty("Note was successfully uploaded (auto-merge)"); }); break; case RemoteUploadResult.Conflict: _log.Warn("Sync", "Uploading note " + clonenote.UniqueName + " resulted in conflict"); ResolveUploadConflict(realnote, clonenote, conflictnote); break; default: throw new ArgumentOutOfRangeException(); } });