Пример #1
0
        /// <summary>
        /// Constructor used for cloning
        /// </summary>
        /// <param name="cloneInput"></param>
        public SyncIndexInput(SyncIndexInput cloneInput)
        {
            _name          = cloneInput._name;
            _syncDirectory = cloneInput._syncDirectory;

            if (string.IsNullOrWhiteSpace(_name))
            {
                throw new ArgumentNullException(nameof(cloneInput._name));
            }
            if (_syncDirectory == null)
            {
                throw new ArgumentNullException(nameof(cloneInput._syncDirectory));
            }

            _fileMutex = SyncMutexManager.GrabMutex(cloneInput._syncDirectory, cloneInput._name);
            _fileMutex.WaitOne();

            try
            {
#if FULLDEBUG
                Trace.WriteLine($"Creating clone for {cloneInput._name}");
#endif
                _cacheDirIndexInput = (IndexInput)cloneInput._cacheDirIndexInput.Clone();
            }
            catch (Exception)
            {
                // sometimes we get access denied on the 2nd stream...but not always. I haven't tracked it down yet
                // but this covers our tail until I do
                Trace.TraceError($"Dagnabbit, falling back to memory clone for {cloneInput._name}");
            }
            finally
            {
                _fileMutex.ReleaseMutex();
            }
        }
Пример #2
0
        public override void Close()
        {
            _fileMutex.WaitOne();
            try
            {
#if FULLDEBUG
                Trace.WriteLine($"CLOSED READSTREAM local {_name}");
#endif
                _cacheDirIndexInput.Close();
                _cacheDirIndexInput = null;
                _syncDirectory      = null;
                GC.SuppressFinalize(this);
            }
            finally
            {
                _fileMutex.ReleaseMutex();
            }
        }
Пример #3
0
        protected override void Dispose(bool disposing)
        {
            _fileMutex.WaitOne();
            try
            {
#if FULLDEBUG
                _loggingService.Log(new LogEntry(LogLevel.Info, null, $"CLOSED READSTREAM local {_name}"));
#endif
                _cacheDirIndexInput.Dispose();
                _cacheDirIndexInput = null;
                _syncDirectory      = null;
                GC.SuppressFinalize(this);
            }
            finally
            {
                _fileMutex.ReleaseMutex();
            }
        }
Пример #4
0
        public SyncIndexOutput(SyncDirectory syncDirectory, string name)
        {
            if (syncDirectory == null)
            {
                throw new ArgumentNullException(nameof(syncDirectory));
            }

            //NOTE: _name was null here https://github.com/azure-contrib/AzureDirectory/issues/19
            // I have changed this to be correct now
            _name          = name;
            _syncDirectory = syncDirectory;
            _fileMutex     = SyncMutexManager.GrabMutex(_syncDirectory, _name);
            _fileMutex.WaitOne();
            try
            {
                // create the local cache one we will operate against...
                _cacheDirIndexOutput = CacheDirectory.CreateOutput(_name);
            }
            finally
            {
                _fileMutex.ReleaseMutex();
            }
        }
Пример #5
0
        public SyncIndexInput(SyncIndexInput cloneInput)
        {
            _fileMutex = SyncMutexManager.GrabMutex(cloneInput._syncDirectory, cloneInput._name);
            _fileMutex.WaitOne();

            try
            {
#if FULLDEBUG
                Debug.WriteLine($"Creating clone for {cloneInput._name}");
#endif
                _syncDirectory = cloneInput._syncDirectory;
                _indexInput    = cloneInput._indexInput.Clone() as IndexInput;
            }
            catch (Exception)
            {
                // sometimes we get access denied on the 2nd stream...but not always. I haven't tracked it down yet
                // but this covers our tail until I do
                Trace.Fail($"Dagnabbit, falling back to memory clone for {cloneInput._name}");
            }
            finally
            {
                _fileMutex.ReleaseMutex();
            }
        }
