/// <summary> /// Called to close the file and cleanup. /// </summary> /// <param name="InFinalizer">true if called from the finalizer.</param> private void Close(bool InFinalizer) { if (!InFinalizer) { GC.SuppressFinalize(this); } if (workStream != null) { workStream.Close(); workStream = null; } // We need to delete the temp file. if (workFile != null) { File.Delete(workFile); } }
/// <summary> /// Called to cleanup any resources and close the file. /// </summary> /// <param name="InFinalizer"></param> /// <param name="commit"></param> private SyncNodeStatus Close(bool InFinalizer, bool commit) { if (!InFinalizer) { GC.SuppressFinalize(this); } SyncNodeStatus status = new SyncNodeStatus(); status.nodeID = node.ID; status.status = SyncStatus.ClientError; if (stream != null) { stream.Close(); stream = null; } if (workStream != null) { workStream.Close(); workStream = null; } if (commit) { // backup file for rolling back on failure string tmpFile = ""; if (File.Exists(file)) { tmpFile = file + ".~stmp"; File.Move(file, tmpFile); Log.log.Info("backing up {0}->{1}", file, tmpFile); } // first try to write the file try { Log.log.Info("trying to move {0}->{1}", workFile, file); File.Move(workFile, file); workFile = null; } catch { Log.log.Info("Couldn't move {0}->{1}", workFile, file); Log.log.Info("Restoring file {0}", file); try { if (File.Exists(file)) { File.Delete(file); // delete newly transferred file } if (File.Exists(tmpFile)) { File.Move(tmpFile, file); // restore backup file into place } } catch (Exception ex) { Log.log.Info("couldn't return to prior state{0}--{1}", ex.Message, ex.StackTrace); }; // DELETE HASHMAP ? throw; // and don't try to commit } // try to collection.commit() status.status = SyncStatus.Success; try { Log.log.Info("trying to commit collection"); collection.Commit(node); } catch (CollisionException ce) { commit = false; status.status = SyncStatus.UpdateConflict; Log.log.Info("Couldn't commit collection: UpdateConflict {0}--{1}", ce.Message, ce.StackTrace); } catch (Exception ex) { commit = false; status.status = SyncStatus.ServerFailure; Log.log.Info("Couldn't commit collection {0}--{1}", ex.Message, ex.StackTrace); } /* Note : Restore original file if collection.Commit fails. * Conflict is a valid case for failure. And do not remove * files in workarea as they are needed for conflict resolution. */ if (!commit && status.status != SyncStatus.UpdateConflict) { try { Log.log.Debug("Collection commit failed : Restoring backup file : {0}", file.ToString()); // Delete newly transferred file if (File.Exists(file)) { File.Delete(file); Log.log.Debug("-- Deleting file : {0}", file.ToString()); } // Restore backup file into place if (File.Exists(tmpFile)) { File.Move(tmpFile, file); Log.log.Debug("-- Restoring {0} to {1}", tmpFile.ToString(), file.ToString()); } // Fixme : Delete hashmap ? } catch (Exception ex) { Log.log.Info("File restore failed : Couldn't return to prior state {0}--{1}", ex.Message, ex.StackTrace); }; } else // commit successful, delete the temporary (.~stmp) file. { try { // restore backup file into place if (File.Exists(tmpFile)) { File.Delete(tmpFile); } } catch (Exception ex) { Log.log.Info("problem deleting .~stmp file {0}--{1}", ex.Message, ex.StackTrace); }; } if (commit) { FileInfo fi = new FileInfo(file); fi.LastWriteTime = node.LastWriteTime; fi.CreationTime = node.CreationTime; if (oldNode != null) { // Check if this was a rename. // If the old path does not equal the new path // Delete the old file. string oldPath = oldNode.GetFullPath(collection); try { Log.log.Info("{0} may have been moved to {1}", file, oldPath); if (MyEnvironment.Windows) { if (string.Compare(oldPath, file, true) != 0) { File.Delete(oldPath); } } else { if (oldPath != file) { File.Delete(oldPath); } } } catch {}; } } } // We need to delete the temp file if we are the master. // On the client leave for a delta sync. if (workFile != null) { if (collection.Role == SyncRoles.Master || (collection.Role == SyncRoles.Slave && File.Exists(file))) { File.Delete(workFile); } } if (partialFile != null) { File.Delete(partialFile); } return(status); }