Beispiel #1
0
 /// <summary>
 /// Virtual Cache Constructor. Virtual Cache now defaults to being a Memory Extender.
 /// I.e. - Persisted static property defaults to false. Set VirtualCache.Persisted to true
 /// if wanting to persist the cached data across application runs.
 /// </summary>
 /// <param name="storePath">Data Store URI path or the Store name.</param>
 /// <param name="clusteredData">true (default) will configure the Store to save
 /// data together with the Keys in the Key Segment (a.k.a. - clustered),
 /// false will configure Store to save data in its own Data Segment. For small to medium sized
 /// data, Clustered is recommended, otherwise set this to false.</param>
 /// <param name="storeFileName">Valid complete file path where to create the File to contain the data Store.
 /// It will be created if it does not exist yet. Leaving this blank will create the Store within the default
 /// SOP SystemFile, or in the referenced File portion of the storePath, if storePath has a directory path.</param>
 /// <param name="fileConfig">File Config should contain description how to manage data allocations on disk and B-Tree
 /// settings for all the Data Stores of the File. If not set, SOP will use the default configuration.</param>
 public VirtualCacheWithBackgroundRefresh(string storePath, bool clusteredData = true, string storeFileName = null, Sop.Profile fileConfig = null)
     : base(storePath, clusteredData, storeFileName, fileConfig)
 {
     Server.SystemFile.Store.Locker.Invoke(() =>
     {
         var storeTimeStampPath = string.Format("{0}ByDate", storePath);
         Logger.Verbose("Creating/retrieving store {0}.", storeTimeStampPath);
         _storeKeysByDate = Server.StoreNavigator.GetStore <long, CacheEntryReference>(
             storeTimeStampPath,
             new StoreParameters <long>
         {
             IsDataInKeySegment = clusteredData,
             AutoFlush          = !clusteredData,
             MruManaged         = false
         });
     });
     if (isMultiThreaded)
     {
         Processor.Register(this);
     }
 }
Beispiel #2
0
        /// <summary>
        /// Dispose this Virtual Cache instance. Update and On Idle tasks are waited for completion if
        /// ongoing during time of Dispose. Transaction is committed if pending and Virtual Cache is
        /// set to persist cached items to disk (parameter persisted was set to true on ctor).
        ///
        /// The cache entries' data Stores are closed then disposed off as well.
        /// </summary>
        override public void Dispose()
        {
            bool needsCommit = false;

            if (Processor != null)
            {
                needsCommit = Processor.Unregister(this);
            }
            #region wait for ongoing tasks to finish & dispose them after.
            if (!Persisted)
            {
                ExitSignal = true;
            }
            if (_updateTimeStampTask != null)
            {
                // this is a quick task, no need to set a timeout.
                if (_updateTimeStampTask.Status == TaskStatus.Running)
                {
                    _updateTimeStampTask.Wait();
                }
                _updateTimeStampTask.Dispose();
                _updateTimeStampTask = null;
            }
            if (_onIdleTask != null)
            {
                // this is a quick task, no need to set a timeout.
                if (_onIdleTask.Status == TaskStatus.Running ||
                    _onIdleTask.Status == TaskStatus.WaitingToRun)
                {
                    _onIdleTask.Wait();
                }
                _onIdleTask.Dispose();
                _onIdleTask = null;
            }

            // flush all in-flight changes if persisted...
            if (!_store.Locker.TransactionRollback && Persisted)
            {
                ProcessBatch(true);
                ProcessExpiredEntries();
            }
            #endregion
            if (_storeKeysByDate != null)
            {
                Logger.Verbose("Disposing Store {0}.", _storeKeysByDate.Name);
                if (!Persisted)
                {
                    ((OnDisk.Algorithm.SortedDictionary.ISortedDictionaryOnDisk)_storeKeysByDate.RealObject).IsUnloading = true;
                }
                _storeKeysByDate.Dispose();
                _storeKeysByDate = null;
            }
            if (_store != null)
            {
                Logger.Verbose("Disposing Store {0}.", _store.Name);
                if (!Persisted)
                {
                    ((OnDisk.Algorithm.SortedDictionary.ISortedDictionaryOnDisk)_store.RealObject).IsUnloading = true;
                }
                _store.Dispose();
                _store = null;
            }
            if (needsCommit)
            {
                if (Persisted)
                {
                    // commit if Persisted is true.
                    Commit(true);
                }
                else
                {
                    // if in memextender, destroy Server to cause removal of data file.
                    lock (_serverLocker)
                    {
                        // unload any inflight changes in memory, no need to save on dispose.
                        ((OnDisk.ObjectServer)((Sop.ObjectServer)_server).RealObjectServer).Unload();
                        _server.Dispose();
                        _server = null;
                    }
                }
            }
            if (Logger != null)
            {
                Logger.Dispose();
                Logger = null;
            }
        }