예제 #1
0
        private string GetLogFile()
        {
            DiagnosticsHelper.TraceInformation("Getting log file base path");
            var localStorage = RoleEnvironment.GetLocalResource(Settings.LogDirSetting);
            var logfile      = Path.Combine(localStorage.RootPath + @"\", Settings.MongodLogFileName);

            return("\"" + logfile + "\"");
        }
예제 #2
0
        private void StartMongoD()
        {
            var mongoAppRoot = Path.Combine(
                Environment.GetEnvironmentVariable("RoleRoot") + @"\",
                Settings.MongoDBBinaryFolder);
            var mongodPath = Path.Combine(mongoAppRoot, @"mongod.exe");

            var blobPath = GetMongoDataDirectory();

            var logFile = GetLogFile();

            var logLevel = Settings.MongodLogLevel;

            string cmdline;

            if (RoleEnvironment.IsEmulated)
            {
                cmdline = String.Format(Settings.MongodCommandLineEmulated,
                                        mongodPort,
                                        blobPath,
                                        logFile,
                                        replicaSetName,
                                        logLevel);
            }
            else
            {
                cmdline = String.Format(Settings.MongodCommandLineCloud,
                                        mongodPort,
                                        blobPath,
                                        logFile,
                                        replicaSetName,
                                        logLevel);
            }

            DiagnosticsHelper.TraceInformation(string.Format("Launching mongod as {0} {1}", mongodPath, cmdline));

            // launch mongo
            try
            {
                mongodProcess = new Process()
                {
                    StartInfo = new ProcessStartInfo(mongodPath, cmdline)
                    {
                        UseShellExecute  = false,
                        WorkingDirectory = mongoAppRoot,
                        CreateNoWindow   = false
                    }
                };
                mongodProcess.Start();
            }
            catch (Exception e)
            {
                DiagnosticsHelper.TraceError("Can't start Mongo: " + e.Message);
                throw new ApplicationException("Can't start mongo: " + e.Message); // throwing an exception here causes the VM to recycle
            }
        }
예제 #3
0
        private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
        {
            Func <RoleEnvironmentConfigurationSettingChange, bool> changeIsExempt =
                x => !Settings.ExemptConfigurationItems.Contains(x.ConfigurationSettingName);
            var environmentChanges = e.Changes.OfType <RoleEnvironmentConfigurationSettingChange>();

            e.Cancel = environmentChanges.Any(changeIsExempt);
            DiagnosticsHelper.TraceInformation("Role config changing. Cancel set to {0}",
                                               e.Cancel);
        }
예제 #4
0
        public override bool OnStart()
        {
            DiagnosticsHelper.TraceInformation("MongoWorkerRole onstart called");

            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

            // Set the maximum number of concurrent connections
            ServicePointManager.DefaultConnectionLimit = 12;

            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
            {
                configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
            });

            RoleEnvironment.Changing += RoleEnvironmentChanging;
            RoleEnvironment.Changed  += RoleEnvironmentChanged;

            replicaSetName = RoleEnvironment.GetConfigurationSettingValue(Constants.ReplicaSetNameSetting);
            instanceId     = ConnectionUtilities.ParseNodeInstanceId(RoleEnvironment.CurrentRoleInstance.Id);

            DiagnosticsHelper.TraceInformation("ReplicaSetName={0}, InstanceId={1}",
                                               replicaSetName, instanceId);

            SetHostAndPort();
            DiagnosticsHelper.TraceInformation("Obtained host={0}, port={1}", mongodHost, mongodPort);

            StartMongoD();
            DiagnosticsHelper.TraceInformation("Mongod process started");

            // Need to ensure MongoD is up here
            DatabaseHelper.EnsureMongodIsListening(replicaSetName, instanceId, mongodPort);

            if ((instanceId == 0) && !DatabaseHelper.IsReplicaSetInitialized(mongodPort))
            {
                try
                {
                    DatabaseHelper.RunInitializeCommandLocally(replicaSetName, mongodPort);
                    DiagnosticsHelper.TraceInformation("RSInit issued successfully");
                }
                catch (MongoCommandException e)
                {
                    //Ignore exceptions caught on rs init for now
                    DiagnosticsHelper.TraceWarning(
                        "Exception {0} on RSInit with {1}",
                        e.Message, e.StackTrace);
                }
            }

            DiagnosticsHelper.TraceInformation("Done with OnStart");
            return(true);
        }
