/// <remarks>Never run a cell process entry point more than once per AppDomain.</remarks> public void Run(CellDefinition cellDefinition, IDeploymentReader deploymentReader, ApplicationEnvironment environment) { // Load Assemblies into AppDomain var assemblies = deploymentReader.GetAssembliesAndSymbols(cellDefinition.Assemblies).ToList(); var loader = new AssemblyLoader(); loader.LoadAssembliesIntoAppDomain(assemblies, environment); // Create the EntryPoint var entryPointTypeName = cellDefinition.EntryPointTypeName; if (string.IsNullOrEmpty(entryPointTypeName)) { entryPointTypeName = "Lokad.Cloud.Services.AppEntryPoint.EntryPoint, Lokad.Cloud.Services.AppEntryPoint"; } var entryPointType = Type.GetType(entryPointTypeName); if (entryPointType == null) { throw new InvalidOperationException("Type " + entryPointTypeName + " not found."); } _appEntryPoint = (IApplicationEntryPoint)Activator.CreateInstance(entryPointType); var settings = string.IsNullOrEmpty(cellDefinition.SettingsXml) ? new XElement("Settings") : XElement.Parse(cellDefinition.SettingsXml); // Run _appEntryPoint.Run(settings, deploymentReader, environment, _externalCancellationTokenSource.Token); }
void Run() { var cancellationToken = _cancellationTokenSource.Token; _thread = new Thread(() => { var currentRoundStartTime = DateTimeOffset.UtcNow - FloodFrequencyThreshold; while (!cancellationToken.IsCancellationRequested) { var observer = _hostContext.Observer; var lastRoundStartTime = currentRoundStartTime; currentRoundStartTime = DateTimeOffset.UtcNow; var identity = _hostContext.GetNewCellLifeIdentity(_solutionName, _cellName, _deployment); AppDomain domain = AppDomain.CreateDomain("LokadCloudServiceRuntimeCell_" + identity.UniqueCellInstanceName, null, AppDomain.CurrentDomain.SetupInformation); try { try { _entryPoint = (CellAppDomainEntryPoint)domain.CreateInstanceAndUnwrap( Assembly.GetExecutingAssembly().FullName, typeof(CellAppDomainEntryPoint).FullName); } catch (Exception exception) { // Fatal Error observer.TryNotify(() => new CellFatalErrorRestartedEvent(identity, exception)); cancellationToken.WaitHandle.WaitOne(DelayWhenFlooding); continue; } // Forward cancellation token to AppDomain-internal cancellation token source var registration = cancellationToken.Register(_entryPoint.Cancel); var environment = new ApplicationEnvironment(_hostContext, identity, _deployment, _cellDefinition.Assemblies, _sendCommand); try { observer.TryNotify(() => new CellStartedEvent(identity)); _entryPoint.Run(_cellDefinition, _hostContext.DeploymentReader, environment); } catch (ThreadAbortException exception) { Thread.ResetAbort(); observer.TryNotify(() => new CellAbortedEvent(identity, exception)); } catch (Exception exception) { if (cancellationToken.IsCancellationRequested) { observer.TryNotify(() => new CellAbortedEvent(identity, exception)); } else { _entryPoint = null; if ((DateTimeOffset.UtcNow - lastRoundStartTime) < FloodFrequencyThreshold) { observer.TryNotify(() => new CellExceptionRestartedEvent(identity, exception, true)); cancellationToken.WaitHandle.WaitOne(DelayWhenFlooding); } else { observer.TryNotify(() => new CellExceptionRestartedEvent(identity, exception, false)); } } } finally { RemotingServices.Disconnect(environment); _entryPoint = null; observer.TryNotify(() => new CellStoppedEvent(identity)); registration.Dispose(); } } catch (Exception exception) { // Fatal Error observer.TryNotify(() => new CellFatalErrorRestartedEvent(identity, exception)); cancellationToken.WaitHandle.WaitOne(DelayWhenFlooding); continue; } finally { AppDomain.Unload(domain); } } }); _thread.Name = "Lokad.Cloud AppHost Cell (" + _cellName + ")"; _thread.Start(); }
/// <remarks>Never run a cell process entry point more than once per AppDomain.</remarks> public void Run(CellDefinition cellDefinition, IDeploymentReader deploymentReader, ApplicationEnvironment environment) { // Load Assemblies into AppDomain var assemblies = deploymentReader.GetAssembliesAndSymbols(cellDefinition.Assemblies).ToList(); var loader = new AssemblyLoader(); loader.LoadAssembliesIntoAppDomain(assemblies, environment); // Create the EntryPoint var entryPointTypeName = cellDefinition.EntryPointTypeName; if (string.IsNullOrEmpty(entryPointTypeName)) { entryPointTypeName = "Lokad.Cloud.Services.AppEntryPoint.EntryPoint, Lokad.Cloud.Services.AppEntryPoint"; } var entryPointType = Type.GetType(entryPointTypeName); if (entryPointType == null) { throw new InvalidOperationException("Type " + entryPointTypeName + " not found."); } _appEntryPoint = (IApplicationEntryPoint)Activator.CreateInstance(entryPointType); var settings = string.IsNullOrEmpty(cellDefinition.SettingsXml) ? new XElement("Settings") : XElement.Parse(cellDefinition.SettingsXml); // Run _appEntryPoint.Run(settings, deploymentReader, environment, _externalCancellationTokenSource.Token); }
void Run() { var cancellationToken = _cancellationTokenSource.Token; _thread = new Thread(() => { var currentRoundStartTime = DateTimeOffset.UtcNow - FloodFrequencyThreshold; while (!cancellationToken.IsCancellationRequested) { var observer = _hostContext.Observer; var lastRoundStartTime = currentRoundStartTime; currentRoundStartTime = DateTimeOffset.UtcNow; var identity = _hostContext.GetNewCellLifeIdentity(_solutionName, _cellName, _deployment); AppDomain domain = AppDomain.CreateDomain("LokadCloudServiceRuntimeCell_" + identity.UniqueCellInstanceName, null, AppDomain.CurrentDomain.SetupInformation); try { try { _entryPoint = (CellAppDomainEntryPoint)domain.CreateInstanceAndUnwrap( Assembly.GetExecutingAssembly().FullName, typeof(CellAppDomainEntryPoint).FullName); } catch (Exception exception) { // Fatal Error observer.TryNotify(() => new CellFatalErrorRestartedEvent(identity, exception)); cancellationToken.WaitHandle.WaitOne(DelayWhenFlooding); continue; } // Forward cancellation token to AppDomain-internal cancellation token source var registration = cancellationToken.Register(_entryPoint.Cancel); var environment = new ApplicationEnvironment(_hostContext, identity, _deployment, _cellDefinition.Assemblies, _sendCommand); try { observer.TryNotify(() => new CellStartedEvent(identity)); _entryPoint.Run(_cellDefinition, _hostContext.DeploymentReader, environment); } catch (ThreadAbortException exception) { Thread.ResetAbort(); observer.TryNotify(() => new CellAbortedEvent(identity, exception)); } catch (Exception exception) { if (cancellationToken.IsCancellationRequested) { observer.TryNotify(() => new CellAbortedEvent(identity, exception)); } else { _entryPoint = null; if ((DateTimeOffset.UtcNow - lastRoundStartTime) < FloodFrequencyThreshold) { observer.TryNotify(() => new CellExceptionRestartedEvent(identity, exception, true)); cancellationToken.WaitHandle.WaitOne(DelayWhenFlooding); } else { observer.TryNotify(() => new CellExceptionRestartedEvent(identity, exception, false)); } } } finally { RemotingServices.Disconnect(environment); _entryPoint = null; observer.TryNotify(() => new CellStoppedEvent(identity)); registration.Dispose(); } } catch (Exception exception) { // Fatal Error observer.TryNotify(() => new CellFatalErrorRestartedEvent(identity, exception)); cancellationToken.WaitHandle.WaitOne(DelayWhenFlooding); continue; } finally { AppDomain.Unload(domain); } } }); _thread.Name = "Lokad.Cloud AppHost Cell (" + _cellName + ")"; _thread.Start(); }