You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2017/08/18 08:04:55 UTC

[08/20] lucenenet git commit: Lucene.Net.Replicator: Cleaned up documentation and reverted code order back to the same as Lucene.

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/ReplicationClient.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/ReplicationClient.cs b/src/Lucene.Net.Replicator/ReplicationClient.cs
index 14c1c2b..6064856 100644
--- a/src/Lucene.Net.Replicator/ReplicationClient.cs
+++ b/src/Lucene.Net.Replicator/ReplicationClient.cs
@@ -32,32 +32,154 @@ namespace Lucene.Net.Replicator
     /// <summary>
     /// A client which monitors and obtains new revisions from a <see cref="IReplicator"/>.
     /// It can be used to either periodically check for updates by invoking
-    /// <see cref="StartUpdateThread"/>, or manually by calling <see cref="UpdateNow"/>.
-    /// <para>
+    /// <see cref="StartUpdateThread"/>, or manually by calling <see cref="UpdateNow()"/>.
+    /// <para/>
     /// Whenever a new revision is available, the <see cref="RequiredFiles"/> are
     /// copied to the <see cref="Directory"/> specified by <see cref="PerSessionDirectoryFactory"/> and
     /// a handler is notified.
-    /// </para>
     /// </summary>
     /// <remarks>
-    /// Lucene.Experimental
+    /// @lucene.experimental
     /// </remarks>
     public class ReplicationClient : IDisposable
     {
+        //Note: LUCENENET specific, .NET does not work with Threads in the same way as Java does, so we mimic the same behavior using the ThreadPool instead.
+        private class ReplicationThread
+        {
+            private readonly Action doUpdate;
+            private readonly Action<Exception> handleException;
+            private readonly ReentrantLock @lock;
+            private readonly object controlLock = new object();
+
+            private readonly long interval;
+            private readonly AutoResetEvent handle = new AutoResetEvent(false);
+
+            private AutoResetEvent stopHandle;
+
+            /// <summary>
+            /// Gets or sets the name
+            /// </summary>
+            public string Name { get; private set; }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            /// <param name="intervalMillis">The interval in milliseconds.</param>
+            /// <param name="threadName">The thread name.</param>
+            /// <param name="doUpdate">A delegate to call to perform the update.</param>
+            /// <param name="handleException">A delegate to call to handle an exception.</param>
+            /// <param name="lock"></param>
+            public ReplicationThread(long intervalMillis, string threadName, Action doUpdate, Action<Exception> handleException, ReentrantLock @lock)
+            {
+                this.doUpdate = doUpdate;
+                this.handleException = handleException;
+                this.@lock = @lock;
+                Name = threadName;
+                this.interval = intervalMillis;
+            }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            public bool IsAlive { get; private set; }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            public void Start()
+            {
+                lock (controlLock)
+                {
+                    if (IsAlive)
+                        return;
+                    IsAlive = true;
+                }
+                RegisterWait(interval);
+            }
+
+            /// <summary>
+            /// 
+            /// </summary>
+            public void Stop()
+            {
+                lock (controlLock)
+                {
+                    if (!IsAlive)
+                        return;
+                    IsAlive = false;
+                }
+                stopHandle = new AutoResetEvent(false);
+
+                //NOTE: Execute any outstanding, this execution will terminate almost instantaniously if it's not already running.
+                ExecuteImmediately();
+
+                stopHandle.WaitOne();
+                stopHandle = null;
+            }
+
+            /// <summary>
+            /// Executes the next cycle of work immediately
+            /// </summary>
+            public void ExecuteImmediately()
+            {
+                handle.Set();
+            }
+
+            private void RegisterWait(long timeout)
+            {
+                //NOTE: We don't care about timedout as it can either be because we was requested to run immidiately or stop.
+                if (IsAlive)
+                    ThreadPool.RegisterWaitForSingleObject(handle, (state, timedout) => Run(), null, timeout, true);
+                else
+                    SignalStop();
+            }
+
+            private void SignalStop()
+            {
+                if (stopHandle != null)
+                    stopHandle.Set();
+            }
+
+            private void Run()
+            {
+                if (!IsAlive)
+                {
+                    SignalStop();
+                    return;
+                }
+
+                Stopwatch timer = Stopwatch.StartNew();
+                @lock.Lock();
+                try
+                {
+                    doUpdate();
+                }
+                catch (Exception exception)
+                {
+                    handleException(exception);
+                }
+                finally
+                {
+                    @lock.Unlock();
+
+                    timer.Stop();
+                    long driftAdjusted = Math.Max(interval - timer.ElapsedMilliseconds, 0);
+                    if (IsAlive)
+                        RegisterWait(driftAdjusted);
+                    else
+                        SignalStop();
+                }
+            }
+        }
+
+        // LUCENENET specific - de-nested the IReplicationHandler and
+        // ISourceDirectoryFactory interfaces.
+
         /// <summary>
         /// The component name to use with <see cref="Util.InfoStream.IsEnabled"/>
         /// </summary>
         public const string INFO_STREAM_COMPONENT = "ReplicationThread";
 
-        /// <summary> 
-        /// Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages. 
-        /// </summary>
-        public InfoStream InfoStream
-        {
-            get { return infoStream; }
-            set { infoStream = value ?? InfoStream.NO_OUTPUT; }
-        }
-
         private readonly IReplicator replicator;
         private readonly IReplicationHandler handler;
         private readonly ISourceDirectoryFactory factory;
@@ -83,6 +205,16 @@ namespace Lucene.Net.Replicator
         }
 
         /// <exception cref="IOException"></exception>
