Пример #1
0
        /// <summary>
        /// Build initialization result
        /// </summary>
        /// <param name="frontendResult">indicating the frontend result</param>
        /// <param name="dispatcherManager">indicating the dispatcher manager</param>
        /// <param name="serviceOperationTimeout">indicating service operation timeout</param>
        /// <param name="clientBrokerHeartbeatInterval">indicating client broker heartbeat interval</param>
        /// <param name="clientBrokerHeartbeatRetryCount">indicating client broker heartbeat retry count</param>
        /// <param name="azureRequestQueueUris">the Azure storage queue SAS Uri</param>
        /// <param name="azureRequestBlobUri">the Azure storage blob container SAS Uri</param>
        /// <param name="useAzureQueue">if the azure storage queue(blob) is used</param>
        /// <returns>returns the initialization result</returns>
        private static BrokerInitializationResult BuildInitializationResult(
            FrontendResult frontendResult,
            DispatcherManager dispatcherManager,
            int serviceOperationTimeout,
            int clientBrokerHeartbeatInterval,
            int clientBrokerHeartbeatRetryCount,
            string[] azureRequestQueueUris,
            string azureRequestBlobUri,
            bool?useAzureQueue)
        {
            BrokerInitializationResult info = new BrokerInitializationResult();

            info.BrokerEpr                       = frontendResult.FrontendUriList;
            info.ControllerEpr                   = frontendResult.ControllerUriList;
            info.ResponseEpr                     = frontendResult.GetResponseUriList;
            info.ServiceOperationTimeout         = serviceOperationTimeout;
            info.ClientBrokerHeartbeatInterval   = clientBrokerHeartbeatInterval;
            info.ClientBrokerHeartbeatRetryCount = clientBrokerHeartbeatRetryCount;
            info.MaxMessageSize                  = frontendResult.MaxMessageSize;
            info.SupportsMessageDetails          = frontendResult.FrontendSupportsMessageDetails && dispatcherManager.BackendSupportsMessageDetails;
            info.AzureRequestQueueUris           = azureRequestQueueUris;
            info.AzureRequestBlobUri             = azureRequestBlobUri;
            info.UseAzureQueue                   = (useAzureQueue == true);
            return(info);
        }
Пример #2
0
        /// <summary>
        /// Attach to a session
        /// </summary>
        /// <param name="sessionId">session id</param>
        /// <returns>returns broker initialization result</returns>
        public BrokerInitializationResult Attach(string sessionId)
        {
            if (!this.AllowNewSession)
            {
                ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerIsOffline, SR.BrokerIsOffline);
            }

            try
            {
                this.CheckAccess(sessionId);

                TraceHelper.TraceEvent(sessionId, System.Diagnostics.TraceEventType.Information, "[BrokerLauncher] Attach: SessionId = {0}", sessionId);
                BrokerInitializationResult returnValue = this.brokerManager.AttachBroker(sessionId).GetAwaiter().GetResult();

                #region Debug Failure Test
                SimulateFailure.FailOperation(1);
                #endregion

                TraceHelper.TraceEvent(sessionId, System.Diagnostics.TraceEventType.Information, "[BrokerLauncher] Attach Broker {0} Succeeded.", sessionId);
                return(returnValue);
            }
            catch (Exception e)
            {
                // Bug 10614: Throw a proper exception when the broker node is being taken offline
                if (!this.AllowNewSession)
                {
                    ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerIsOffline, SR.BrokerIsOffline);
                }

                TraceHelper.TraceEvent(sessionId, System.Diagnostics.TraceEventType.Error, "[BrokerLauncher] Attach Broker {0} failed: {1}", sessionId, e);
                throw ExceptionHelper.ConvertExceptionToFaultException(e);
            }
        }