예제 #5
0
        public override void Run()
        {
            DiagnosticsHelper.TraceInformation("MongoWorkerRole run method called");
            var mongodRunning = CheckIfMongodRunning();

            while (mongodRunning || !Settings.RecycleRoleOnExit)
            {
                Thread.Sleep(runSleepInterval);
                mongodRunning = CheckIfMongodRunning();
            }

            DiagnosticsHelper.TraceWarning("MongoWorkerRole run method exiting");
        }
예제 #6
0
        private void RoleEnvironmentChanged(object sender, RoleEnvironmentChangedEventArgs e)
        {
            // Get the list of configuration changes
            var settingChanges = e.Changes.OfType <RoleEnvironmentConfigurationSettingChange>();

            foreach (var settingChange in settingChanges)
            {
                var settingName = settingChange.ConfigurationSettingName;
                var value       = RoleEnvironment.GetConfigurationSettingValue(settingName);
                DiagnosticsHelper.TraceInformation(
                    "Setting {0} now has value {1} ",
                    settingName,
                    value);
                if (settingName == Settings.LogVerbositySetting)
                {
                    var logLevel = Utilities.GetLogVerbosity(value);
                    if (logLevel != null)
                    {
                        if (logLevel != Settings.MongodLogLevel)
                        {
                            Settings.MongodLogLevel = logLevel;
                            DatabaseHelper.SetLogLevel(mongodPort, logLevel);
                        }
                    }
                }
                if (settingName == Settings.RecycleSetting)
                {
                    Settings.RecycleRoleOnExit = Utilities.GetRecycleFlag(RoleEnvironment.GetConfigurationSettingValue(settingName));
                }
            }


            // Get the list of topology changes
            var topologyChanges = e.Changes.OfType <RoleEnvironmentTopologyChange>();

            foreach (var topologyChange in topologyChanges)
            {
                var roleName = topologyChange.RoleName;
                DiagnosticsHelper.TraceInformation(
                    "Role {0} now has {1} instance(s)",
                    roleName,
                    RoleEnvironment.Roles[roleName].Instances.Count);
            }
        }
예제 #7
0
        private string GetMongoDataDirectory()
        {
            DiagnosticsHelper.TraceInformation("Getting db path");
            var dataBlobName  = string.Format(Constants.MongoDataBlobName, instanceId);
            var containerName = ConnectionUtilities.GetDataContainerName(replicaSetName);

            mongodDataDriveLetter = Utilities.GetMountedPathFromBlob(
                Settings.LocalCacheDirSetting,
                Constants.MongoDataCredentialSetting,
                containerName,
                dataBlobName,
                Settings.MaxDBDriveSizeInMB,
                out mongoDataDrive);
            DiagnosticsHelper.TraceInformation("Obtained data drive as {0}", mongodDataDriveLetter);
            var dir = Directory.CreateDirectory(Path.Combine(mongodDataDriveLetter, @"data"));

            DiagnosticsHelper.TraceInformation("Data directory is {0}", dir.FullName);
            return(dir.FullName);
        }