+        private void CopyBytes(IndexOutput output, Stream input)
+        {
+            int numBytes;
+            while ((numBytes = input.Read(copyBuffer, 0, copyBuffer.Length)) > 0)
+            {
+                output.WriteBytes(copyBuffer, 0, numBytes);
+            }
+        }
+
+        /// <exception cref="IOException"></exception>
         private void DoUpdate()
         {
             SessionToken session = null;
@@ -179,19 +311,18 @@ namespace Lucene.Net.Replicator
                     factory.CleanupSession(session.Id);
                 }
             }
-
         }
 
-        /// <exception cref="IOException"></exception>
-        private void CopyBytes(IndexOutput output, Stream input)
+        /// <summary>Throws <see cref="ObjectDisposedException"/> if the client has already been disposed.</summary>
+        protected virtual void EnsureOpen()
         {
-            int numBytes;
-            while ((numBytes = input.Read(copyBuffer, 0, copyBuffer.Length)) > 0) {
-                output.WriteBytes(copyBuffer, 0, numBytes);
-            }
+            if (!disposed)
+                return;
+
+            throw new ObjectDisposedException("this update client has already been closed");
         }
 
-        //.NET Note: Utility Method
+        // LUCENENET specific Utility Method
         private void WriteToInfoStream(string message)
         {
             if (infoStream.IsEnabled(INFO_STREAM_COMPONENT))
@@ -199,11 +330,26 @@ namespace Lucene.Net.Replicator
         }
 
         /// <summary>
+        /// Called when an exception is hit by the replication thread. The default
+        /// implementation prints the full stacktrace to the <see cref="Util.InfoStream"/> set in
+        /// <see cref="InfoStream"/>, or the <see cref="Util.InfoStream.Default"/>
+        /// one. You can override to log the exception elsewhere.
+        /// </summary>
+        /// <remarks>
+        /// <b>NOTE:</b> If you override this method to throw the exception further,
+        /// the replication thread will be terminated. The only way to restart it is to
+        /// call <see cref="StopUpdateThread"/> followed by
+        /// <see cref="StartUpdateThread"/>.
+        /// </remarks>
+        protected virtual void HandleUpdateException(Exception exception)
+        {
+            WriteToInfoStream(string.Format("an error occurred during revision update: {0}", exception));
+        }
+
+        /// <summary>
         /// Returns the files required for replication. By default, this method returns
         /// all files that exist in the new revision, but not in the handler.
         /// </summary>
-        /// <param name="newRevisionFiles"></param>
-        /// <returns></returns>
         private IDictionary<string, IList<RevisionFile>> RequiredFiles(IDictionary<string, IList<RevisionFile>> newRevisionFiles)
         {
             IDictionary<string, IList<RevisionFile>> handlerRevisionFiles = handler.CurrentRevisionFiles;
@@ -227,10 +373,25 @@ namespace Lucene.Net.Replicator
             return requiredFiles;
         }
 