Пример #6
0
        /// <summary>
        /// Constructor to create Lucene IndexInput for reading index files
        /// </summary>
        /// <param name="directory"></param>
        /// <param name="name"></param>
        /// <remarks>
        /// This will not work for the segments.gen file because it doesn't compare to master and segments.gen is not write-once!
        /// Therefore do not use this class from a Directory instance for that file, see SyncDirectory.OpenInput
        /// </remarks>
        public SyncIndexInput(SyncDirectory directory, string name)
        {
            if (directory == null)
            {
                throw new ArgumentNullException(nameof(directory));
            }

            _name          = name;
            _syncDirectory = directory;

#if FULLDEBUG
            Trace.WriteLine($"opening {_name} ");
#endif
            _fileMutex = SyncMutexManager.GrabMutex(_syncDirectory, _name);
            _fileMutex.WaitOne();
            try
            {
                var fileName = _name;

                var  fileNeeded = false;
                bool fileExists;

                //Check the cache folder for the file existing, it doesn't exist then the file is needed
                if (!CacheDirectory.FileExists(fileName))
                {
                    fileNeeded = true;
                    fileExists = false;
                }
                else
                {
                    //Hrm, if the file already exists I think we're already in trouble but here's some logic to deal with that anyways.
                    fileExists = true;

                    //Normally we'd compare the file attributes to see if we need to override it but Lucene has write-once semantics so
                    //this is unecessary. If the file already exists locally then we will have to assume it is the correct file!

                    //fileNeeded = CompareExistingFileAttributes(fileName);
                    fileNeeded = false;
                }

                // if the file does not exist
                // or if it exists and it is older then the lastmodified time in the blobproperties (which always comes from the blob storage)
                if (fileNeeded)
                {
                    SyncLocally(fileName);
                    _cacheDirIndexInput = CacheDirectory.OpenInput(fileName);
                }
                else
                {
#if FULLDEBUG
                    Trace.WriteLine($"Using cached file for {_name}");
#endif

                    _cacheDirIndexInput = CacheDirectory.OpenInput(fileName);
                }
            }
            finally
            {
                _fileMutex.ReleaseMutex();
            }
        }
Пример #7
0
 /// <summary>
 /// Constructor to create Lucene IndexInput for reading index files
 /// </summary>
 /// <param name="directory"></param>
 /// <param name="name"></param>
 /// <remarks>
 /// This will not work for the segments.gen file because it doesn't compare to master and segments.gen is not write-once!
 /// Therefore do not use this class from a Directory instance for that file, see SyncDirectory.OpenInput
 /// </remarks>
 public SyncIndexInput(SyncDirectory directory, string name) : this(directory, name, new TraceLoggingService())
 {
 }
Пример #8
0
        public SyncIndexInput(SyncDirectory directory, string name)
        {
            if (directory == null)
            {
                throw new ArgumentNullException(nameof(directory));
            }

            _name          = name;
            _syncDirectory = directory;

#if FULLDEBUG
            Trace.WriteLine($"opening {_name} ");
#endif
            _fileMutex = SyncMutexManager.GrabMutex(_syncDirectory, _name);
            _fileMutex.WaitOne();
            try
            {
                var fileName = _name;

                var fFileNeeded = false;
                if (!CacheDirectory.FileExists(fileName))
                {
                    fFileNeeded = true;
                }
                else
                {
                    long cachedLength = CacheDirectory.FileLength(fileName);
                    long masterLength = MasterDirectory.FileLength(fileName);

                    if (cachedLength != masterLength)
                    {
                        fFileNeeded = true;
                    }
                    else
                    {
                        long cacheDate  = CacheDirectory.FileModified(fileName);
                        long masterDate = MasterDirectory.FileModified(fileName);

                        //we need to compare to the second instead of by ticks because when we call
                        //TouchFile in SyncIndexOutput this won't set the files to be identical
                        DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                        var      cachedLastModifiedUTC = start.AddMilliseconds(cacheDate).ToUniversalTime();
                        var      masterLastModifiedUTC = start.AddMilliseconds(masterDate).ToUniversalTime();

                        if (cachedLastModifiedUTC != masterLastModifiedUTC)
                        {
                            var timeSpan = masterLastModifiedUTC.Subtract(cachedLastModifiedUTC);

                            //NOTE: This heavily depends on TouchFile in SyncIndexOutput which sets both the
                            //master and slave files to be 'Now', in theory this operation shouldn't
                            //make the file times any bigger than 1 second
                            if (timeSpan.TotalSeconds > 2)
                            {
                                fFileNeeded = true;
                            }
                            else
                            {
#if FULLDEBUG
                                Debug.WriteLine(timeSpan.TotalSeconds);
#endif
                                // file not needed
                            }
                        }
                    }
                }

                // if the file does not exist
                // or if it exists and it is older then the lastmodified time in the blobproperties (which always comes from the blob storage)
                if (fFileNeeded)
                {
                    //get the master file stream
                    using (var masterStream = new StreamInput(MasterDirectory.OpenInput(fileName)))
                        using (var cacheStream = _syncDirectory.CreateCachedOutputAsStream(fileName))
                        {
                            //copy this to the cached file stream
                            masterStream.CopyTo(cacheStream);

                            cacheStream.Flush();
                            Debug.WriteLine($"GET {_name} RETREIVED {cacheStream.Length} bytes");
                        }

                    // and open it as an input
                    _indexInput = CacheDirectory.OpenInput(fileName);
                }
                else
                {
#if FULLDEBUG
                    Debug.WriteLine($"Using cached file for {_name}");
#endif

                    // open the file in read only mode
                    _indexInput = CacheDirectory.OpenInput(fileName);
                }
            }
            finally
            {
                _fileMutex.ReleaseMutex();
            }
        }
Пример #9
0
 public SyncIndexOutput(SyncDirectory syncDirectory, string name) : this(syncDirectory, name, new TraceLoggingService())
 {
 }