예제 #8
0
        private void RoleEnvironmentChanged(object sender, RoleEnvironmentChangedEventArgs e)
        {
            // Get the list of configuration changes
            var settingChanges = e.Changes.OfType <RoleEnvironmentConfigurationSettingChange>();

            foreach (var settingChange in settingChanges)
            {
                var settingName = settingChange.ConfigurationSettingName;
                var value       = RoleEnvironment.GetConfigurationSettingValue(settingName);
                DiagnosticsHelper.TraceInformation(
                    "Setting {0} now has value {1} ",
                    settingName,
                    value);
                if (settingName == Settings.LogVerbositySetting)
                {
                    var logLevel = Utilities.GetLogVerbosity(value);
                    if (logLevel != null)
                    {
                        if (logLevel != Settings.MongodLogLevel)
                        {
                            Settings.MongodLogLevel = logLevel;
                            DatabaseHelper.SetLogLevel(mongodPort, logLevel);
                        }
                    }
                }
                if (settingName == Settings.RecycleSetting)
                {
                    Settings.RecycleRoleOnExit = Utilities.GetRecycleFlag(RoleEnvironment.GetConfigurationSettingValue(settingName));
                }
            }


            // Get the list of topology changes
            var topologyChanges = e.Changes.OfType <RoleEnvironmentTopologyChange>();

            foreach (var topologyChange in topologyChanges)
            {
                var roleName  = topologyChange.RoleName;
                var roleCount = RoleEnvironment.Roles[roleName].Instances.Count;
                DiagnosticsHelper.TraceInformation(
                    "Role {0} now has {1} instance(s)",
                    roleName,
                    roleCount);
                if (instanceId == 0 && roleName.Equals(Constants.MongoDBWorkerRoleName))
                {
                    DiagnosticsHelper.TraceInformation(
                        "{0} instance count changed from {1} {2}",
                        roleName,
                        replicaSetRoleCount,
                        roleCount);
                    if (replicaSetRoleCount != roleCount)
                    {
                        if (replicaSetInitialized)
                        {
                            replicaSetRoleCount = DatabaseHelper.ReconfigReplicaSet(replicaSetName, mongodPort);
                            DiagnosticsHelper.TraceInformation("RS reconfig succeeded. New role count {0}", replicaSetRoleCount);
                        }
                        else
                        {
                            // config changed even before rs init
                            DiagnosticsHelper.TraceWarning("Role count change before rs init.");
                        }
                    }
                }
            }
        }
예제 #9
0
        internal static string GetMountedPathFromBlob(
            string localCachePath,
            string cloudDir,
            string containerName,
            string blobName,
            int driveSize,
            out CloudDrive mongoDrive)
        {
            DiagnosticsHelper.TraceInformation(
                "In mounting cloud drive for dir {0} on {1} with {2}",
                cloudDir,
                containerName,
                blobName);

            CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting(cloudDir);

            var blobClient = storageAccount.CreateCloudBlobClient();

            DiagnosticsHelper.TraceInformation("Get container");
            // this should be the name of your replset
            var driveContainer = blobClient.GetContainerReference(containerName);

            // create blob container (it has to exist before creating the cloud drive)
            try
            {
                driveContainer.CreateIfNotExist();
            }
            catch (StorageException e)
            {
                DiagnosticsHelper.TraceInformation(
                    "Container creation failed with {0} {1}",
                    e.Message,
                    e.StackTrace);
            }

            var mongoBlobUri = blobClient.GetContainerReference(containerName).GetPageBlobReference(blobName).Uri.ToString();

            DiagnosticsHelper.TraceInformation("Blob uri obtained {0}", mongoBlobUri);

            // create the cloud drive
            mongoDrive = storageAccount.CreateCloudDrive(mongoBlobUri);
            try
            {
                mongoDrive.CreateIfNotExist(driveSize);
            }
            catch (CloudDriveException e)
            {
                DiagnosticsHelper.TraceInformation(
                    "Drive creation failed with {0} {1}",
                    e.Message,
                    e.StackTrace);
            }

            DiagnosticsHelper.TraceInformation("Initialize cache");
            var localStorage = RoleEnvironment.GetLocalResource(localCachePath);

            CloudDrive.InitializeCache(localStorage.RootPath.TrimEnd('\\'),
                                       localStorage.MaximumSizeInMegabytes);

            // mount the drive and get the root path of the drive it's mounted as
            try
            {
                DiagnosticsHelper.TraceInformation(
                    "Trying to mount blob as azure drive");
                var driveLetter = mongoDrive.Mount(localStorage.MaximumSizeInMegabytes,
                                                   DriveMountOptions.None);
                DiagnosticsHelper.TraceInformation(
                    "Write lock acquired on azure drive, mounted as {0}",
                    driveLetter);
                return(driveLetter);
            }
            catch (CloudDriveException e)
            {
                DiagnosticsHelper.TraceCritical(
                    "Failed to mount cloud drive with {0} {1}",
                    e.Message,
                    e.StackTrace);
                throw;
            }
        }