internal void SaveServiceInstance(
            ServiceExecutionHost host,
            Guid instanceID,
            Guid parentInstanceID,
            ServiceConfiguration config,
            ServiceStateInfo stateInfo,
            SchedulingInfo schedulingInfo
            )
        {
            // The first time we save write the configuration to XML. Otherwise ignore.
            string serializedConfig = null;

            if (stateInfo.State == ServiceState.Initializing)
            {
                var stringWriter = new StringWriter();
                using (var writer = new XmlTextWriter(stringWriter))
                    new NetDataContractSerializer().WriteObject(writer, config);
                serializedConfig = stringWriter.ToString();
            }

            var env = this.EnvironmentConfiguration;

            using (var connection = new SqlConnection(env.ConnectionString))
            {
                var command = new SqlCommand(env.SP_InstanceSave, connection);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddWithValue("@instanceID", instanceID.ToString("N"));
                command.Parameters.AddWithValue("@parentInstanceID", SqlUtility.SqlValue(parentInstanceID, Guid.Empty, () => parentInstanceID.ToString("N")));
                command.Parameters.AddWithValue("@profileID", SqlUtility.SqlValue(config.Profile, () => config.Profile.ProfileID.ToString("N")));
                command.Parameters.AddWithValue("@serviceName", config.ServiceName);
                command.Parameters.AddWithValue("@hostName", host.HostName);
                command.Parameters.AddWithValue("@hostGuid", host.HostGuid.ToString("N"));
                command.Parameters.AddWithValue("@progress", stateInfo.Progress);
                command.Parameters.AddWithValue("@state", stateInfo.State);
                command.Parameters.AddWithValue("@outcome", stateInfo.Outcome);
                command.Parameters.AddWithValue("@timeInitialized", SqlUtility.SqlValue(stateInfo.TimeInitialized, DateTime.MinValue));
                command.Parameters.AddWithValue("@timeStarted", SqlUtility.SqlValue(stateInfo.TimeStarted, DateTime.MinValue));
                command.Parameters.AddWithValue("@timeEnded", SqlUtility.SqlValue(stateInfo.TimeEnded, DateTime.MinValue));
                command.Parameters.AddWithValue("@timeLastPaused", SqlUtility.SqlValue(stateInfo.TimeLastPaused, DateTime.MinValue));
                command.Parameters.AddWithValue("@timeLastResumed", SqlUtility.SqlValue(stateInfo.TimeLastResumed, DateTime.MinValue));
                command.Parameters.AddWithValue("@resumeCount", stateInfo.ResumeCount);
                command.Parameters.AddWithValue("@configuration", SqlUtility.SqlValue(serializedConfig));
                command.Parameters.AddWithValue("@Scheduling_Status", SqlUtility.SqlValue(schedulingInfo, () => schedulingInfo.SchedulingStatus));
                command.Parameters.AddWithValue("@Scheduling_Scope", SqlUtility.SqlValue(schedulingInfo, () => schedulingInfo.SchedulingScope));
                command.Parameters.AddWithValue("@Scheduling_MaxDeviationBefore", SqlUtility.SqlValue(schedulingInfo, () => schedulingInfo.MaxDeviationBefore));
                command.Parameters.AddWithValue("@Scheduling_MaxDeviationAfter", SqlUtility.SqlValue(schedulingInfo, () => schedulingInfo.MaxDeviationAfter));
                command.Parameters.AddWithValue("@Scheduling_RequestedTime", SqlUtility.SqlValue(schedulingInfo, () => SqlUtility.SqlValue(schedulingInfo.RequestedTime, DateTime.MinValue)));
                command.Parameters.AddWithValue("@Scheduling_ExpectedStartTime", SqlUtility.SqlValue(schedulingInfo, () => SqlUtility.SqlValue(schedulingInfo.ExpectedStartTime, DateTime.MinValue)));
                command.Parameters.AddWithValue("@Scheduling_ExpectedEndTime", SqlUtility.SqlValue(schedulingInfo, () => SqlUtility.SqlValue(schedulingInfo.ExpectedEndTime, DateTime.MinValue)));

                connection.Open();
                command.ExecuteNonQuery();
            }
        }
