/// <summary> /// For Java to pull the responses /// </summary> /// <param name="action">indicating the action</param> /// <param name="position">indicating the position</param> /// <param name="count">indicating the count</param> /// <param name="clientId">indicating the client id</param> /// <returns>returns the responses messages</returns> public BrokerResponseMessages PullResponses(string action, GetResponsePosition position, int count, string clientId) { try { ParamCheckUtility.ThrowIfOutofRange(count <= 0, "count"); ParamCheckUtility.ThrowIfNull(clientId, "clientId"); ParamCheckUtility.ThrowIfTooLong(clientId.Length, "clientId", Constant.MaxClientIdLength, SR.ClientIdTooLong); ParamCheckUtility.ThrowIfNotMatchRegex(ParamCheckUtility.ClientIdValid, clientId, "clientId", SR.InvalidClientId); BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerController] PullResponses: Action = {0}, Position = {1}, Count = {2}", action, position, count); this.ThrowIfDisposed(); this.CheckAuth(); #region Debug Failure Test SimulateFailure.FailOperation(1); #endregion return(this.GetClient(clientId).PullResponses(action, position, count, GetMessageVersion())); } catch (Exception e) { BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerController] PullResponses Failed: {0}", e); throw TranslateException(e); } }
public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { ParamCheckUtility.ThrowIfNull(info, "info"); info.AddValue(BrokerQueueItem.MessageVersionTag, SerializeMessageVersion(this.Message.Version)); MemoryStream msgStream = null; try { msgStream = new MemoryStream(); using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(msgStream)) { var msgStreamTemp = msgStream; msgStream = null; this.Message.WriteMessage(writer); writer.Flush(); info.AddValue(BrokerQueueItem.MessageTag, msgStreamTemp.ToArray()); } } finally { if (msgStream != null) { msgStream.Dispose(); } } BrokerQueueItem.SerializeObject(info, this.asyncState, BrokerQueueItem.AsyncStateTag); BrokerQueueItem.SerializeObject(info, this.persistGuid, BrokerQueueItem.PersistIdTag); }
/// <summary> /// Ask broker to initialize /// </summary> /// <param name="startInfo">indicating the start info</param> /// <param name="brokerInfo">indicating the broker info</param> /// <returns>returns broker initialization result</returns> public BrokerInitializationResult Initialize(SessionStartInfoContract startInfo, BrokerStartInfo brokerInfo) { ParamCheckUtility.ThrowIfNull(startInfo, "startInfo"); ParamCheckUtility.ThrowIfNull(brokerInfo, "brokerInfo"); // Concurrent mode is set to single so no need to lock here if (this.entry != null) { ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_AlreadyInitialized, SR.AlreadyInitialized); } // Notice: We get the session Id here and expect to change the // cosmos log file name to include session id. But cosmos log has a // limitation that it is a static class without close method, and // it can't be initialized twice. HpcTraceListener is just a wrapper // for that static class. So creating a new HpcTraceListener can not // workaround this issue. TraceHelper.TraceInfo( brokerInfo.SessionId, "[BrokerManagementService].Initialize: Broker worker initializes for session {0}", brokerInfo.SessionId); // Set the configuration indicating enable/disable diag trace SoaDiagTraceHelper.SetDiagTraceEnabledFlag(brokerInfo.SessionId, brokerInfo.EnableDiagTrace); TraceHelper.IsDiagTraceEnabled = SoaDiagTraceHelper.IsDiagTraceEnabled; Environment.SetEnvironmentVariable(SessionIdEnv, brokerInfo.SessionId.ToString(), EnvironmentVariableTarget.Process); #if HPCPACK // create the session id mapping file foreach (TraceListener listener in TraceHelper.RuntimeTrace.CosmosTrace.Listeners) { if (listener is HpcTraceListener) { HpcTraceListener hpcListener = listener as HpcTraceListener; if (hpcListener.IsPerSessionLogging) { string logIdFileName = string.Format("{0}_{1}", HpcTraceListener.LogFileBaseName, brokerInfo.SessionId); string logIdFilePath = Path.Combine(HpcTraceListener.LogDir, logIdFileName); try { using (FileStream file = File.Open(logIdFilePath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.None)) { } } catch (Exception e) { TraceHelper.TraceError(brokerInfo.SessionId, "[BrokerManagementService].Initialize: Create log session Id match file failed with Exception {0}", e.ToString()); } } } } #endif this.entry = new BrokerEntry(brokerInfo.SessionId); this.entry.BrokerFinished += new EventHandler(this.Entry_BrokerFinished); return(this.entry.Run(startInfo, brokerInfo)); }
/// <summary> /// remove the broker queue from the cached list. /// </summary> /// <param name="clientId">the client id.</param> internal void RemovePersistQueueByClient(string clientId) { ParamCheckUtility.ThrowIfNull(clientId, "clientId"); BrokerTracing.TraceInfo("[BrokerQueueFactory] .RemovePersistQueueByClient: ClientId:{0}", clientId); lock (this.clientBrokerQueueDic) { if (this.clientBrokerQueueDic.ContainsKey(clientId)) { this.clientBrokerQueueDic.Remove(clientId); } } }
public void GetRequestAsync(BrokerQueueCallback requestCallback, object state) { ParamCheckUtility.ThrowIfNull(requestCallback, "requestCallback"); bool isCallbackHandled = false; if (this.requestCacheQueue.Count > 0) { BrokerQueueItem request = null; if (!this.requestCacheQueue.TryDequeue(out request)) { BrokerTracing.TraceInfo("[BrokerQueueDispatcher] .GetRequestAsync: All cached requests are dispatched."); } if (request != null) { try { #if DEBUG BrokerTracing.TraceVerbose("[BrokerQueueDispatcher] .GetRequestAsync: handle request callback from cache queue. request id={0}", GetMessageId(request)); #endif this.RegisterReemit(request); isCallbackHandled = true; requestCallback(request, state); } catch (Exception e) { this.requestCacheQueue.Enqueue(request); // request callback raise exception. BrokerTracing.TraceWarning("[BrokerQueueDispatcher] .GetRequestAsync: The request callback raise exception. Exception: {0}", e); } } } if (this.requestCacheQueue.Count <= this.watermarkerForTriggerPrefetch) { BrokerTracing.TraceVerbose("[BrokerQueueDispatcher] .GetRequestAsync (perf): Trigger prefetch because the count of cached items is below threshold. state={0}", (int)state); this.TriggerPrefetch(); } if (!isCallbackHandled) { this.requestCallbackQueue.Enqueue(new BrokerQueueCallbackItem(requestCallback, state)); // in case the last request come in the cache queue right before the request callback enqueue. this.HandlePendingRequestCallback(); } }
/// <summary> /// cleanup the stale persisted data for the sessions that related jobs are purged by the scheduler. /// </summary> /// <param name="persistName">the persist name.</param> /// <param name="isStaleSessionCallback">the calback function to judge whether a session is stale.</param> public static async Task CleanupStalePersistedData(string persistName, IsStaleSessionCallback isStaleSessionCallback, string connectString) { ParamCheckUtility.ThrowIfNull(isStaleSessionCallback, "isStaleSessionCallback"); if (!string.IsNullOrEmpty(persistName)) { if (persistName.Trim().Equals("AzureQueue", StringComparison.OrdinalIgnoreCase)) { BrokerTracing.TraceInfo( "[BrokerQueueFactory] .CleanupStalePersistedData: cleaning up stale data in AzureQueue"); await AzureQueuePersist .CleanupStaleMessageQueue(isStaleSessionCallback, connectString); } else { throw new ArgumentOutOfRangeException("persistName", persistName + ", which persistence is not supported."); } } }
/// <summary> /// Send requests /// </summary> /// <param name="message">indicating the message</param> void IBrokerFrontend.SendRequest(Message message) { string clientId = FrontEndBase.GetClientId(message, String.Empty); try { ParamCheckUtility.ThrowIfNull(clientId, "clientId"); ParamCheckUtility.ThrowIfTooLong(clientId.Length, "clientId", Constant.MaxClientIdLength, SR.ClientIdTooLong); ParamCheckUtility.ThrowIfNotMatchRegex(ParamCheckUtility.ClientIdValid, clientId, "clientId", SR.InvalidClientId); this.observer.IncomingRequest(); this.GetClient(clientId).RequestReceived(DummyRequestContext.GetInstance(MessageVersion.Default), message, null); } catch (Exception e) { BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerController] SendRequest {1} Failed: {0}", e, clientId); throw TranslateException(e); } }
/// <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); } }
/// <summary> /// Purge a client /// </summary> /// <param name="clientId">indicating the client id</param> public void Purge(string clientId) { try { ParamCheckUtility.ThrowIfNull(clientId, "clientId"); ParamCheckUtility.ThrowIfTooLong(clientId.Length, "clientId", Constant.MaxClientIdLength, SR.ClientIdTooLong); ParamCheckUtility.ThrowIfNotMatchRegex(ParamCheckUtility.ClientIdValid, clientId, "clientId", SR.InvalidClientId); BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerController] Purge Client {0}", clientId); this.ThrowIfDisposed(); this.CheckAuth(); this.clientManager.PurgeClient(clientId, GetUserName()).GetAwaiter().GetResult(); BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerController] Purge Client {0} Succeeded.", clientId); } catch (Exception e) { BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerController] Purge Client {1} Failed: {0}", e, clientId); throw TranslateException(e); } }
/// <summary> /// Gets number of requests that have been committed into specified client /// </summary> /// <param name="clientId">client id</param> /// <returns>number of committed requests in the client with specified client id</returns> public int GetRequestsCount(string clientId) { try { ParamCheckUtility.ThrowIfNull(clientId, "clientId"); ParamCheckUtility.ThrowIfTooLong(clientId.Length, "clientId", Constant.MaxClientIdLength, SR.ClientIdTooLong); ParamCheckUtility.ThrowIfNotMatchRegex(ParamCheckUtility.ClientIdValid, clientId, "clientId", SR.InvalidClientId); BrokerTracing.TraceInfo("[BrokerController] Get requests count for Client {0}", clientId); this.ThrowIfDisposed(); this.CheckAuth(); return(this.GetClient(clientId).RequestsCount); } catch (Exception e) { BrokerTracing.TraceError("[BrokerController] Get requests for Client {1} Failed: {0}", e, clientId); throw TranslateException(e); } }
/// <summary> /// Initializes a new instance of the PersistMessage class for deserialization. /// </summary> /// <param name="info">the serializaion info.</param> /// <param name="context">the serialization context.</param> protected BrokerQueueItem(SerializationInfo info, StreamingContext context) { ParamCheckUtility.ThrowIfNull(info, "info"); MessageVersion version = DeserializeMessageVersion(info.GetInt32(MessageVersionTag)); using (XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader((byte[])info.GetValue(BrokerQueueItem.MessageTag, typeof(byte[])), BrokerEntry.ReaderQuotas)) { using (Message messageTmp = Message.CreateMessage(reader, BrokerEntry.MaxMessageSize, version)) { this.buffer = messageTmp.CreateBufferedCopy(BrokerEntry.MaxMessageSize); } } int deserializeFlags = 0; foreach (SerializationEntry entry in info) { switch (entry.Name) { case BrokerQueueItem.AsyncStateTag: this.asyncState = BrokerQueueItem.DeserializeObject(entry); deserializeFlags |= 1; break; case BrokerQueueItem.PersistIdTag: this.persistGuid = (Guid)BrokerQueueItem.DeserializeObject(entry); deserializeFlags |= 2; break; } if (deserializeFlags == 3) { break; } } this.context = BrokerQueueItem.DummyRequestContextField; this.asyncToken = new BrokerQueueAsyncToken(this.persistGuid, this.asyncState, null, 0); }
/// <summary> /// Get responses from client /// </summary> /// <param name="action">indicating the action</param> /// <param name="clientData">indicating the client data</param> /// <param name="resetToBegin">indicating the position</param> /// <param name="count">indicating the count</param> /// <param name="clientId">indicating the client id</param> public void GetResponses(string action, string clientData, GetResponsePosition resetToBegin, int count, string clientId) { try { BrokerTracing.TraceVerbose("[BrokerController] GetResponses is called for Client {0}.", clientId); ParamCheckUtility.ThrowIfOutofRange(count <= 0 && count != -1, "count"); ParamCheckUtility.ThrowIfNull(clientId, "clientId"); ParamCheckUtility.ThrowIfTooLong(clientId.Length, "clientId", Constant.MaxClientIdLength, SR.ClientIdTooLong); ParamCheckUtility.ThrowIfNotMatchRegex(ParamCheckUtility.ClientIdValid, clientId, "clientId", SR.InvalidClientId); BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerController] GetResponses for Client {2}, Count = {0}, Position = {1}", count, resetToBegin, clientId); this.ThrowIfDisposed(); this.CheckAuth(); // Try to get callback instance for inprocess broker IResponseServiceCallback callbackInstance = this.callbackInstance; // If callback instance is null, get callback instance from operation context if (callbackInstance == null) { callbackInstance = OperationContext.Current.GetCallbackChannel <IResponseServiceCallback>(); } this.GetClient(clientId).GetResponses(action, clientData, resetToBegin, count, callbackInstance, GetMessageVersion()); #region Debug Failure Test SimulateFailure.FailOperation(1); #endregion BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerController] GetResponses for Client {0} Succeeded.", clientId); } catch (Exception e) { BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerController] GetResponses for Client {1} Failed: {0}", e, clientId); throw TranslateException(e); } }
/// <summary> /// Gets broker client status /// </summary> /// <param name="clientId">indicating the client id</param> /// <returns>returns the broker client status</returns> public BrokerClientStatus GetBrokerClientStatus(string clientId) { try { ParamCheckUtility.ThrowIfNull(clientId, "clientId"); ParamCheckUtility.ThrowIfTooLong(clientId.Length, "clientId", Constant.MaxClientIdLength, SR.ClientIdTooLong); ParamCheckUtility.ThrowIfNotMatchRegex(ParamCheckUtility.ClientIdValid, clientId, "clientId", SR.InvalidClientId); BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerController] Get broker client status for Client {0}", clientId); this.ThrowIfDisposed(); this.CheckAuth(); BrokerClientState state = this.GetClient(clientId).State; return(BrokerClient.MapToBrokerClientStatus(state)); } catch (Exception e) { BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerController] Get broker client status for Client {1} Failed: {0}", e, clientId); throw TranslateException(e); } }
/// <summary> /// Indicate the end of requeusts /// </summary> /// <param name="count">indicating the number of the messages</param> /// <param name="timeoutMs">indicating the timeout in MS</param> /// <param name="clientId">indicating the client id</param> public void EndRequests(int count, string clientId, int batchId, int timeoutThrottlingMs, int timeoutEOMMs) { ParamCheckUtility.ThrowIfOutofRange(count < 0, "count"); ParamCheckUtility.ThrowIfOutofRange(timeoutThrottlingMs <= 0 && timeoutThrottlingMs != Timeout.Infinite, "timeoutThrottlingMs"); ParamCheckUtility.ThrowIfOutofRange(timeoutEOMMs <= 0 && timeoutEOMMs != Timeout.Infinite, "timeoutEOMMs"); ParamCheckUtility.ThrowIfNull(clientId, "clientId"); ParamCheckUtility.ThrowIfTooLong(clientId.Length, "clientId", Constant.MaxClientIdLength, SR.ClientIdTooLong); ParamCheckUtility.ThrowIfNotMatchRegex(ParamCheckUtility.ClientIdValid, clientId, "clientId", SR.InvalidClientId); this.ThrowIfDisposed(); this.CheckAuth(); BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerController] Receive EOM for Client {0}, Count = {1}", clientId, count); try { #region Debug Failure Test SimulateFailure.FailOperation(1); #endregion BrokerClient brokerClient = this.GetClient(clientId); FrontEndBase frontendBase = brokerClient.GetDuplexFrontEnd(); WaitOnThrottling(frontendBase, timeoutThrottlingMs); // Then handle the EOM which waits until all requests are stored. Use user specified EndRequests timeout for this brokerClient.EndOfMessage(count, batchId, timeoutEOMMs); #region Debug Failure Test SimulateFailure.FailOperation(2); #endregion } catch (Exception e) { BrokerTracing.TraceError("[BrokerController] EOM failed for client {0}: {1}", clientId, e); throw TranslateException(e); } }
/// <summary> /// Allocate a new durable or non-durable session /// </summary> /// <param name="startInfo">session start info</param> /// <param name="durable">whether session should be durable</param> /// <param name="endpointPrefix">the endpoint prefix, net.tcp:// or https:// </param> /// <returns>the Broker Launcher EPRs, sorted by the preference.</returns> protected virtual async Task <SessionAllocateInfoContract> AllocateInternalAsync(SessionStartInfoContract startInfo, string endpointPrefix, bool durable) { TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] Begin: AllocateInternalAsync"); SessionAllocateInfoContract sessionAllocateInfo = new SessionAllocateInfoContract(); ParamCheckUtility.ThrowIfNull(startInfo, "startInfo"); ParamCheckUtility.ThrowIfNullOrEmpty(startInfo.ServiceName, "startInfo.ServiceName"); ParamCheckUtility.ThrowIfNullOrEmpty(endpointPrefix, "endpointPrefix"); #if HPCPACK // check client api version, 4.3 or older client is not supported by 4.4 server for the broken changes if (startInfo.ClientVersion == null || startInfo.ClientVersion < new Version(4, 4)) { TraceHelper.TraceEvent(TraceEventType.Error, "[SessionLauncher] .AllocateInternalAsync: ClientVersion {0} does not match ServerVersion {1}.", startInfo.ClientVersion, ServerVersion); ThrowHelper.ThrowSessionFault(SOAFaultCode.ClientServerVersionMismatch, SR.SessionLauncher_ClientServerVersionMismatch, startInfo.ClientVersion == null ? "NULL" : startInfo.ClientVersion.ToString(), ServerVersion.ToString()); } #endif // Init service version to the service version passed in if (startInfo.ServiceVersion != null) { sessionAllocateInfo.ServiceVersion = startInfo.ServiceVersion; TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: Original service version is {0}", sessionAllocateInfo.ServiceVersion); } else { sessionAllocateInfo.ServiceVersion = null; TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: Original service version is null."); } string callId = Guid.NewGuid().ToString(); this.CheckAccess(); SecureString securePassword = CreateSecureString(startInfo.Password); startInfo.Password = null; // BUG 4522 : Use CCP_SCHEDULER when referencing service registration file share so HA HN virtual name is used when needed //var reliableRegistry = new ReliableRegistry(this.fabricClient.PropertyManager); //string defaultServiceRegistrationServerName = await reliableRegistry.GetValueAsync<string>(HpcConstants.HpcFullKeyName, HpcConstants.FileShareServerRegVal, this.token); //if (String.IsNullOrEmpty(defaultServiceRegistrationServerName)) //{ // defaultServiceRegistrationServerName = "localhost"; //} // the reg repo path is from scheduler environments, defaultServiceRegistrationServerName is actually not used string serviceConfigFile; ServiceRegistrationRepo serviceRegistration = this.GetRegistrationRepo(callId); serviceConfigFile = serviceRegistration.GetServiceRegistrationPath(startInfo.ServiceName, startInfo.ServiceVersion); // If the serviceConfigFile wasnt found and serviceversion isnt specified, try getitng the service config based on the service's latest version if (string.IsNullOrEmpty(serviceConfigFile) && (startInfo.ServiceVersion == null)) { TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: Try to find out versioned service."); // Get service version in ServiceRegistrationRepo Version dynamicServiceVersion = serviceRegistration.GetServiceVersionInternal(startInfo.ServiceName, false); if (dynamicServiceVersion != null) { TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: Selected dynamicServiceVersion is {0}.", dynamicServiceVersion.ToString()); } serviceConfigFile = serviceRegistration.GetServiceRegistrationPath(startInfo.ServiceName, dynamicServiceVersion); // If a config file is found, update the serviceVersion that is returned to client and stored in recovery info if (!string.IsNullOrEmpty(serviceConfigFile)) { TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: serviceConfigFile is {0}.", serviceConfigFile); startInfo.ServiceVersion = dynamicServiceVersion; if (dynamicServiceVersion != null) { sessionAllocateInfo.ServiceVersion = dynamicServiceVersion; } } } string serviceName = ServiceRegistrationRepo.GetServiceRegistrationFileName(startInfo.ServiceName, startInfo.ServiceVersion); TraceHelper.TraceEvent(TraceEventType.Verbose, "[SessionLauncher] .AllocateInternalAsync: Service name = {0}, Configuration file = {1}", serviceName, serviceConfigFile); // If the service is not found and user code doesn't specify // version, we will use the latest version. if (string.IsNullOrEmpty(serviceConfigFile)) { if (startInfo.ServiceVersion != null) { ThrowHelper.ThrowSessionFault(SOAFaultCode.ServiceVersion_NotFound, SR.SessionLauncher_ServiceVersionNotFound, startInfo.ServiceName, startInfo.ServiceVersion.ToString()); } else { ThrowHelper.ThrowSessionFault(SOAFaultCode.Service_NotFound, SR.SessionLauncher_ServiceNotFound, startInfo.ServiceName); } } ExeConfigurationFileMap map = new ExeConfigurationFileMap(); map.ExeConfigFilename = serviceConfigFile; ServiceRegistration registration = null; BrokerConfigurations brokerConfigurations = null; string hostpath = null; string traceSwitchValue = null; try { Configuration config = null; RetryManager.RetryOnceAsync( () => config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None), TimeSpan.FromSeconds(1), ex => ex is ConfigurationErrorsException).GetAwaiter().GetResult(); Debug.Assert(config != null, "Configuration is not opened properly."); registration = ServiceRegistration.GetSectionGroup(config); brokerConfigurations = BrokerConfigurations.GetSectionGroup(config); if (registration != null && registration.Host != null && registration.Host.Path != null) { hostpath = registration.Host.Path; } else { // x86 or x64 hostpath = registration.Service.Architecture == ServiceArch.X86 ? TaskCommandLine32 : TaskCommandLine64; } traceSwitchValue = registration.Service.SoaDiagTraceLevel; // TODO: should deprecate the previous settings if (string.IsNullOrEmpty(traceSwitchValue)) { traceSwitchValue = ConfigurationHelper.GetTraceSwitchValue(config); } } catch (ConfigurationErrorsException e) { ThrowHelper.ThrowSessionFault(SOAFaultCode.ConfigFile_Invalid, SR.SessionLauncher_ConfigFileInvalid, e.ToString()); } catch (Exception ex) { TraceHelper.TraceEvent(TraceEventType.Error, ex.ToString()); throw; } // after figuring out the service and version, and the session pool size, we check if the service pool already has the instance. sessionAllocateInfo.Id = "0"; sessionAllocateInfo.SessionInfo = null; if (startInfo.UseSessionPool) { if (this.TryGetSessionAllocateInfoFromPooled(endpointPrefix, durable, sessionAllocateInfo, serviceConfigFile, registration, out var allocateInternal)) { return(allocateInternal); } } // for sessions to add in session pool try { var sessionAllocateInfoContract = await this.CreateAndSubmitSessionJob( startInfo, endpointPrefix, durable, callId, securePassword, registration, sessionAllocateInfo, traceSwitchValue, serviceName, brokerConfigurations, hostpath); if (sessionAllocateInfoContract != null) { return(sessionAllocateInfoContract); } } finally { // Add the submitted job to the session pool. if (startInfo.UseSessionPool) { this.AddSessionToPool(Path.GetFileNameWithoutExtension(serviceConfigFile), durable, sessionAllocateInfo.Id, registration.Service.MaxSessionPoolSize); } } return(null); }
/// <summary> /// Initializes a new instance of the BrokerQueueCallbackItem class. /// </summary> /// <param name="brokerQueueCallback">the response/request callback.</param> /// <param name="state">the state object for the callback.</param> public BrokerQueueCallbackItem(BrokerQueueCallback brokerQueueCallback, object state) { ParamCheckUtility.ThrowIfNull(brokerQueueCallback, "brokerQueueCallback"); this.brokerQueueCallbackField = brokerQueueCallback; this.callbackStateField = state; }
public BrokerQueue GetPersistQueueByClient(string clientId, string userName, out bool isNewCreate) { BrokerTracing.TraceInfo($"[GetPersistQueueByClient] username:{userName}, sessionid:{this.sessionId}, client:{clientId}"); isNewCreate = false; if (string.IsNullOrEmpty(clientId)) { clientId = BrokerQueueFactory.defaultClientId; } BrokerQueue brokerQueue = null; lock (this.clientBrokerQueueDic) { this.clientBrokerQueueDic.TryGetValue(clientId, out brokerQueue); } if (brokerQueue == null) { lock (this.thisLockObj) { lock (this.clientBrokerQueueDic) { this.clientBrokerQueueDic.TryGetValue(clientId, out brokerQueue); } if (brokerQueue == null) { ISessionPersist sessionPersist = null; if (string.IsNullOrEmpty(this.persistName)) { sessionPersist = new MemoryPersist(userName, this.sessionId, clientId); brokerQueue = new BrokerPersistQueue( this.brokerQueueDispatcher, this.persistName, this.sessionId, clientId, sessionPersist, 1, // no request cache // no request cache 1, // no response cache // no response cache 0, // no timeout // no timeout false, // no in-memory cache this.sharedData, this); this.brokerQueueDispatcher.AddBrokerQueue(brokerQueue, null); } else { ParamCheckUtility.ThrowIfNull(this.sharedData.BrokerInfo.AzureStorageConnectionString, "StorageConnectString"); sessionPersist = new AzureQueuePersist(userName, this.sessionId, clientId, this.sharedData.BrokerInfo.AzureStorageConnectionString); isNewCreate = sessionPersist.IsNewCreated; brokerQueue = new BrokerPersistQueue( this.brokerQueueDispatcher, this.persistName, this.sessionId, clientId, sessionPersist, BrokerQueueConstants.DefaultThresholdForRequestPersist, BrokerQueueConstants.DefaultThresholdForResponsePersist, BrokerQueueConstants.DefaultMessagesInCacheTimeout, isNewCreate, // need in-memory quick cache for newly-created durable queue // need in-memory quick cache for newly-created durable queue this.sharedData, this); // // For an existing durable queue, if EndOfMessage is not received, or there are requests waiting to be processed, // then schedule the broker queue for dispatching; // for an newly created durable queue, it will be added to brokerQueueDispatcher when BrokerQueuePersist.Flush // is called (with quick cache filled), so no need to call AddBrokerQueue here (bug #21453) // if (!isNewCreate && (!brokerQueue.EOMReceived || sessionPersist.RequestsCount > 0)) { this.brokerQueueDispatcher.AddBrokerQueue(brokerQueue, null); } } lock (this.clientBrokerQueueDic) { this.clientBrokerQueueDic.Add(clientId, brokerQueue); } } } } // Bug 6313: Check the user name ThrowIfUserNameDoesNotMatch(brokerQueue, userName); return(brokerQueue); }