public void Shutdown() { if(_status != DekiInstanceStatus.RUNNING) { throw new InvalidOperationException("bad state"); } TimerFactory.Dispose(); _storage.Shutdown(); // run shudown code ServiceBL.StopServices(); // reset instance fields _status = DekiInstanceStatus.STOPPED; RunningServices.Clear(); _configCache = null; _storage = null; Cache.Dispose(); SearchCache.Dispose(); _eventSink.InstanceShutdown(DreamContext.Current.StartTime); _eventSink = null; // unregister the instance to database mapping if(null != _sessionFactory) { _sessionFactory.Dispose(); _sessionFactory = null; } }
/// <summary> /// Calls methods to perform initial init of a wiki instance including db updates, etc /// </summary> public void Startup(DekiContext context) { if(context == null) { throw new ArgumentNullException("context"); } if(_status != DekiInstanceStatus.CREATED) { throw new InvalidOperationException("bad state"); } _status = DekiInstanceStatus.INITIALIZING; // run startup code try { // create the IDekiDataSessionFactory for this instance Type typeMySql = Type.GetType("MindTouch.Deki.Data.MySql.MySqlDekiDataSessionFactory, mindtouch.deki.data.mysql", true); Type typeCaching = null; try { typeCaching = Type.GetType("MindTouch.Deki.Data.Caching.CachingDekiDataSessionFactory, mindtouch.data.caching", false); } catch(Exception x) { Log.Warn("The caching library was found but could not be loaded. Check that its version matches the version of your MindTouch API", x); } IDekiDataSessionFactory factoryMySql = (IDekiDataSessionFactory)typeMySql.GetConstructor(Type.EmptyTypes).Invoke(null); IDekiDataSessionFactory factoryLogging = new LoggingDekiDataSessionFactory(factoryMySql); if(typeCaching != null) { IDekiDataSessionFactory factoryCaching = (IDekiDataSessionFactory)typeCaching.GetConstructor(new[] { typeof(IDekiDataSessionFactory) }).Invoke(new object[] { factoryLogging }); _sessionFactory = factoryCaching; } else { _sessionFactory = factoryLogging; } _sessionFactory.Initialize(Config ?? _deki.Config, new DekiInstanceSettings()); try { DbUtils.CurrentSession = _sessionFactory.CreateSession(); // check for 'api-key' if(string.IsNullOrEmpty(ApiKey) && string.IsNullOrEmpty(_deki.MasterApiKey)) { throw new ArgumentNullException("apikey", "Missing apikey for wiki instance. Please ensure that you have a global <apikey> defined (in the service settings xml file) or an instance specific key in the config table as 'security/api-key'."); } // check if a storage config section was provided (default storage is filesystem provider) XDoc storageConfig; switch(ConfigBL.GetInstanceSettingsValue("storage/@type", ConfigBL.GetInstanceSettingsValue("storage/type", "default"))) { case "default": string defaultAttachPath = Path.Combine(_deki.DekiPath, "attachments"); storageConfig = new XDoc("config") .Elem("path", defaultAttachPath) .Elem("cache-path", Path.Combine(defaultAttachPath, ".cache")); _storage = new FSStorage(storageConfig); break; case "fs": string fsPath = ConfigBL.GetInstanceSettingsValue("storage/fs/path", null); //Replace a $1 with the wiki name fsPath = string.Format(Dream.PhpUtil.ConvertToFormatString(fsPath ?? string.Empty), Id); storageConfig = new XDoc("config") .Elem("path", fsPath) .Elem("cache-path", ConfigBL.GetInstanceSettingsValue("storage/fs/cache-path", null)); _storage = new FSStorage(storageConfig); break; case "s3": storageConfig = new XDoc("config") .Elem("publickey", ConfigBL.GetInstanceSettingsValue("storage/s3/publickey", null)) .Elem("privatekey", ConfigBL.GetInstanceSettingsValue("storage/s3/privatekey", null)) .Elem("bucket", ConfigBL.GetInstanceSettingsValue("storage/s3/bucket", null)) .Elem("prefix", string.Format(Dream.PhpUtil.ConvertToFormatString(ConfigBL.GetInstanceSettingsValue("storage/s3/prefix", string.Empty)), DekiContext.Current.Instance.Id)) .Elem("timeout", ConfigBL.GetInstanceSettingsValue("storage/s3/timeout", null)) .Elem("allowredirects", ConfigBL.GetInstanceSettingsValue("storage/s3/allowredirects", null)) .Elem("redirecttimeout", ConfigBL.GetInstanceSettingsValue("storage/s3/redirecttimeout", null)); _storage = new S3Storage(storageConfig); break; default: throw new ArgumentException("Storage provider unknown or not defined (key: storage/type)", "storage/type"); } HomePageId = DbUtils.CurrentSession.Pages_HomePageId; } finally { if(null != DbUtils.CurrentSession) { DbUtils.CurrentSession.Dispose(); DbUtils.CurrentSession = null; } } _eventSink = new DekiChangeSink(Id, DekiContext.Current.ApiUri, DekiContext.Current.Deki.PubSub.At("publish").WithCookieJar(DekiContext.Current.Deki.Cookies)); _eventSink.InstanceStarting(DreamContext.Current.StartTime); } catch { // we failed to initialize _status = DekiInstanceStatus.ABANDONED; throw; } // set state to initializing _status = DekiInstanceStatus.INITIALIZING; }