Пример #3
0
        /// <summary>
        /// Initializes a new instance of the BrokerEntry class
        /// </summary>
        /// <param name="startInfo">indicating the start info</param>
        /// <param name="brokerInfo">indicating the broker info</param>
        public BrokerEntry(SessionStartInfoContract startInfo, BrokerStartInfo brokerInfo, BrokerManagementService serviceInstance)
        {
            if (startInfo.TransportScheme != TransportScheme.NetTcp)
            {
                throw new NotSupportedException("Sample broker does not support transport scheme other than NetTcp.");
            }

            if (brokerInfo.Durable)
            {
                throw new NotSupportedException("Sample broker does not support durable session.");
            }

            this.clientManager = new ServiceClientManager(brokerInfo.SessionId, brokerInfo.Headnode, serviceInstance);

            Frontend       frontend = new Frontend(this.clientManager);
            WebHttpBinding binding  = new WebHttpBinding();

            binding.MaxBufferPoolSize      = 5000000;
            binding.MaxBufferSize          = 5000000;
            binding.MaxReceivedMessageSize = 5000000;

            binding.ReaderQuotas.MaxArrayLength         = 5000000;
            binding.ReaderQuotas.MaxBytesPerRead        = 5000000;
            binding.ReaderQuotas.MaxDepth               = 5000000;
            binding.ReaderQuotas.MaxNameTableCharCount  = 5000000;
            binding.ReaderQuotas.MaxStringContentLength = 5000000;

            this.frontendServiceHost = new WebServiceHost(frontend, new Uri(String.Format("http://{0}:8081/", Environment.MachineName)));
            ServiceEndpoint endpoint = this.frontendServiceHost.AddServiceEndpoint(typeof(IWebHttpFrontendService), binding, String.Empty);

            endpoint.Behaviors.Add(new WebHttpBehavior());

            string listenUri = endpoint.ListenUri.AbsoluteUri;

            this.frontendServiceHost.Open();

            this.result           = new BrokerInitializationResult();
            this.result.BrokerEpr = new string[3] {
                listenUri, null, null
            };
            this.result.ControllerEpr = new string[3];
            this.result.ResponseEpr   = new string[3];
        }
Пример #4
0
        /// <summary>
        /// Create a session
        /// </summary>
        /// <param name="info">session start info</param>
        /// <param name="sessionId">session id</param>
        /// <returns>returns broker initialization result</returns>
        public BrokerInitializationResult Create(SessionStartInfoContract info, string sessionId)
        {
            if ((!this.AllowNewSession) || (!this.IsOnline && String.IsNullOrEmpty(info.DiagnosticBrokerNode)))
            {
                ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerIsOffline, SR.BrokerIsOffline);
            }

            // Handle invalid input parameters
            try
            {
                ParamCheckUtility.ThrowIfNull(info, "info");
                if (!BrokerLauncherEnvironment.Standalone)
                {
                    this.CheckAccess(sessionId);
                }

                TraceHelper.TraceEvent(sessionId, System.Diagnostics.TraceEventType.Information, "[BrokerLauncher] Create: SessionId = {0}", sessionId);
                //TODO: make it async
                BrokerInitializationResult returnValue = this.brokerManager.CreateNewBrokerDomain(info, sessionId, false).GetAwaiter().GetResult();

                #region Debug Failure Test
                SimulateFailure.FailOperation(1);
                #endregion

                TraceHelper.RuntimeTrace.LogSessionCreated(sessionId);
                TraceHelper.TraceEvent(sessionId, System.Diagnostics.TraceEventType.Information, "[BrokerLauncher] Create Broker {0} Succeeded.", sessionId);
                return(returnValue);
            }
            catch (Exception e)
            {
                TraceHelper.RuntimeTrace.LogFailedToCreateSession(sessionId);

                // Bug 10614: Throw a proper exception when the broker node is being taken offline
                if ((!this.AllowNewSession) || (!this.IsOnline && String.IsNullOrEmpty(info.DiagnosticBrokerNode)))
                {
                    ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerIsOffline, SR.BrokerIsOffline);
                }

                TraceHelper.TraceEvent(sessionId, System.Diagnostics.TraceEventType.Error, "[BrokerLauncher] Create Broker {0} failed: {1}", sessionId, e.ToString());
                throw ExceptionHelper.ConvertExceptionToFaultException(e);
            }
        }
