コード例 #1
0
ファイル: Cell.cs プロジェクト: yonglehou/lokad-cloud-apphost
        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();
        }