/// <exception cref="IOException"></exception> private void DoUpdate() { SessionToken session = null; Dictionary <string, Directory> sourceDirectory = new Dictionary <string, Directory>(); Dictionary <string, IList <string> > copiedFiles = new Dictionary <string, IList <string> >(); bool notify = false; try { string version = handler.CurrentVersion; session = replicator.CheckForUpdate(version); WriteToInfoStream(string.Format("doUpdate(): handlerVersion={0} session={1}", version, session)); if (session == null) { return; } IDictionary <string, IList <RevisionFile> > requiredFiles = RequiredFiles(session.SourceFiles); WriteToInfoStream(string.Format("doUpdate(): handlerVersion={0} session={1}", version, session)); foreach (KeyValuePair <string, IList <RevisionFile> > pair in requiredFiles) { string source = pair.Key; Directory directory = factory.GetDirectory(session.Id, source); sourceDirectory.Add(source, directory); List <string> cpFiles = new List <string>(); copiedFiles.Add(source, cpFiles); foreach (RevisionFile file in pair.Value) { if (disposed) { // if we're closed, abort file copy WriteToInfoStream("doUpdate(): detected client was closed); abort file copy"); return; } Stream input = null; IndexOutput output = null; try { input = replicator.ObtainFile(session.Id, source, file.FileName); output = directory.CreateOutput(file.FileName, IOContext.DEFAULT); CopyBytes(output, input); cpFiles.Add(file.FileName); // TODO add some validation, on size / checksum } finally { IOUtils.Dispose(input, output); } } // only notify if all required files were successfully obtained. notify = true; } } finally { if (session != null) { try { replicator.Release(session.Id); } finally { if (!notify) { // cleanup after ourselves IOUtils.Dispose(sourceDirectory.Values); factory.CleanupSession(session.Id); } } } } // notify outside the try-finally above, so the session is released sooner. // the handler may take time to finish acting on the copied files, but the // session itself is no longer needed. try { if (notify && !disposed) { // no use to notify if we are closed already handler.RevisionReady(session.Version, session.SourceFiles, new ReadOnlyDictionary <string, IList <string> >(copiedFiles), sourceDirectory); } } finally { IOUtils.Dispose(sourceDirectory.Values); //TODO: Resharper Message, Expression is always true -> Verify and if so then we can remove the null check. if (session != null) { factory.CleanupSession(session.Id); } } }
public ReplicationSession(SessionToken session, RefCountedRevision revision) { Session = session; Revision = revision; lastAccessTime = Stopwatch.GetTimestamp(); }