Пример #5
0
        /// <summary>
        /// Initializes a new instance of the BrokerEntry class
        /// </summary>
        /// <param name="startInfo">indicating the start info</param>
        /// <param name="brokerInfo">indicating the broker info</param>
        public BrokerEntry(SessionStartInfoContract startInfo, BrokerStartInfo brokerInfo, BrokerManagementService serviceInstance)
        {
            if (startInfo.TransportScheme != TransportScheme.NetTcp)
            {
                throw new NotSupportedException("Sample broker does not support transport scheme other than NetTcp.");
            }

            if (brokerInfo.Durable)
            {
                throw new NotSupportedException("Sample broker does not support durable session.");
            }

            this.clientManager = new ServiceClientManager(brokerInfo.SessionId, brokerInfo.Headnode, serviceInstance);
            Frontend frontend = new Frontend(this.clientManager);

            // Choose different binding configuration by start info
            NetTcpBinding frontendBinding;

            if (startInfo.Secure)
            {
                frontendBinding = new NetTcpBinding();
            }
            else
            {
                frontendBinding = new NetTcpBinding(SecurityMode.None);
            }

            frontendBinding.PortSharingEnabled = true;

            this.frontendServiceHost = new ServiceHost(frontend, new Uri(String.Format("net.tcp://{0}:9091/SampleBroker", Environment.MachineName)));
            string listenUri = this.frontendServiceHost.AddServiceEndpoint(typeof(IDuplexService), frontendBinding, String.Empty).ListenUri.AbsoluteUri;

            this.frontendServiceHost.Open();

            this.result           = new BrokerInitializationResult();
            this.result.BrokerEpr = new string[3] {
                listenUri, null, null
            };
            this.result.ControllerEpr = new string[3];
            this.result.ResponseEpr   = new string[3];
        }
Пример #6
0
        /// <summary>
        /// Create broker
        /// </summary>
        /// <param name="sessionId">indicating the session id</param>
        private async Task CreateInternal(string sessionId)
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(this.CurrentDomain_AssemblyResolve);

            this.SetIsDiagTraceEnabledProperty();
            Assembly        brokerCoreAsm = Assembly.LoadFile(this.brokerCoreServiceLibPath);
            ConstructorInfo ci            = brokerCoreAsm.GetType(BrokerEntryClassFullName).GetConstructor(new Type[1] {
                typeof(string)
            });

            this.brokerEntry = (IBrokerEntry)ci.Invoke(new object[1] {
                sessionId
            });
            this.brokerEntry.BrokerFinished += new EventHandler(this.Entry_BrokerFinished);
            this.result = this.brokerEntry.Run(this.startInfoContract, this.brokerInfo);

            //set isDebugModeEnabled True to jump UpdateBrokerInfo method.
            if (!this.isDebugModeEnabled && !this.isNoSession)
            {
                await this.UpdateBrokerInfo(this.brokerInfo).ConfigureAwait(false);
            }
        }
