protected void WriteAndReplaceDataFile()

in GVFS/GVFS.Common/FileBasedCollection.cs [75:156]


        protected void WriteAndReplaceDataFile(Func<IEnumerable<string>> getDataLines)
        {
            lock (this.fileLock)
            {
                try
                {
                    this.CloseDataFile();

                    bool tmpFileCreated = false;
                    int tmpFileCreateAttempts = 0;

                    bool tmpFileMoved = false;
                    int tmpFileMoveAttempts = 0;

                    Exception lastException = null;

                    while (!tmpFileCreated || !tmpFileMoved)
                    {
                        if (!tmpFileCreated)
                        {
                            tmpFileCreated = this.TryWriteTempFile(getDataLines, out lastException);
                            if (!tmpFileCreated)
                            {
                                if (this.Tracer != null && tmpFileCreateAttempts % IoFailureLoggingThreshold == 0)
                                {
                                    EventMetadata metadata = CreateEventMetadata(lastException);
                                    metadata.Add("tmpFileCreateAttempts", tmpFileCreateAttempts);
                                    this.Tracer.RelatedWarning(metadata, nameof(this.WriteAndReplaceDataFile) + ": Failed to create tmp file ... retrying");
                                }

                                ++tmpFileCreateAttempts;
                                Thread.Sleep(IoFailureRetryDelayMS);
                            }
                        }

                        if (tmpFileCreated)
                        {
                            try
                            {
                                if (this.fileSystem.FileExists(this.tempFilePath))
                                {
                                    this.fileSystem.MoveAndOverwriteFile(this.tempFilePath, this.DataFilePath);
                                    tmpFileMoved = true;
                                }
                                else
                                {
                                    if (this.Tracer != null)
                                    {
                                        EventMetadata metadata = CreateEventMetadata();
                                        metadata.Add("tmpFileMoveAttempts", tmpFileMoveAttempts);
                                        this.Tracer.RelatedWarning(metadata, nameof(this.WriteAndReplaceDataFile) + ": tmp file is missing. Recreating tmp file.");
                                    }

                                    tmpFileCreated = false;
                                }
                            }
                            catch (Win32Exception e)
                            {
                                if (this.Tracer != null && tmpFileMoveAttempts % IoFailureLoggingThreshold == 0)
                                {
                                    EventMetadata metadata = CreateEventMetadata(e);
                                    metadata.Add("tmpFileMoveAttempts", tmpFileMoveAttempts);
                                    this.Tracer.RelatedWarning(metadata, nameof(this.WriteAndReplaceDataFile) + ": Failed to overwrite data file ... retrying");
                                }

                                ++tmpFileMoveAttempts;
                                Thread.Sleep(IoFailureRetryDelayMS);
                            }
                        }
                    }

                    if (this.collectionAppendsDirectlyToFile)
                    {
                        this.OpenOrCreateDataFile(retryUntilSuccess: true);
                    }
                }
                catch (Exception e)
                {
                    throw new FileBasedCollectionException(e);
                }
            }
        }