private void UnpackResponse(PersistedDataReader dataReader)
        {
            while (dataReader.ReadDataHeader())
            {
                lock (this)
                {
                    if (this.DimensionSet == null)
                    {
                        this.DimensionSet = dataReader.DimensionSet;
                    }

                    var remoteData = dataReader.LoadData <TInternal>();
                    if (!remoteData.Validate())
                    {
                        remoteData.Dispose();
                        throw new PersistedDataException("Remote data is invalid.");
                    }

                    if (this.data == null && this.DimensionSet.Equals(dataReader.DimensionSet))
                    {
                        this.DimensionSet = dataReader.DimensionSet;
                        this.data         = remoteData;
                    }
                    else
                    {
                        if (this.data == null)
                        {
                            this.data = new KeyedDataStore <TInternal>(this.DimensionSet, this.memoryStreamManager);
                        }

                        this.data.TakeData(remoteData);
                        remoteData.Dispose();
                    }
                }

                foreach (var responseSource in dataReader.Header.Sources)
                {
                    // NOTE: We use 'StartsWith' below because lots of data is currently marked with
                    // the non-FQDN machine name. We can change it to 'Equals' in the future.
                    var localSource =
                        this.Sources.FirstOrDefault(s =>
                                                    s.Name.StartsWith(responseSource.Name,
                                                                      StringComparison.OrdinalIgnoreCase));
                    if (localSource == null)
                    {
                        // XXX: here for testing because we have to query 'localhost' but won't ever get something good
                        // back. Yes, this is STUPID.
                        if (this.Sources.Count == 1 && this.Sources[0].Name == "localhost")
                        {
                            localSource = this.Sources[0];
                        }
                        else
                        {
                            throw new PersistedDataException(
                                      string.Format("Source {0} returned by server is unknown", responseSource.Name));
                        }
                    }
                    localSource.Status = responseSource.Status;
                }
            }
        }
Exemplo n.º 2
0
        private void ReadFromStorage(string filename, bool sourcesOnly)
        {
            KeyedDataStore <TInternal> readData = null;

            try
            {
                Events.Write.BeginLoadingData(filename);
                using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    using (var reader = new PersistedDataReader(stream, this.memoryStreamManager, this.DimensionSet))
                    {
                        // We'll only ever write one set of data, so we only try to read one.
                        if (reader.ReadDataHeader())
                        {
                            this.MergeSourceStatus(reader.Header.Sources);

                            if (sourcesOnly)
                            {
                                return;
                            }

                            if (typeof(TInternal) != reader.DataType)
                            {
                                throw new InvalidDataException(
                                          string.Format(
                                              "this.start={0},this.end={1}, hdr.start={2}, hdr.end={3}, this.type={4}, hdr.type={5}",
                                              this.StartTicks, this.EndTicks, reader.StartTime.Ticks,
                                              reader.EndTime.Ticks,
                                              typeof(TInternal), reader.DataType));
                            }

                            readData = reader.LoadData <TInternal>();
                            if (this.DimensionSet.Equals(reader.DimensionSet) &&
                                (this.data == null || this.data.Empty))
                            {
                                this.DimensionSet = reader.DimensionSet;
                                if (this.data != null)
                                {
                                    this.data.Dispose();
                                }
                                this.data = readData;
                                readData  = null;
                            }
                            else
                            {
                                if (this.data == null)
                                {
                                    this.data = new KeyedDataStore <TInternal>(this.DimensionSet,
                                                                               this.memoryStreamManager,
                                                                               "read data");
                                }
                                this.data.TakeData(readData);
                                this.data.Merge();
                            }
                        }
                    }
                }
            }
            catch (FileNotFoundException)
            {
                Events.Write.SealedDataFileMissing(filename);
            }
            catch (PersistedDataException ex)
            {
                Events.Write.PersistedDataException(ex);
                Events.Write.DiscardingIncompleteData(filename);
                if (this.data != null)
                {
                    this.data.Dispose();
                }
                this.data = null;
            }
            catch (OutOfMemoryException)
            {
                // TODO: this code is here to deal with file corruption issues, once checksums have been added and
                // are fully available it must be removed.
                File.Delete(filename);
                throw;
            }
            finally
            {
                if (readData != null)
                {
                    readData.Dispose();
                }
            }

            // if data is still null, some error happened loading the file (empty, missing, corrupt).
            // Just start over with clean data.
            if (this.data == null)
            {
                if (File.Exists(this.Filename))
                {
                    File.Delete(this.Filename);
                }

                this.data = new KeyedDataStore <TInternal>(this.DimensionSet, this.memoryStreamManager,
                                                           "placeholder for invalid data.");
            }

            Events.Write.EndLoadingData(filename);
        }