Пример #7
0
        /// <summary>
        /// Create broker
        /// </summary>
        /// <param name="startInfo">indicating the session start information</param>
        /// <param name="sessionId">indicating the session id</param>
        /// <param name="targetTimeout">indicating the target timeout</param>
        /// <param name="eprs">indicating the broker epr list</param>
        /// <param name="epr">output selected epr</param>
        /// <param name="binding">indicting the binding</param>
        /// <returns>returns the session information</returns>
        public async Task <SessionBase> CreateBroker(SessionStartInfo startInfo, string sessionId, DateTime targetTimeout, string[] eprs, Binding binding)
        {
            Exception            innerException = null;
            IEnumerable <string> endpoints      = eprs;

            if (startInfo.UseAzureQueue.GetValueOrDefault() && !endpoints.Contains(SessionInternalConstants.BrokerConnectionStringToken))
            {
                endpoints = endpoints.Concat(new[] { SessionInternalConstants.BrokerConnectionStringToken });
            }

            foreach (string epr in endpoints)
            {
                TimeSpan        timeout        = SessionBase.GetTimeout(targetTimeout);
                IBrokerLauncher brokerLauncher = null;
                try
                {
                    SessionBase.TraceSource.TraceInformation("[Session:{0}] Try to create broker... BrokerLauncherEpr = {1}", sessionId, epr);

                    void RenewBrokerLauncherClient()
                    {
                        if (epr == SessionInternalConstants.BrokerConnectionStringToken)
                        {
                            brokerLauncher = new BrokerLauncherCloudQueueClient(startInfo.BrokerLauncherStorageConnectionString);
                        }
                        else
                        {
                            var client = new BrokerLauncherClient(new Uri(epr), startInfo, binding);
                            client.InnerChannel.OperationTimeout = timeout;
                            brokerLauncher = client;
                        }
                    }

                    RenewBrokerLauncherClient();

                    BrokerInitializationResult result = null;

                    int retry = 20;
                    while (retry > 0)
                    {
                        try
                        {
                            if (this.durable)
                            {
                                result = brokerLauncher.CreateDurable(startInfo.Data, sessionId);
                            }
                            else
                            {
                                result = brokerLauncher.Create(startInfo.Data, sessionId);
                            }

                            break;
                        }
                        catch (Exception ex)
                        {
                            if (retry <= 0)
                            {
                                throw;
                            }

                            retry--;
                            Debug.WriteLine($"Waiting for Broker Launcher running. Detail: {ex.Message}");
                            await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false);

                            RenewBrokerLauncherClient();
                        }
                    }

                    Debug.Assert(result != null);

                    SessionBase.TraceSource.TraceInformation("[Session:{0}] Succesfully created broker.", sessionId);
                    SessionInfo info = SessionBase.BuildSessionInfo(result, this.durable, sessionId, epr, startInfo.Data.ServiceVersion, startInfo);

                    if (this.durable)
                    {
#if net40
                        return(new DurableSession(info, startInfo.Headnode, binding));
#else
                        return(new DurableSession(info, startInfo.Headnode, binding));
#endif
                    }
                    else
                    {
                        var session = new V3Session(info, startInfo.Headnode, startInfo.ShareSession, binding);
                        if (startInfo.UseAzureStorage)
                        {
                            session.BrokerLauncherClient = brokerLauncher;
                        }

                        return(session);
                    }
                }
                catch (FaultException <SessionFault> e)
                {
                    SessionBase.TraceSource.TraceEvent(TraceEventType.Warning, 0, "[Session:{0}] Fault exception occured while creating broker: {1}. FaultCode = {2}", sessionId, e, e.Detail.Code);
                    switch (e.Detail.Code)
                    {
                    // Continue if current broker node is being taken offline
                    case SOAFaultCode.Broker_BrokerIsOffline:
                        continue;
                    }

                    throw Utility.TranslateFaultException(e);
                }
                catch (TimeoutException te)
                {
                    SessionBase.TraceSource.TraceEvent(TraceEventType.Error, 0, "[Session:{0}] TimeoutException occured while creating broker: {1}", sessionId, te);

                    // don't continue when we timeout
                    throw new TimeoutException(string.Format(SR.ConectBrokerLauncherTimeout, epr, Constant.DefaultCreateSessionTimeout), te);
                }
                catch (CommunicationException ex)
                {
                    SessionBase.TraceSource.TraceEvent(TraceEventType.Warning, 0, "[Session:{0}] Failed to create broker: {1}", sessionId, ex);
                    innerException = ex;
                    SessionBase.TraceSource.TraceInformation(ex.ToString());
                    continue;
                }
                finally
                {
                    var client = brokerLauncher as BrokerLauncherClient;
                    if (client != null)
                    {
                        Utility.SafeCloseCommunicateObject(client);
                    }
                }
            }

            SessionBase.TraceSource.TraceEvent(TraceEventType.Error, 0, "[Session:{0}] Failed to create broker after trying all available eprs.", sessionId);
            throw new SessionException(SR.NoBrokerNodeFound, innerException);
        }
