Ejemplo n.º 1
0
        /// <summary>
        /// Add a binary to the file and store the data in the data cache.
        ///
        /// It should be noted that there is a failure mode in which the commit of the binary details file could work, but the commit
        /// of the data could fail. This would result in the record of the binary being stored, but no actual data would be present
        /// in the files. This would manifest itself as an exception, which is caught here, and an attempt to remove the binary details
        /// is made. In the event that the data commit fails because of catastrophic failure or power loss, the recovery attempt may not
        /// take place or may itself fail. This would leave the data in an inconsistent state, but only for the most recently saved binary.
        ///
        /// On open, the most recently saved binary is checked, to see if the data is present. If it is not, it is removed at that stage.
        /// On the assumption that the failure to
        /// </summary>
        /// <param name="details"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public Guid Add(BinaryStorageClass details, byte[] data)
        {
            lock (_lock)
            {
                try
                {
                    if (details.Id == Guid.Empty)
                    {
                        details.Id = Guid.NewGuid();
                    }
                    details.FileIndex        = _nextIndex++;
                    details.FirstDataBlockId = _data.Write(data);
                    _file.Write(details);
                    _file.Commit();

                    _binaries.Add(details.Id, details);

                    //Make sure that the file is removed if commit fails.
                    Action reverseOutFile = () =>
                    {
                        // ReSharper disable AccessToDisposedClosure
                        //Note: Resharper cannot determine whether the lambda will outlive the try/catch block. It can't so we can ignore the warning.
                        _file.Delete(details);
                        _file.Commit();
                        // ReSharper restore AccessToDisposedClosure
                    };

                    using (var reverse = new OnError(reverseOutFile))
                    {
                        _data.Commit();
                        reverse.Commit(); //if we reach here, the commit worked and we don't need to reverse out the file.
                    }

                    return(details.Id);
                }
                catch
                {
                    _file.Dispose();
                    _file = null;
                    Open(_path);
                    _data.ReOpen();
                    throw;
                }
            }
        }
Ejemplo n.º 2
0
 public void Commit()
 {
     _file.Commit();
 }