/// <summary>
        /// Pull out sorted batches from the RowSorter instance and save them using the IBatchHandler implementation.
        /// Also return the first batch as an output.
        /// </summary>
        /// <param name="rowSorter">RowSorter instance.</param>
        /// <returns>The first batch pulled from the RowSorter.</returns>
        private Batch SaveBatchesAndReturnFirstBatch(RowSorter rowSorter)
        {
            // Get an enumerator over the batch list.
            IEnumerable<RowSorter.SortedBatch> batchEnumerator = rowSorter.PullSortedBatches();

            // Prepare a batch header instance. The BatchCode will be the folder name under which we will write files corresponding
            // to each sorted batch. Every batch will have a knowledge that contains the information in the batch. So we have to combine 
            // the existing client knowledge with the batch knowledge before returning it back to the caller.
            var header = new BatchHeader
            {
                BatchCode = Guid.NewGuid(), // New batch code.
                BatchFileNames = new List<string>()
            };

            var batchList = new List<Batch>();

            Guid batchName = Guid.NewGuid();
            Guid nextBatchName = Guid.NewGuid();

            foreach (var sortedBatch in batchEnumerator)
            {
                // Create a new batch instance. 
                var b = new Batch
                {
                    BatchCode = header.BatchCode,
                    FileName = batchName.ToString(), // Random file name
                    LearnedKnowledge = sortedBatch.sortedDataSetKnowledge.Serialize(),
                    Data = sortedBatch.sortedDataSet,
                    ClientScopeName = _clientScopeName,
                    NextBatch = nextBatchName
                };

                header.BatchFileNames.Add(b.FileName);
                batchList.Add(b);

                // Set the batch names.
                batchName = nextBatchName;
                nextBatchName = Guid.NewGuid();
            }

            // If there are no batches, just return.
            if (0 == batchList.Count)
            {
                return null;
            }

            // Set properties for the last batch.
            batchList[batchList.Count - 1].IsLastBatch = true;
            batchList[batchList.Count - 1].NextBatch = null;

            // Only save if we have more than 1 batch.
            if (batchList.Count > 1)
            {
                // Save all but the first batch, since we are sending that to the client as a response to the current request.
                _batchHandler.SaveBatches(batchList.Skip(1).ToList(), header);
            }

            // Return the first batch.
            return batchList[0];
        }
예제 #2
0
        /// <summary>
        /// Gets the next batch in a sequence.
        /// </summary>
        /// <param name="batchCode">Batch code value</param>
        /// <param name="nextBatchSequenceNumber">Sequence number of the next batch</param>
        /// <returns>Batch information</returns>
        public Batch GetNextBatch(Guid batchCode, Guid nextBatchSequenceNumber)
        {
            // Create the batch directory.
            var path = Path.Combine(_batchSpoolDirectory, batchCode.ToString());

            if (!Directory.Exists(path))
            {
                // no batch found.
                return(null);
            }

            string      headerFilePath = Path.Combine(path, BATCH_HEADER_FILENAME);
            BatchHeader header         = null;

            if (File.Exists(headerFilePath))
            {
                var headerFormatter = new BinaryFormatter();
                using (var fileStream = new FileStream(headerFilePath, FileMode.Open, FileAccess.Read))
                {
                    header = headerFormatter.Deserialize(fileStream) as BatchHeader;
                }
            }

            if (null == header)
            {
                // no header
                return(null);
            }

            // Get the batch file name from the header.
            string batchFile = header.BatchFileNames.Where(b => new Guid(b) == nextBatchSequenceNumber).FirstOrDefault();

            if (String.IsNullOrEmpty(batchFile))
            {
                // missing batch file.
                return(null);
            }

            string batchFilePath = Path.Combine(path, batchFile);
            Batch  batch         = null;

            if (File.Exists(batchFilePath))
            {
                var formatter = new BinaryFormatter();
                using (var fileStream = new FileStream(batchFilePath, FileMode.Open, FileAccess.Read))
                {
                    batch = formatter.Deserialize(fileStream) as Batch;
                }
            }

            if (null != batch)
            {
                string filePath = Path.Combine(path, batch.FileName);
                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                }

                if (batch.IsLastBatch)
                {
                    // If this is the last batch then try to cleanup the directory.
                    CleanupBatchDirectory(path, headerFilePath, header);
                }
            }

            return(batch);
        }