Пример #8
0
        /// <summary>
        /// Attach to a broker, returns session instance
        /// </summary>
        /// <param name="attachInfo">indicating the attach information</param>
        /// <param name="info">indicating the session info to be updated</param>
        /// <param name="timeout">indicating the timeout</param>
        /// <param name="binding">indicting the binding</param>
        /// <returns>returns the session instance</returns>
        public Task <SessionBase> AttachBroker(SessionAttachInfo attachInfo, SessionInfo info, TimeSpan timeout, Binding binding)
        {
            SessionBase.TraceSource.TraceInformation("[Session:{0}] Try to attach broker...", attachInfo.SessionId);
            BrokerLauncherClient broker = new BrokerLauncherClient(new Uri(info.BrokerLauncherEpr), attachInfo, binding);

            broker.InnerChannel.OperationTimeout = timeout;
            try
            {
                BrokerInitializationResult result = broker.Attach(info.Id);
                info.BrokerEpr                       = result.BrokerEpr;
                info.ControllerEpr                   = result.ControllerEpr;
                info.ResponseEpr                     = result.ResponseEpr;
                info.ServiceOperationTimeout         = result.ServiceOperationTimeout;
                info.MaxMessageSize                  = result.MaxMessageSize;
                info.ClientBrokerHeartbeatInterval   = result.ClientBrokerHeartbeatInterval;
                info.ClientBrokerHeartbeatRetryCount = result.ClientBrokerHeartbeatRetryCount;
                info.BrokerUniqueId                  = result.BrokerUniqueId;

                info.UseAzureQueue         = result.UseAzureQueue;
                info.AzureRequestQueueUris = result.AzureRequestQueueUris;
                info.AzureRequestBlobUri   = result.AzureRequestBlobUri;

                info.Username         = attachInfo.Username;
                info.InternalPassword = attachInfo.InternalPassword;
                info.Headnode         = attachInfo.Headnode;

                info.UseWindowsClientCredential = attachInfo.UseWindowsClientCredential;
            }
            catch (FaultException <SessionFault> e)
            {
                SessionBase.TraceSource.TraceEvent(TraceEventType.Error, 0, "[Session:{0}] Fault exception occured while attaching broker: {1}. FaultCode = {2}", attachInfo.SessionId, e, e.Detail.Code);
                throw Utility.TranslateFaultException(e);
            }
            catch (CommunicationException e)
            {
                SessionBase.TraceSource.TraceEvent(TraceEventType.Error, 0, "[Session:{0}] Failed to attach to broker: {1}", attachInfo.SessionId, e);
                throw new SessionException(SOAFaultCode.ConnectBrokerLauncherFailure, SR.ConnectBrokerLauncherFailure, e);
            }
            catch (Exception e)
            {
                SessionBase.TraceSource.TraceEvent(TraceEventType.Error, 0, "[Session:{0}] Failed to attach to broker: {1}", attachInfo.SessionId, e);
                throw new SessionException(SOAFaultCode.UnknownError, e.ToString());
            }
            finally
            {
                Utility.SafeCloseCommunicateObject(broker);
            }

            if (SoaHelper.IsSchedulerOnIaaS(attachInfo.Headnode))
            {
                string suffix = SoaHelper.GetSuffixFromHeadNodeEpr(attachInfo.Headnode);
                if (info.BrokerEpr != null)
                {
                    SoaHelper.UpdateEprWithCloudServiceName(info.BrokerEpr, suffix);
                }

                if (info.ControllerEpr != null)
                {
                    SoaHelper.UpdateEprWithCloudServiceName(info.ControllerEpr, suffix);
                }

                if (info.ResponseEpr != null)
                {
                    SoaHelper.UpdateEprWithCloudServiceName(info.ResponseEpr, suffix);
                }
            }

            if (this.durable)
            {
                if (!info.Durable)
                {
                    throw new SessionException(SOAFaultCode.InvalidAttachInteractiveSession, SR.InvalidAttachInteractiveSession);
                }
#if net40
                return(TaskEx.FromResult <SessionBase>(new DurableSession(info, attachInfo.Headnode, binding)));
#else
                return(Task.FromResult <SessionBase>(new DurableSession(info, attachInfo.Headnode, binding)));
#endif
            }
            else
            {
                if (info.Durable)
                {
                    throw new SessionException(SOAFaultCode.InvalidAttachDurableSession, SR.InvalidAttachDurableSession);
                }
#if net40
                return(TaskEx.FromResult <SessionBase>(new V3Session(info, attachInfo.Headnode, true, binding)));
#else
                return(Task.FromResult <SessionBase>(new V3Session(info, attachInfo.Headnode, true, binding)));
#endif
            }
        }