+        protected virtual void Dispose(bool disposing)
+        {
+            if (disposed)
+                return;
+
+            StopUpdateThread();
+            disposed = true;
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
         /// <summary>
         /// Start the update thread with the specified interval in milliseconds. For
         /// debugging purposes, you can optionally set the name to set on
-        /// <see cref="ReplicationThread.Name"/>. If you pass <code>null</code>, a default name
+        /// <see cref="ReplicationThread.Name"/>. If you pass <c>null</c>, a default name
         /// will be set.
         /// </summary>
         /// <exception cref="InvalidOperationException"> if the thread has already been started </exception>
@@ -273,34 +434,15 @@ namespace Lucene.Net.Replicator
             get { return updateThread != null && updateThread.IsAlive; }
         }
 
-        /// <summary>Throws <see cref="ObjectDisposedException"/> if the client has already been disposed.</summary>
-        protected virtual void EnsureOpen()
-        {
-            if (!disposed)
-                return;
-
-            throw new ObjectDisposedException("this update client has already been closed");
-        }
-
-        /// <summary>
-        /// Called when an exception is hit by the replication thread. The default
-        /// implementation prints the full stacktrace to the <seealso cref="InfoStream"/> set in
-        /// <seealso cref="InfoStream"/>, or the <see cref="Util.InfoStream.Default"/>
-        /// one. You can override to log the exception elswhere.
-        /// </summary>
-        /// <remarks>
-        /// If you override this method to throw the exception further,
-        /// the replication thread will be terminated. The only way to restart it is to
-        /// call <seealso cref="StopUpdateThread"/> followed by
-        /// <seealso cref="StartUpdateThread"/>.
-        /// </remarks>
-        protected virtual void HandleUpdateException(Exception exception)
+        public override string ToString()
         {
-            WriteToInfoStream(string.Format("an error occurred during revision update: {0}", exception));
+            if (updateThread == null)
+                return "ReplicationClient";
+            return string.Format("ReplicationClient ({0})", updateThread.Name);
         }
 
         /// <summary>
-        /// Executes the update operation immediately, irregardess if an update thread
+        /// Executes the update operation immediately, regardless if an update thread
         /// is running or not.
         /// </summary>
         /// <exception cref="IOException"></exception>
@@ -327,156 +469,61 @@ namespace Lucene.Net.Replicator
             }
         }
 
-        protected virtual void Dispose(bool disposing)
-        {
-            if (disposed)
-                return;
-
-            StopUpdateThread();
-            disposed = true;
-        }
-
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        public override string ToString()
+        /// <summary> 
+        /// Gets or sets the <see cref="Util.InfoStream"/> to use for logging messages. 
+        /// </summary>
+        public InfoStream InfoStream
         {
-            if (updateThread == null)
-                return "ReplicationClient";
-            return string.Format("ReplicationClient ({0})", updateThread.Name);
+            get { return infoStream; }
+            set { infoStream = value ?? InfoStream.NO_OUTPUT; }
         }
+    }
 