示例#2
0
        void IServiceExecutionHost.InitializeService(ServiceConfiguration config, SchedulingInfo schedulingInfo, Guid instanceID, Guid parentInstanceID, Guid connectionGuid)
        {
            if (String.IsNullOrEmpty(config.ServiceClass))
            {
                throw new ServiceException("ServiceConfiguration.ServiceClass cannot be empty.");
            }

            ServiceRuntimeInfo runtimeInfo = Get(instanceID);

            lock (runtimeInfo.ExecutionSync)
            {
                if (runtimeInfo.StateInfo != null && runtimeInfo.StateInfo.Value.State != ServiceState.Uninitialized)
                {
                    throw new ServiceException("Service is already initialized.");
                }

                // Save init data for later
                runtimeInfo.ParentInstanceID = parentInstanceID;
                runtimeInfo.Configuration    = config;
                runtimeInfo.SchedulingInfo   = schedulingInfo;
                UpdateState(instanceID, new ServiceStateInfo()
                {
                    State = ServiceState.Initializing
                });

                // Load the app domain, and attach to its events
                AppDomain domain = AppDomain.CreateDomain(
                    String.Format("Edge service - {0} ({1})", config.ServiceName, instanceID)
                    );
                domain.DomainUnload += new EventHandler(DomainUnload);


                // Instantiate the service type in the new domain
                Service serviceRef;
                if (config.AssemblyPath == null)
                {
                    Type serviceType = Type.GetType(config.ServiceClass, false);

                    if (serviceType == null)
                    {
                        serviceType = Type.GetType(String.Format("Edge.Core.Services.{0}.{0}Service", config.ServiceClass), false);
                    }

                    if (serviceType == null)
                    {
                        throw new ServiceException(String.Format("Service type '{0}' could not be found. Please specify AssemblyPath if the service is not in the host directory.", config.ServiceClass));
                    }

                    serviceRef = (Service)domain.CreateInstanceAndUnwrap(serviceType.Assembly.FullName, serviceType.FullName);
                }
                else
                {
                    // A 3rd party service
                    serviceRef = (Service)domain.CreateInstanceFromAndUnwrap(
                        config.AssemblyPath,
                        config.ServiceClass
                        );
                }

                runtimeInfo.ServiceRef = serviceRef;
                runtimeInfo.AppDomain  = domain;

                lock (_serviceByAppDomain)
                {
                    _serviceByAppDomain.Add(domain.Id, runtimeInfo.InstanceID);
                };

                // Give the service ref its properties
                serviceRef.Init(this, this.Environment.EnvironmentConfiguration, config, schedulingInfo, instanceID, parentInstanceID);
            }
        }
示例#3
0
        internal void Init(ServiceExecutionHost host, ServiceEnvironmentConfiguration envConfig, ServiceConfiguration config, SchedulingInfo schedulingInfo, Guid instanceID, Guid parentInstanceID)
        {
            Host             = host;
            this.Environment = new ServiceEnvironment(envConfig);

            this.InstanceID     = instanceID;
            this.Configuration  = config;
            this.SchedulingInfo = schedulingInfo;

            if (parentInstanceID != Guid.Empty)
            {
                this.ParentInstance = Environment.GetServiceInstance(parentInstanceID);
            }

            Current = this;

            // Monitor app domain-level events
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(this.DomainUnhandledException);
            AppDomain.CurrentDomain.DomainUnload       += new EventHandler(this.DomainUnload);

            StateInfo.TimeInitialized = DateTime.Now;
            StateInfo.State           = ServiceState.Ready;
            NotifyState();
        }