Пример #9
0
        /// <summary>
        /// Attach to a existing broker
        /// </summary>
        /// <param name="sessionId">session id</param>
        /// <returns>returns initialization result</returns>
        public async Task <BrokerInitializationResult> AttachBroker(string sessionId)
        {
            BrokerInfo info;
            BrokerInitializationResult result = null;
            Exception lastException           = null;

            TraceHelper.TraceEvent(sessionId, System.Diagnostics.TraceEventType.Information, "[BrokerManager] Client attached");

            for (int i = 0; i < RecoverBrokerRetryLimit; i++)
            {
                // Try to find broker that is still running
                bool success;
                lock (this.brokerDic)
                {
                    success = this.brokerDic.TryGetValue(sessionId, out info);
                    if (success)
                    {
                        Monitor.Enter(info);
                    }
                }

                if (success)
                {
                    try
                    {
                        info.CheckAccess();
                        TraceHelper.TraceEvent(sessionId, System.Diagnostics.TraceEventType.Information, "[BrokerManager] Attaching exsiting broker: {0}", sessionId);
                        if (info.Disposed)
                        {
                            TraceHelper.TraceEvent(sessionId, System.Diagnostics.TraceEventType.Information, "[BrokerManager] Broker is exiting...");
                            ThrowHelper.ThrowSessionFault(SOAFaultCode.Session_ValidateJobFailed_AlreadyFinished, SR.BrokerFinishing, sessionId.ToString());
                        }
                        else
                        {
                            bool needRestart = false;
                            try
                            {
                                info.Attach();
                            }
                            catch (EndpointNotFoundException e)
                            {
                                // Bug 8236: Need to catch EndpointNotFoundException and try to recover and retry attaching.
                                TraceHelper.TraceEvent(sessionId, TraceEventType.Warning, "[BrokerManager] Attach failed with EndpointNotFoundException, broker might be unloading. Will wait for broker exit and try raise it again. Exception: {0}", e);

                                // Wait until the process is exited and all event are finished
                                // This means that this broker info instance is removed from brokerDic so that we can start from create broker for attaching
                                info.WaitForProcessExit(TimeoutForWaitingProcessExit);
                                TraceHelper.TraceEvent(sessionId, TraceEventType.Information, "[BrokerManager] Broker process is exited and all events are finished, restart that broker for attaching");
                                needRestart = true;
                            }
                            catch (FaultException <SessionFault> e)
                            {
                                if (e.Detail.Code == (int)SOAFaultCode.Broker_BrokerSuspending)
                                {
                                    TraceHelper.TraceEvent(sessionId, TraceEventType.Warning, "[BrokerManager] Attach failed, broker is unloading to suspended state. Will wait for broker exit and try raise it again.");

                                    // Wait until the process is exited and all event are finished
                                    // This means that this broker info instance is removed from brokerDic so that we can start from create broker for attaching
                                    info.WaitForProcessExit(TimeoutForWaitingProcessExit);
                                    TraceHelper.TraceEvent(sessionId, TraceEventType.Information, "[BrokerManager] Broker process is exited and all events are finished, restart that broker for attaching");
                                    needRestart = true;
                                }
                                else
                                {
                                    TraceHelper.TraceEvent(sessionId, TraceEventType.Error, "[BrokerManager] Attach failed: {0}", e);
                                    throw;
                                }
                            }

                            if (!needRestart)
                            {
                                //TODO: check whether need to obtain the cluster id, hash and Azure storage SAS here.

                                return(info.InitializationResult);
                            }
                        }
                    }
                    finally
                    {
                        Monitor.Exit(info);
                    }
                }

                // Try to find service job from finished jobs.
                // If no such service job is found, exception will throw by the scheduler helper and back to the client
                BrokerRecoverInfo recoverInfo = await this.schedulerHelper.TryGetSessionStartInfoFromFininshedJobs(sessionId);

                ClusterInfoContract clusterInfo = await this.schedulerHelper.GetClusterInfoAsync();

                try
                {
                    result = await this.CreateBrokerAndRun(recoverInfo, true, clusterInfo);
                }
                catch (FaultException <SessionFault> e)
                {
                    if (e.Detail.Code == SOAFaultCode.Broker_SessionIdAlreadyExists)
                    {
                        // Bug 9840: This exception means that someone already raised up the broker
                        // Should goto the very beginning to load initialization result
                        lastException = e;

                        // TODO: We don't know if this retry period is enough
                        // We need to investigate this more in SP2 and we might
                        // need an event wait handle to synchronize these rather
                        // than a retry period
                        await Task.Delay(AttachSessionRetryPeriod);

                        continue;
                    }
                    else
                    {
                        throw;
                    }
                }

                if (this.IsCallingFromHeadNode(OperationContext.Current.ServiceSecurityContext.WindowsIdentity))
                {
                    TraceHelper.RuntimeTrace.LogSessionRaisedUpFailover(sessionId);
                }
                else
                {
                    TraceHelper.RuntimeTrace.LogSessionRaisedUp(sessionId, OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name);
                }

                lastException = null;
                break;
            }

            if (lastException == null)
            {
                return(result);
            }
            else
            {
                throw lastException;
            }
        }