-        //Note: LUCENENET specific, .NET does not work with Threads in the same way as Java does, so we mimic the same behavior using the ThreadPool instead.
-        private class ReplicationThread
-        {
-            private readonly Action doUpdate;
-            private readonly Action<Exception> handleException;
-            private readonly ReentrantLock @lock;
-            private readonly object controlLock = new object();
-            
-            private readonly long interval;
-            private readonly AutoResetEvent handle = new AutoResetEvent(false);
-
-            private AutoResetEvent stopHandle;
-
-            /// <summary>
-            /// Gets or sets the name
-            /// </summary>
-            public string Name { get; private set; }
-
-            /// <summary>
-            /// 
-            /// </summary>
-            /// <param name="intervalMillis"></param>
-            /// <param name="threadName"></param>
-            /// <param name="doUpdate"></param>
-            /// <param name="handleException"></param>
-            /// <param name="lock"></param>
-            public ReplicationThread(long intervalMillis, string threadName, Action doUpdate, Action<Exception> handleException, ReentrantLock @lock)
-            {
-                this.doUpdate = doUpdate;
-                this.handleException = handleException;
-                this.@lock = @lock;
-                Name = threadName;
-                this.interval = intervalMillis;
-            }
-
-            /// <summary>
-            /// 
-            /// </summary>
-            public bool IsAlive { get; private set; }
-
-            /// <summary>
-            /// 
-            /// </summary>
-            public void Start()
-            {
-                lock (controlLock)
-                {
-                    if (IsAlive)
-                        return;
-                    IsAlive = true;
-                }
-                RegisterWait(interval);
-            }
-
-            /// <summary>
-            /// 
-            /// </summary>
-            public void Stop()
-            {
-                lock (controlLock)
-                {
-                    if (!IsAlive)
-                        return;
-                    IsAlive = false;
-                }
-                stopHandle = new AutoResetEvent(false);
-
-                //NOTE: Execute any outstanding, this execution will terminate almost instantaniously if it's not already running.
-                ExecuteImmediately();
-
-                stopHandle.WaitOne();
-                stopHandle = null;
-            }
-
-            /// <summary>
-            /// Executes the next cycle of work immediately
-            /// </summary>
-            public void ExecuteImmediately()
-            {
-                handle.Set();
-            }
-
-            private void RegisterWait(long timeout)
-            {
-                //NOTE: We don't care about timedout as it can either be because we was requested to run immidiately or stop.
-                if (IsAlive)
-                    ThreadPool.RegisterWaitForSingleObject(handle, (state, timedout) => Run(), null, timeout, true);
-                else
-                    SignalStop();
-            }
-
-            private void SignalStop()
-            {
-                if (stopHandle != null)
-                    stopHandle.Set();
-            }
+    /// <summary>Handler for revisions obtained by the client.</summary>
+    //Note: LUCENENET specific denesting of interface
+    public interface IReplicationHandler
+    {
+        /// <summary>Returns the current revision files held by the handler.</summary>
+        string CurrentVersion { get; }
 
-            private void Run()
-            {
-                if (!IsAlive)
-                {
-                    SignalStop();
-                    return;
-                }
+        /// <summary>Returns the current revision version held by the handler.</summary>
+        IDictionary<string, IList<RevisionFile>> CurrentRevisionFiles { get; }
 
-                Stopwatch timer = Stopwatch.StartNew();
-                @lock.Lock();
-                try
-                {
-                    doUpdate();
-                }
-                catch (Exception exception)
-                {
-                    handleException(exception);
-                }
-                finally
-                {
-                    @lock.Unlock();
+        /// <summary>
+        /// Called when a new revision was obtained and is available (i.e. all needed files were successfully copied).
+        /// </summary>
+        /// <param name="version">The version of the <see cref="IRevision"/> that was copied</param>
+        /// <param name="revisionFiles"> The files contained by this <see cref="IRevision"/></param>
+        /// <param name="copiedFiles">The files that were actually copied</param>
+        /// <param name="sourceDirectory">A mapping from a source of files to the <see cref="Directory"/> they were copied into</param>
+        /// <exception cref="IOException"/>
+        void RevisionReady(string version,
+            IDictionary<string, IList<RevisionFile>> revisionFiles,
+            IDictionary<string, IList<string>> copiedFiles,
+            IDictionary<string, Directory> sourceDirectory);
+    }
 
-                    timer.Stop();
-                    long driftAdjusted = Math.Max(interval - timer.ElapsedMilliseconds, 0);
-                    if (IsAlive)
-                        RegisterWait(driftAdjusted);
-                    else
-                        SignalStop();
-                }
-            }
-        }
+    /// <summary>
+    /// Resolves a session and source into a <see cref="Directory"/> to use for copying
+    /// the session files to.
+    /// </summary>
+    //Note: LUCENENET specific denesting of interface
+    public interface ISourceDirectoryFactory
+    {
+        /// <summary>
+        /// Returns the <see cref="Directory"/> to use for the given session and source.
+        /// Implementations may e.g. return different directories for different
+        /// sessions, or the same directory for all sessions. In that case, it is
+        /// advised to clean the directory before it is used for a new session.
+        /// </summary>
+        /// <exception cref="System.IO.IOException"></exception>
+        /// <seealso cref="CleanupSession(string)"/>
+        Directory GetDirectory(string sessionId, string source); //throws IOException;
 
+        /// <summary>
+        /// Called to denote that the replication actions for this session were finished and the directory is no longer needed. 
+        /// </summary>
+        /// <exception cref="System.IO.IOException"></exception>
+        void CleanupSession(string sessionId);
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/Replicator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Replicator.cs b/src/Lucene.Net.Replicator/Replicator.cs
index 28de0d3..05bbd5a 100644
--- a/src/Lucene.Net.Replicator/Replicator.cs
+++ b/src/Lucene.Net.Replicator/Replicator.cs
@@ -22,22 +22,21 @@ namespace Lucene.Net.Replicator
 
     /// <summary>
     /// An interface for replicating files. Allows a producer to 
-    /// <see cref="Publish"/> <see cref="IRevision"/>s and consumers to
-    /// <see cref="CheckForUpdate"/>. When a client needs to be
+    /// <see cref="Publish(IRevision)"/> <see cref="IRevision"/>s and consumers to
+    /// <see cref="CheckForUpdate(string)"/>. When a client needs to be
     /// updated, it is given a <see cref="SessionToken"/> through which it can
-    /// <see cref="ObtainFile"/> the files of that
+    /// <see cref="ObtainFile(string, string, string)"/> the files of that
     /// revision. After the client has finished obtaining all the files, it should
-    /// <see cref="Release"/> the given session, so that the files can be
+    /// <see cref="Release(string)"/> the given session, so that the files can be
     /// reclaimed if they are not needed anymore.
-    /// <p>
+    /// <para/>
     /// A client is always updated to the newest revision available. That is, if a
     /// client is on revision <em>r1</em> and revisions <em>r2</em> and <em>r3</em>
-    /// were published, then when the cllient will next check for update, it will
+    /// were published, then when the client will next check for update, it will
     /// receive <em>r3</em>.
-    /// </p>
     /// </summary>
     /// <remarks>
-    /// Lucene.Experimental
+    /// @lucene.experimental
     /// </remarks>
     public interface IReplicator : IDisposable
     {
@@ -54,10 +53,10 @@ namespace Lucene.Net.Replicator
         /// <summary>
         /// Check whether the given version is up-to-date and returns a
         /// <see cref="SessionToken"/> which can be used for fetching the revision files,
-        /// otherwise returns <code>null</code>.
+        /// otherwise returns <c>null</c>.
         /// </summary>
         /// <remarks>
-        /// When the returned session token is no longer needed, you
+        /// <b>NOTE:</b> When the returned session token is no longer needed, you
         /// should call <see cref="Release"/> so that the session resources can be
         /// reclaimed, including the revision files.
         /// </remarks>
@@ -75,7 +74,7 @@ namespace Lucene.Net.Replicator
         /// context of the given <see cref="SessionToken.Id"/>.
         /// </summary>
         /// <remarks>
-        /// It is the caller's responsibility to call <see cref="IDisposable.Dispose"/> on the returned stream.
+        /// <b>NOTE:</b> It is the caller's responsibility to call <see cref="IDisposable.Dispose"/> on the returned stream.
         /// </remarks>
         /// <exception cref="SessionExpiredException">The specified session has already expired</exception>
         Stream ObtainFile(string sessionId, string source, string fileName);

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/Revision.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/Revision.cs b/src/Lucene.Net.Replicator/Revision.cs
index 57d7ffb..7963241 100644
--- a/src/Lucene.Net.Replicator/Revision.cs
+++ b/src/Lucene.Net.Replicator/Revision.cs
@@ -33,13 +33,19 @@ namespace Lucene.Net.Replicator
     /// they match at the client side.
     /// </summary>
     /// <remarks>
-    /// Lucene.Experimental
+    /// @lucene.experimental
     /// </remarks>
     public interface IRevision : IComparable<IRevision>
     {
         /// <summary>
+        /// Compares the revision to the given version string. Behaves like
+        /// <see cref="IComparable{T}.CompareTo(T)"/>
+        /// </summary>
+        int CompareTo(string version);
+
+        /// <summary>
         /// Returns a string representation of the version of this revision. The
-        /// version is used by <see cref="CompareTo"/> as well as to
+        /// version is used by <see cref="CompareTo(string)"/> as well as to
         /// serialize/deserialize revision information. Therefore it must be self
         /// descriptive as well as be able to identify one revision from another.
         /// </summary>
@@ -52,14 +58,8 @@ namespace Lucene.Net.Replicator
         IDictionary<string, IList<RevisionFile>> SourceFiles { get; }
 
         /// <summary>
-        /// Compares the revision to the given version string. Behaves like
-        /// <see cref="IComparable{T}.CompareTo"/>
-        /// </summary>
-        int CompareTo(string version);
-
-        /// <summary>
-        /// Returns a <see cref="Stream"/> for the given fileName and source. It is the
-        /// caller's respnsibility to close the <see cref="Stream"/> when it has been
+        /// Returns a <see cref="Stream"/> for the given <paramref name="fileName"/> and <paramref name="source"/>. It is the
+        /// caller's respnsibility to dispose the <see cref="Stream"/> when it has been
         /// consumed.
         /// </summary>
         /// <exception cref="IOException"></exception>

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/RevisionFile.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/RevisionFile.cs b/src/Lucene.Net.Replicator/RevisionFile.cs
index 3d54719..c74f057 100644
--- a/src/Lucene.Net.Replicator/RevisionFile.cs
+++ b/src/Lucene.Net.Replicator/RevisionFile.cs
@@ -24,7 +24,7 @@ namespace Lucene.Net.Replicator
     /// single revision to contain files from multiple sources (e.g. multiple indexes).
     /// </summary>
     /// <remarks>
-    /// Lucene.Experimental
+    /// @lucene.experimental
     /// </remarks>
     public class RevisionFile : IEquatable<RevisionFile>
     {
@@ -51,12 +51,15 @@ namespace Lucene.Net.Replicator
             Length = length;
         }
 
-        public override string ToString()
+        public override bool Equals(object obj)
         {
-            return string.Format("fileName={0} length={1}", FileName, Length);
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != this.GetType()) return false;
+            return Equals((RevisionFile)obj);
         }
 
-        #region Resharper Generated Code
+        // LUCENENET specific Equals overload
         public bool Equals(RevisionFile other)
         {
             if (ReferenceEquals(null, other)) return false;
@@ -64,21 +67,17 @@ namespace Lucene.Net.Replicator
             return string.Equals(FileName, other.FileName) && Length == other.Length;
         }
 
-        public override bool Equals(object obj)
-        {
-            if (ReferenceEquals(null, obj)) return false;
-            if (ReferenceEquals(this, obj)) return true;
-            if (obj.GetType() != this.GetType()) return false;
-            return Equals((RevisionFile)obj);
-        }
-
         public override int GetHashCode()
         {
-            unchecked
+            unchecked // LUCENENET TODO: Correct hash code logic
             {
                 return (FileName.GetHashCode() * 397) ^ Length.GetHashCode();
             }
         }
-        #endregion
+
+        public override string ToString()
+        {
+            return string.Format("fileName={0} length={1}", FileName, Length);
+        }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/SessionExpiredException.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/SessionExpiredException.cs b/src/Lucene.Net.Replicator/SessionExpiredException.cs
index 7aeb426..45c16a1 100644
--- a/src/Lucene.Net.Replicator/SessionExpiredException.cs
+++ b/src/Lucene.Net.Replicator/SessionExpiredException.cs
@@ -1,5 +1,8 @@
 using System;
 using System.IO;
+#if FEATURE_SERIALIZABLE
+using System.Runtime.Serialization;
+#endif
 
 namespace Lucene.Net.Replicator
 {
@@ -24,11 +27,14 @@ namespace Lucene.Net.Replicator
     /// Exception indicating that a revision update session was expired due to lack of activity.
     /// </summary>
     /// <remarks>
-    /// <see cref="LocalReplicator.DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>
-    /// <see cref="LocalReplicator.ExpirationThreshold"/>
-    /// 
-    /// Lucene.Experimental
+    /// @lucene.experimental
     /// </remarks>
+    /// <seealso cref="LocalReplicator.DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>
+    /// <seealso cref="LocalReplicator.ExpirationThreshold"/>
+    // LUCENENET: All exeption classes should be marked serializable
+#if FEATURE_SERIALIZABLE
+    [Serializable]
+#endif
     public class SessionExpiredException : IOException
     {
         //
@@ -51,5 +57,17 @@ namespace Lucene.Net.Replicator
             : base(message, inner)
         {
         }
+
+#if FEATURE_SERIALIZABLE
+        /// <summary>
+        /// Initializes a new instance of this class with serialized data.
+        /// </summary>
+        /// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
+        /// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
+        public SessionExpiredException(SerializationInfo info, StreamingContext context)
+            : base(info, context)
+        {
+        }
+#endif
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/67882465/src/Lucene.Net.Replicator/SessionToken.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Replicator/SessionToken.cs b/src/Lucene.Net.Replicator/SessionToken.cs
index c998137..305729b 100644
--- a/src/Lucene.Net.Replicator/SessionToken.cs
+++ b/src/Lucene.Net.Replicator/SessionToken.cs
@@ -1,7 +1,5 @@
-using System.Collections.Generic;
-using System.IO;
-using Lucene.Net.Store;
 using Lucene.Net.Support.IO;
+using System.Collections.Generic;
 
 namespace Lucene.Net.Replicator
 {
@@ -27,20 +25,19 @@ namespace Lucene.Net.Replicator
     /// files will be kept safe until the replication completes.
     /// </summary>
     /// <remarks>
-    /// <see cref="IReplicator.CheckForUpdate"/>
-    /// <see cref="IReplicator.Release"/>
-    /// <see cref="LocalReplicator.DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>
-    /// 
-    /// Lucene.Experimental
+    /// @lucene.experimental
     /// </remarks>
+    /// <seealso cref="IReplicator.CheckForUpdate"/>
+    /// <seealso cref="IReplicator.Release"/>
+    /// <seealso cref="LocalReplicator.DEFAULT_SESSION_EXPIRATION_THRESHOLD"/>
     public sealed class SessionToken
     {
         /// <summary>
         /// Id of this session.
         /// Should be passed when releasing the session, thereby acknowledging the 
-        /// <see cref="IReplicator"/>  that this session is no longer in use.
-        /// <see cref="IReplicator.Release"/>
+        /// <see cref="IReplicator"/> that this session is no longer in use.
         /// </summary>
+        /// <seealso cref="IReplicator.Release"/>
         public string Id { get; private set; }
 
         /// <summary>
@@ -54,11 +51,10 @@ namespace Lucene.Net.Replicator
         public IDictionary<string, IList<RevisionFile>> SourceFiles { get; private set; }
 
         /// <summary>
-        /// Constructor which deserializes from the given <see cref="DataInput"/>.
+        /// Constructor which deserializes from the given <see cref="IDataInput"/>.
         /// </summary>
-        /// <param name="reader"></param>
-        /// <exception cref="IOException"></exception>
-        public SessionToken(DataInputStream reader)
+        /// <exception cref="System.IO.IOException"></exception>
+        public SessionToken(DataInputStream reader) // LUCENENET TODO: API : IDataInput
         {
             Id = reader.ReadUTF();
             Version = reader.ReadUTF();
@@ -82,11 +78,9 @@ namespace Lucene.Net.Replicator
         }
 
         /// <summary>
-        /// Constructor with the given id and revision.
+        /// Constructor with the given <paramref name="id"/> and <paramref name="revision"/>.
         /// </summary>
-        /// <param name="id"></param>
-        /// <param name="revision"></param>
-        /// <exception cref="IOException"></exception>
+        /// <exception cref="System.IO.IOException"></exception>
         public SessionToken(string id, IRevision revision)
         {
             Id = id;
@@ -97,8 +91,7 @@ namespace Lucene.Net.Replicator
         /// <summary>
         /// Serialize the token data for communication between server and client.
         /// </summary>
-        /// <param name="writer"></param>
-        /// <exception cref="IOException"></exception>
+        /// <exception cref="System.IO.IOException"></exception>
         public void Serialize(DataOutputStream writer)
         {
             writer.WriteUTF(Id);