예제 #1
0
        /// <summary>
        /// start service host by serviceInfo
        /// </summary>
        /// <param name="serviceInfo"></param>
        /// <returns></returns>
        public static int OpenService(ServiceInfo serviceInfo)
        {
            void SetEnvironment()
            {
                if (serviceInfo.Environment == null)
                {
                    TraceHelper.TraceVerbose(Utility.GetJobId(), "No environment fond.");
                    return;
                }

                foreach (var env in serviceInfo.Environment)
                {
                    Environment.SetEnvironmentVariable(env.Key, env.Value);
                    TraceHelper.TraceVerbose(Utility.GetJobId(), $"Set environment {env.Key}={env.Value}.");
                }
            }

            async Task <string[]> DownloadDependFiles()
            {
                if (serviceInfo.DependFiles != null && serviceInfo.DependFiles.Any())
                {
                    var downloadTasks = serviceInfo.DependFiles.Select(fileInfo => StandaloneDataClient.DownloadFileFromSasAsync(
                                                                           fileInfo.Value,
                                                                           Path.Combine(Path.Combine(Path.GetTempPath(), "ExcelOffloading"), Path.GetFileName(fileInfo.Key))));
                    return(await Task.WhenAll(downloadTasks));
                }
                else
                {
                    TraceHelper.TraceVerbose(Utility.GetJobId(), "No depend files fond.");
                    return(new string[0]);
                }
            }

            Environment.SetEnvironmentVariable(Constant.JobIDEnvVar, serviceInfo.JobId.ToString());
            Environment.SetEnvironmentVariable(Constant.TaskIDEnvVar, serviceInfo.TaskId.ToString());
            Environment.SetEnvironmentVariable(Constant.CoreIdsEnvVar, serviceInfo.CoreId.ToString());
            Environment.SetEnvironmentVariable(Constant.ServiceConfigFileNameEnvVar, serviceInfo.FileName);
            if (!string.IsNullOrEmpty(serviceInfo.RegistrationPath))
            {
                Environment.SetEnvironmentVariable(Constant.RegistryPathEnv, serviceInfo.RegistrationPath);
            }
            else
            {
                Environment.SetEnvironmentVariable(Constant.RegistryPathEnv, Path.Combine(Environment.CurrentDirectory, defaultRegistryPath));
            }

            TraceHelper.TraceVerbose(Utility.GetJobId(), $"Set {Constant.RegistryPathEnv} to {Environment.GetEnvironmentVariable(Constant.RegistryPathEnv)}");

            // use default values for following environment variables
            Environment.SetEnvironmentVariable(Constant.ProcNumEnvVar, "1");
            Environment.SetEnvironmentVariable(Constant.NetworkPrefixEnv, Constant.EnterpriseNetwork);
            Environment.SetEnvironmentVariable(Constant.ServiceInitializationTimeoutEnvVar, "60000");
            Environment.SetEnvironmentVariable(Constant.CancelTaskGracePeriodEnvVar, "15");
            Environment.SetEnvironmentVariable(Constant.ServiceConfigMaxMessageEnvVar, "65536");
            Environment.SetEnvironmentVariable(Constant.ServiceConfigServiceOperatonTimeoutEnvVar, "86400000");

            // the local host process won't be preempted by the scheduler
            Environment.SetEnvironmentVariable(Constant.EnableMessageLevelPreemptionEnvVar, bool.FalseString);

            SetEnvironment();
            var dependFilePath = DownloadDependFiles().GetAwaiter().GetResult();

            Environment.SetEnvironmentVariable(Constant.DataServiceSharedFileEnvVar, string.Join(";", dependFilePath));

#if DEBUG
            #region For EndpointNotFoundException test
            try
            {
                string strWaitPeriod = ConfigurationManager.AppSettings["Test_WaitPeriodBeforeStartup"];
                if (!string.IsNullOrEmpty(strWaitPeriod))
                {
                    int waitPeriodInMilliSecond = int.Parse(strWaitPeriod);
                    Console.Error.WriteLine("Debug: waiting {0} ms before startup service", waitPeriodInMilliSecond);
                    Thread.Sleep(waitPeriodInMilliSecond);
                }
            }
            catch (Exception)
            {
                // do nothing
            }
            #endregion
#endif

            jobId = Utility.GetJobId();

            string serviceConfigFullPath;

            bool onAzure = SoaHelper.IsOnAzure();
            TraceHelper.TraceInfo(
                jobId,
                "OnAzure = {0}",
                onAzure);

            bool bOpenDummy = false;
            try
            {
                string serviceConfigFileName = Environment.GetEnvironmentVariable(Constant.ServiceConfigFileNameEnvVar);

                // exit if no such env var
                if (string.IsNullOrEmpty(serviceConfigFileName))
                {
                    bOpenDummy = true;
                    Console.Error.WriteLine(StringTable.ServiceConfigFileNameNotSpecified);
                    return(ErrorCode.ServiceHost_ServiceConfigFileNameNotSpecified);
                }

                if (onAzure)
                {
                    string localCacheFolder = Utility.GetServiceLocalCacheFullPath();
                    serviceConfigFullPath = Path.Combine(localCacheFolder, serviceConfigFileName);
                }
                else
                {
                    serviceConfigFullPath = GetServiceInfo(serviceConfigFileName);
                }

                if (!File.Exists(serviceConfigFullPath))
                {
                    bOpenDummy = true;
                    Console.Error.WriteLine(StringTable.CantFindServiceRegistrationFile, serviceConfigFullPath);
                    return(ErrorCode.ServiceHost_ServiceRegistrationFileNotFound);
                }

                TraceHelper.TraceInfo(
                    jobId,
                    "ServiceConfigFullPath = {0}",
                    serviceConfigFullPath);
                ServiceRegistration registration;
                string assemblyFullPath;
                int    errorCode = Utility.GetServiceRegistration(serviceConfigFullPath, onAzure, out registration, out assemblyFullPath);
                if (errorCode != ErrorCode.Success)
                {
                    bOpenDummy = true;
                    return(errorCode);
                }

                // Open the host in another application domain
                AppDomain domain = CreateNewServiceDomain(serviceConfigFullPath, assemblyFullPath);



                using (CcpServiceHostWrapper host =
                           CreateInstanceFromAndUnwrap <CcpServiceHostWrapper>(
                               domain,
                               Assembly.GetExecutingAssembly().Location,
                               serviceConfigFullPath,
                               onAzure,
                               ServiceHostRuntimeConfiguration.Standalone))
                {
                    host.Initialize();
                    host.Run();
                    TraceHelper.TraceInfo(
                        jobId,
                        "Sleep...");

                    if (ServiceHostRuntimeConfiguration.Standalone)
                    {
                        // Endless listening, till service info deleted.
                        while (true)
                        {
                            lock (ServiceInfo.s_lock)
                            {
                                if (SvcHostMgmtRestServer.Info == null)
                                {
                                    TraceHelper.TraceInfo(
                                        jobId,
                                        "Close service host!");
                                    host.Dispose();
                                    return(0);
                                }
                            }
                            Thread.Sleep(1000);
                        }
                    }
                    else
                    {
                        // Endless waiting, till it's being killed
                        Thread.Sleep(Timeout.Infinite);
                    }
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);

                TraceHelper.TraceError(
                    jobId,
                    e.ToString());

                // Failed to open service, fall back to open an dummy service.
                bOpenDummy = true;
            }
            finally
            {
                if (bOpenDummy)
                {
                    OpenDummyService(onAzure);
                }
            }

            return(0);
        }