Пример #10
0
        /// <summary>
        /// Start broker process
        /// </summary>
        public void StartBroker()
        {
            bool failoverMode = false;

            if (Interlocked.Increment(ref this.retryCount) > 1)
            {
                // Bug 7150: Need to set attach to true when retrying
                failoverMode             = true;
                this.brokerInfo.Attached = true;
            }

            if (this.customBroker == null || String.IsNullOrEmpty(this.customBroker.Executive))
            {
                this.brokerProcess = this.pool.GetBrokerProcess();
            }
            else
            {
                this.brokerProcess = CreateCustomBrokerProcess(this.customBroker);
            }

            // Log a trace mapping broker worker pid to session id.
            TraceHelper.TraceEvent(
                this.sessionId,
                TraceEventType.Information,
                "[BrokerInfo].StartBroker: Init broker worker {0} for session {1}.",
                this.brokerProcess.Id,
                this.sessionId);

            BrokerManagementServiceClient client = this.CreateClient();

            try
            {
                this.result = client.Initialize(this.sessionStartInfo, this.brokerInfo);

                // Set broker's unique id to the initialization result when the process
                // is (re)started.
                this.result.BrokerUniqueId = this.UniqueId;
                this.brokerProcess.Exited += new EventHandler(this.BrokerProcess_Exited);
            }
            catch (Exception e)
            {
                TraceHelper.TraceEvent(this.sessionId, TraceEventType.Error, "[BrokerInfo] Failed to initialize broker: {0}", e.ToString());

                // If in failover mode, close this broker and do not retry anymore
                if (failoverMode)
                {
                    try
                    {
                        this.CloseBroker(true);
                    }
                    catch (Exception ex)
                    {
                        TraceHelper.TraceEvent(TraceEventType.Warning, "[BrokerInfo].StartBroker: Exception {0}", ex);
                    }
                }

                throw;
            }
            finally
            {
                Utility.AsyncCloseICommunicationObject(client);
            }
        }
Пример #11
0
        /// <summary>
        /// Run the broker
        /// </summary>
        /// <param name="startInfo">session start info</param>
        /// <param name="brokerInfo">indicate the broker start info</param>
        /// <returns>initialization result</returns>
        public BrokerInitializationResult Run(SessionStartInfoContract startInfo, BrokerStartInfo brokerInfo)
        {
            BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerEntry] Broker is starting initialization, ID = {0}", brokerInfo.SessionId);

            try
            {
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: ClusterTopology is {0}", brokerInfo.NetworkTopology);

                // Step 1: Initialize configuration and shared data
                ServiceConfiguration serviceConfig;
                BrokerConfigurations brokerConfig;
                BindingsSection      bindings;
                SoaCommonConfig.WithoutSessionLayer = startInfo.IsNoSession; // TODO: this is a hack. Working mode should be decided by something like a *SchedulerType* filed.

                ConfigurationHelper.LoadConfiguration(startInfo, brokerInfo, out brokerConfig, out serviceConfig, out bindings);
                this.sharedData = new SharedData(brokerInfo, startInfo, brokerConfig, serviceConfig);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 1: Loading configuration and shared data succeeded.");
                Debug.WriteLine($"[BrokerEntry](Debug) UseAad:{startInfo.UseAad}");

                // Step 2: Initialize broker queue
                ClientInfo[] clientInfo;
                this.brokerQueueFactory = BrokerEntry.InitBrokerQueue(this.sharedData, out clientInfo);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 2: Initialize broker queue succeeded.");

                // Step 3: Initialize observer
                this.observer            = new BrokerObserver(this.sharedData, clientInfo);
                this.sharedData.Observer = this.observer;
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 3: Initialize broker observer succeeded.");

                // Step 4: Initialize state manager
                this.stateManager = new BrokerStateManager(this.sharedData, clientInfo.Length != 0);
                this.stateManager.UnloadBroker += this.UnloadBroker;
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 4: Initialize broker state manager succeeded.");

                // Step 5: Initialize service job monitor
                var context = TelepathyContext.GetOrAdd(this.sharedData.BrokerInfo.Headnode);

                if (SoaCommonConfig.WithoutSessionLayer)
                {
                    this.monitor = new DummyServiceJobMonitor(this.sharedData, this.stateManager, this.nodeMappingData, context);
                }
                else
                {
                    this.monitor = new ServiceJobMonitor.ServiceJobMonitor(this.sharedData, this.stateManager, this.nodeMappingData, context);
                }
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 5: Initialize service job monitor succeeded.");

                // Step 6: Initalize broker authorization
                this.brokerAuth = BrokerEntry.BuildBrokerAuthorization(this.sharedData);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 6: Initialize broker authorization succeeded.");

                // Step 7: Initialize dispatcher manager
                DispatcherManager dispatcherManager = new DispatcherManager(bindings, this.sharedData, this.observer, this.monitor, this.brokerQueueFactory, context);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 7: Initialize dispatcher manager succeeded.");

                // Step 8: Start service job monitor
                this.monitor.Start(startInfo, dispatcherManager, this.observer).GetAwaiter().GetResult();
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 8: Start service job monitor succeeded.");

                // Step 9: Initailize client manager
                this.clientManager = new BrokerClientManager(clientInfo, this.brokerQueueFactory, this.observer, this.stateManager, this.monitor, this.sharedData);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 9: Initialize client manager succeeded.");

                // if using AzureQueue, retrieve the connection string and build the request and response message queues if not exist
                string[] requestQueueUris           = { };
                string   requestBlobUri             = string.Empty;
                string   controllerRequestQueueUri  = string.Empty;
                string   controllerResponseQueueUri = string.Empty;
                if (startInfo.UseAzureStorage)
                {
                    int clusterHash = 0;
                    if (!string.IsNullOrEmpty(brokerInfo.ClusterId))
                    {
                        string clusterIdString = brokerInfo.ClusterId.ToLowerInvariant();
                        clusterHash = clusterIdString.GetHashCode();
                    }
                    else if (!string.IsNullOrEmpty(brokerInfo.ClusterName))
                    {
                        string clusterNameString = brokerInfo.ClusterName.ToLowerInvariant();
                        clusterHash = clusterNameString.GetHashCode();
                    }
                    else
                    {
                        throw new InvalidOperationException($"Both {nameof(brokerInfo.ClusterId)} and {nameof(brokerInfo.ClusterName)} are null or empty. No {nameof(clusterHash)} can be determined.");
                    }

                    if (!string.IsNullOrEmpty(brokerInfo.AzureStorageConnectionString))
                    {
                        this.azureQueueProxy = new AzureQueueProxy(brokerInfo.ClusterName, clusterHash, this.SessionId, brokerInfo.AzureStorageConnectionString);
                        requestQueueUris     = this.azureQueueProxy.RequestQueueUris;
                        requestBlobUri       = this.azureQueueProxy.RequestBlobUri;
                        var requestQName  = CloudQueueConstants.GetBrokerWorkerControllerRequestQueueName(this.SessionId);
                        var responseQName = CloudQueueConstants.GetBrokerWorkerControllerResponseQueueName(this.SessionId);
                        controllerRequestQueueUri = CloudQueueCreationModule.CreateCloudQueueAndGetSas(
                            brokerInfo.AzureStorageConnectionString,
                            requestQName,
                            CloudQueueCreationModule.AddMessageSasPolicy).GetAwaiter().GetResult();
                        controllerResponseQueueUri = CloudQueueCreationModule.CreateCloudQueueAndGetSas(
                            brokerInfo.AzureStorageConnectionString,
                            responseQName,
                            CloudQueueCreationModule.ProcessMessageSasPolicy).GetAwaiter().GetResult();
                        if (this.SessionId == SessionStartInfo.StandaloneSessionId)
                        {
                            CloudQueueCreationModule.ClearCloudQueuesAsync(brokerInfo.AzureStorageConnectionString, new[] { requestQName, responseQName });
                        }
                    }
                    else
                    {
                        BrokerTracing.TraceError("[BrokerEntry] Initialization: Use Azure Queue is specified, however the Azure connection string is not set.");
                        ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_AzureConnectionStringNotAvailable, SR.Broker_AzureConnectionStringNotAvailable);
                    }
                }

                // Step 10: Initialize frontend
                this.frontendResult = FrontEndBuilder.BuildFrontEnd(this.sharedData, this.observer, this.clientManager, this.brokerAuth, bindings, this.azureQueueProxy);
                ////this.maxMessageSize = (int)this.frontendResult.MaxMessageSize;
                ////this.readerQuotas = this.frontendResult.ReaderQuotas;
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 10: Initialize frontend succeeded.");

                // Step 11: Start frontend, Initialization finished after this step
                this.OpenFrontend();
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 11: Open frontend succeeded.");

                // Step 12: Build initialization result and retrun to client
                BrokerInitializationResult result = BrokerEntry.BuildInitializationResult(
                    this.frontendResult,
                    dispatcherManager,
                    this.sharedData.Config.LoadBalancing.ServiceOperationTimeout,
                    this.sharedData.Config.Monitor.ClientBrokerHeartbeatInterval,
                    this.sharedData.Config.Monitor.ClientBrokerHeartbeatRetryCount,
                    requestQueueUris,
                    requestBlobUri,
                    controllerRequestQueueUri,
                    controllerResponseQueueUri,
                    startInfo.UseAzureStorage);
                BrokerTracing.TraceVerbose("[BrokerEntry] Initialization: Step 12: Build initialization result suceeded.");
                BrokerTracing.TraceInfo("[BrokerEntry] Initialization succeeded.");
                return(result);
            }
            catch (Exception ex)
            {
                BrokerTracing.TraceError(ex.ToString());
                throw;
            }
            finally
            {
                if (this.sharedData != null)
                {
                    this.sharedData.InitializationFinished();
                }
            }
        }