Exemple #1
0
        /// <summary>
        /// Get a response from the storage
        /// </summary>
        /// <param name="callback">the response callback, the async result should be the BrokerQueueItem</param>
        /// <param name="callbackState">the state object for the callback</param>
        public void GetResponseAsync(PersistCallback callback, object callbackState)
        {
            if (this.isClosedField)
            {
                BrokerTracing.TraceWarning("[MemoryPersist] .GetResponseAsync: the queue is closed.");
                return;
            }

            BrokerQueueItem responseItem = null;

            try
            {
                lock (this.lockResponseQueueField)
                {
                    responseItem = this.responseQueueField.Dequeue();
                }
            }
            catch (InvalidOperationException)
            {
                BrokerTracing.TraceError("[MemoryPersist] .GetResponseAsync: no response available.  sessionId = {0}, clientId = {1}", this.sessionIdField, this.clientIdField);
            }

            if (callback == null)
            {
                return;
            }

            ThreadPool.QueueUserWorkItem(this.GetOperationComplete, new GetCallbackContext(callback, callbackState, responseItem));
        }
        /// <summary>
        /// Add QueueAsyncResult to the dictionary.
        /// </summary>
        /// <param name="result">async result</param>
        /// <param name="requestQueueName">request queue name</param>
        /// <param name="responseQueueName">response queue name</param>
        public void AddQueueAsyncResult(QueueAsyncResult result, string requestQueueName, string responseQueueName)
        {
            ResponseStorageException e;

            this.responseQueueNotFound.TryGetValue(responseQueueName, out e);

            if (e == null)
            {
                BrokerTracing.TraceVerbose(
                    "[AzureQueueManager].AddQueueAsyncResult: Add QueueAsyncResult {0} to the dictionary.",
                    result.MessageId);

                this.callbacks.AddOrUpdate(result.MessageId, result, (key, value) => result);

                this.requestsMappingToRequestQueue.AddOrUpdate(result.MessageId, requestQueueName, (key, value) => requestQueueName);

                this.requestsMappingToResponseQueue.AddOrUpdate(result.MessageId, responseQueueName, (key, value) => responseQueueName);
            }
            else
            {
                BrokerTracing.TraceError(
                    "[AzureQueueManager].AddQueueAsyncResult: Response queue is not found, {0}",
                    responseQueueName);

                throw e;
            }
        }
        public static async Task DeleteTableAsync(string connectString, string sessionId, string responseTableName)
        {
            var info = new QueueInfo(sessionId, responseTableName);

            info.ETag = "*"; // no etag cannot delete.
            try
            {
                var table           = GetTableClient(connectString).GetTableReference(queueTableName);
                var deleteOperation = TableOperation.Delete(info);
                await table.ExecuteAsync(deleteOperation);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError(
                    "[AzureStorageTool] .DeleteTableAsync: Table={0} delete from storage table failed, the exception, {1}",
                    responseTableName,
                    e);
                throw;
            }

            try
            {
                var responseTable = GetTableClient(connectString).GetTableReference(responseTableName);
                await responseTable.DeleteIfExistsAsync();
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError(
                    "[AzureStorageTool] .DeleteTableAsync: Table={0} delete failed, the exception, {1}",
                    responseTableName,
                    e);
                throw;
            }
        }
        /// <summary>
        /// Async method of ProcessMessage.
        /// </summary>
        /// <param name="ar">async result</param>
        /// <returns>response message</returns>
        public Message EndProcessMessage(IAsyncResult ar)
        {
            QueueAsyncResult asyncResult = ar as QueueAsyncResult;

            Debug.Assert(asyncResult != null, "ar must be a QueueAsyncResult.");

            using (asyncResult)
            {
                UniqueId messageId = asyncResult.MessageId;

                try
                {
                    this.manager.RemoveQueueAsyncResult(messageId);
                }
                catch (Exception e)
                {
                    BrokerTracing.TraceError(
                        "[AzureServiceClient].EndProcessMessage: Failed to remove QueueAsyncResult {0}, {1}",
                        messageId,
                        e);
                }

                if (asyncResult.Exception != null)
                {
                    throw asyncResult.Exception;
                }
                else
                {
                    return(asyncResult.ResponseMessage);
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Add a dispatcher to blocked dispatcher list
        /// </summary>
        /// <param name="dispatcherInfo">dispatcher info</param>
        private void AddBlockedDispatcher(DispatcherInfo dispatcherInfo)
        {
            try
            {
                dispatcherInfo.BlockTime = DateTime.Now;
                this.blockedDispatcherDic.Add(dispatcherInfo.UniqueId, dispatcherInfo);

                // if a dispatcher has never been blocked, take it as "young" blocked disaptcher.
                if (dispatcherInfo.BlockRetryCount <= 0)
                {
                    BrokerTracing.TraceVerbose("[DispatcherManager] Increment youngBlockedDispatcherCount, task id={0}, BlockRetryCount={1}", dispatcherInfo.UniqueId, dispatcherInfo.BlockRetryCount);
                    this.youngBlockedDispatcherCount++;
                }

                this.blockedDispatcherQueue.Enqueue(dispatcherInfo);
                if (this.blockedDispatcherQueue.Count == 1)
                {
                    BrokerTracing.TraceVerbose("[DispatcherManager] Block dispatcher: change unblock timer, task id = {0}", dispatcherInfo.UniqueId);
                    this.unblockTimer.Change(this.blockTimeSpan, TimeSpan.FromMilliseconds(-1));
                }
                BrokerTracing.TraceInfo("[DispatcherManager] Add dispatcher {0} into the blocked dispatcher list.", dispatcherInfo.UniqueId);
            }
            catch (ArgumentException)
            {
                BrokerTracing.TraceError("[DispatcherManager] Dispatcher {0} already exist in the blocked dispatcher list.", dispatcherInfo.UniqueId);
            }
        }
Exemple #6
0
        /// <summary>
        /// Dispose the object
        /// </summary>
        void IDisposable.Dispose()
        {
            int count = Interlocked.Decrement(ref this.refCount);

            if (count < 0)
            {
                BrokerTracing.TraceError("[ReferenceObject] Ref count is {0} in dispose method of {1} class", count, this.GetType());
                return;
            }
            else if (count == 0)
            {
#if DEBUG
                // In debug build, decrease the total count when disposing
                Interlocked.Decrement(ref totalCount);
#endif

                this.Dispose(true);
                GC.SuppressFinalize(this);
            }
            else
            {
                // If the real dispose method is not done by the call, wait until the real procedure is done
                // This wait handle makes sure that the real dispose procedure is done after the Dispose method is called, which guaranteed the dispose order
                this.disposeWaitHandle.WaitOne();
            }

            // Dispose the wait handle at last
            this.disposeWaitHandle.Close();
            this.disposeWaitHandle = null;
        }
        /// <summary>
        /// Remove QueueAsyncResult from the dictionary.
        /// </summary>
        /// <param name="messageId">message Id</param>
        public void RemoveQueueAsyncResult(UniqueId messageId)
        {
            string value;

            if (!this.requestsMappingToRequestQueue.TryRemove(messageId, out value))
            {
                BrokerTracing.TraceError(
                    "[AzureQueueManager].CompleteCallback: Failed to remove message Id {0} from requestsMappingToRequestQueue.",
                    messageId);
            }

            if (!this.requestsMappingToResponseQueue.TryRemove(messageId, out value))
            {
                BrokerTracing.TraceError(
                    "[AzureQueueManager].CompleteCallback: Failed to remove message Id {0} from requestsMappingToResponseQueue.",
                    messageId);
            }

            QueueAsyncResult result;

            if (!this.callbacks.TryRemove(messageId, out result))
            {
                BrokerTracing.TraceError(
                    "[AzureQueueManager].CompleteCallback: Failed to remove QueueAsyncResult {0} from callbacks.",
                    messageId);
            }
            else
            {
                BrokerTracing.TraceVerbose(
                    "[AzureQueueManager].CompleteCallback: Remove QueueAsyncResult {0} from callbacks.",
                    messageId);
            }
        }
Exemple #8
0
        /// <summary>
        /// Gets the broker frontend
        /// </summary>
        /// <param name="callbackInstance">indicating response service callback</param>
        /// <returns>returns the broker frontend instance</returns>
        public IBrokerFrontend GetFrontendForInprocessBroker(IResponseServiceCallback callbackInstance)
        {
            BrokerTracing.TraceInfo("[BrokerEntry] GetFrontendForInprocessBroker...");
            try
            {
                if (this.closeFlag != 0)
                {
                    if (this.cleanData)
                    {
                        ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerUnavailable, SR.BrokerIsUnavailable);
                    }
                    else
                    {
                        ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerSuspending, SR.BrokerSuspending);
                    }
                }

                this.sharedData.WaitForInitializationComplete();
                BrokerTracing.TraceInfo("[BrokerEntry] GetFrontendForInprocessBroker successfully.");
                return(new BrokerController(this.clientManager, callbackInstance, this.observer));
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError("[BrokerEntry] GetFrontendForInprocessBroker failed: {0}", e);
                throw;
            }
        }
        /// <summary>
        /// Process a collection of queue messages.
        /// </summary>
        /// <param name="messages">collection of the queue messages</param>
        private void ProcessMessages(IEnumerable <CloudQueueMessage> messages)
        {
            BrokerTracing.TraceInfo(SoaHelper.CreateTraceMessage("Proxy", "ProcessMessages", string.Format("Process {0} messages.", messages.Count <CloudQueueMessage>())));

            messages.AsParallel <CloudQueueMessage>()
            .ForAll <CloudQueueMessage>(
                (requestQueueMessage) =>
            {
                Message request = null;

                try
                {
                    BrokerTracing.TraceInfo(string.Format("SOA broker proxy perf1 - {0}", DateTime.UtcNow.TimeOfDay.TotalSeconds));

                    request = this.requestStorageClients.First().GetWcfMessageFromQueueMessage(requestQueueMessage);

                    this.requestMessageQueue.Add(request);

                    // this.requestMessageQueue.Enqueue(request);
                    UniqueId messageId = SoaHelper.GetMessageId(request);

                    BrokerTracing.TraceInfo(SoaHelper.CreateTraceMessage("Proxy", "Request received inqueue", string.Empty, messageId, "Request message in queue"));
                }
                catch (Exception e)
                {
                    BrokerTracing.TraceError(SoaHelper.CreateTraceMessage("Proxy", "ProcessMessages", string.Format("Error occurs {0}", e)));
                }
            });

            this.semaphoreForWorker.Release();
        }
Exemple #10
0
        /// <summary>
        /// Informs that a client is attaching to this broker
        /// </summary>
        public void Attach()
        {
            BrokerTracing.TraceInfo("[BrokerEntry] Client attached.");
            try
            {
                // Bug 8379: If closing is under going, returns broker suspending exception and let broker manager try again latter.
                if (this.closeFlag != 0)
                {
                    ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerSuspending, SR.BrokerSuspending);
                }

                this.stateManager.Attach();
                this.monitor.Attach();

                BrokerTracing.TraceInfo("[BrokerEntry] Client attached successfully.");
            }
            catch (NullReferenceException)
            {
                // Bug 8379: NullReferenceException caught because closing procedure is on going, returns broker suspending exception instead so that broker manager could properly handle
                ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerSuspending, SR.BrokerSuspending);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError("[BrokerEntry] Client attached failed: {0}", e);
                throw;
            }
        }
Exemple #11
0
 /// <summary>
 /// Get the node mapping for the Azure nodes.
 /// </summary>
 /// <param name="state">object used by the callback method.</param>
 private void GetNodeMappingWorker(object state)
 {
     try
     {
         EndpointAddress endpoint = new EndpointAddress(NodeMappingCacheEpr);
         using (ChannelFactory <INodeMappingCache> channelFactory = new ChannelFactory <INodeMappingCache>(BindingHelper.HardCodedNamedPipeBinding, endpoint))
         {
             INodeMappingCache cache = null;
             try
             {
                 cache           = channelFactory.CreateChannel();
                 this.dictionary = cache.EndGetNodeMapping(cache.BeginGetNodeMapping(true, null, null));
             }
             finally
             {
                 if (cache != null)
                 {
                     ((IClientChannel)cache).Close();
                 }
             }
         }
     }
     catch (Exception e)
     {
         BrokerTracing.TraceError("[NodeMappingData] .GetNodeMapping: Failed to get node mapping. {0}", e);
     }
     finally
     {
         // If error occurs, this.dictionary is null. Set following waithandle avoid blocking the waiter.
         this.complete.Set();
     }
 }
Exemple #12
0
        /// <summary>
        /// Create storage blob container.
        /// </summary>
        /// <param name="container">blob container</param>
        public static void CreateContainerWithRetry(CloudBlobContainer container)
        {
            RetryHelper <object> .InvokeOperation(
                () =>
            {
                if (container.CreateIfNotExists())
                {
                    BrokerTracing.TraceInfo("[AzureQueueManager].CreateContainerWithRetry: Create the container {0}", container.Name);
                }

                return(null);
            },
                (e, count) =>
            {
                BrokerTracing.TraceError("Failed to create the container {0}: {1}. Retry Count = {2}", container.Name, e, count);

                StorageException se = e as StorageException;

                if (se != null)
                {
                    string errorCode = BurstUtility.GetStorageErrorCode(se);

                    // According to test, the error code is ResourceAlreadyExists.
                    // There is no doc about this, add ContainerAlreadyExists here.

                    // TODO: Azure storage SDK 2.0
                    if (         // errorCode == StorageErrorCodeStrings.ResourceAlreadyExists ||
                        errorCode == StorageErrorCodeStrings.ContainerAlreadyExists)
                    {
                        Thread.Sleep(TimeSpan.FromMinutes(1));
                    }
                }
            });
        }
Exemple #13
0
        /// <summary>
        /// Create storage queue
        /// </summary>
        /// <param name="queue">storage queue</param>
        /// <remarks>
        /// CreateIfNotExist method throws StorageClientException when queue is
        /// being deleted, so sleep for a while before retry.
        /// </remarks>
        public static void CreateQueueWithRetry(CloudQueue queue)
        {
            RetryHelper <object> .InvokeOperation(
                () =>
            {
                if (queue.CreateIfNotExists())
                {
                    BrokerTracing.TraceInfo("[AzureQueueManager].CreateQueueWithRetry: Create the queue {0}", queue.Name);
                }

                return(null);
            },
                (e, count) =>
            {
                BrokerTracing.TraceError("Failed to create the queue {0}: {1}. Retry Count = {2}", queue.Name, e, count);

                StorageException se = e as StorageException;

                if (se != null)
                {
                    if (BurstUtility.GetStorageErrorCode(se) == QueueErrorCodeStrings.QueueAlreadyExists)
                    {
                        Thread.Sleep(TimeSpan.FromMinutes(1));
                    }
                }
            });
        }
Exemple #14
0
        /// <summary>
        /// Initializes a new instance of the BrokerClientManager class
        /// </summary>
        /// <param name="clientList">indicating the client info list</param>
        /// <param name="queueFactory">indicating the queue factory</param>
        /// <param name="observer">indicating the observer</param>
        /// <param name="stateManager">indicating the state manager</param>
        /// <param name="monitor">indicating the monitor</param>
        /// <param name="sharedData">indicating the shared data</param>
        public BrokerClientManager(ClientInfo[] clientList, BrokerQueueFactory queueFactory, BrokerObserver observer, BrokerStateManager stateManager, ServiceJobMonitorBase monitor, SharedData sharedData)
        {
            this.clientDic    = new Dictionary <string, BrokerClient>(StringComparer.OrdinalIgnoreCase);
            this.queueFactory = queueFactory;
            this.observer     = observer;
            this.stateManager = stateManager;
            this.monitor      = monitor;
            this.sharedData   = sharedData;

            foreach (ClientInfo client in clientList)
            {
                try
                {
                    // Bug 5193: Only raise client that has requests to process.
                    if (client.TotalRequestsCount != client.ProcessedRequestsCount)
                    {
                        this.AddNewClient(client.ClientId, client.UserName);
                    }
                }
                catch (Exception e)
                {
                    // Create client may fail because of broker queue failure, ignore the client in this situation and trys other client instead.
                    BrokerTracing.TraceError("[BrokerClientManager] Failed to create client {0}, Exception = {1}", client.ClientId, e);
                }
            }

            this.CheckIfAllRequestDone();
            this.CheckIfEOMCalled();
        }
        public static async Task RestoreRequest(
            CloudQueue requestQueue,
            CloudQueue pendingQueue,
            CloudTable responseTable,
            CloudBlobContainer container)
        {
            try
            {
                while (true)
                {
                    var message = await pendingQueue.PeekMessageAsync();

                    if (message == null)
                    {
                        break;
                    }

                    var messageId =
                        ((BrokerQueueItem)formatter.Deserialize(await GetMsgBody(container, message.AsBytes))).Message
                        .Headers.MessageId.ToString();
                    BrokerTracing.TraceVerbose(
                        "[AzureStorageTool] .CheckRequestQueue: queueName = {0}, cloudMessageId = {1}, messageId = {2}",
                        pendingQueue.Name,
                        message.Id,
                        messageId);
                    var query = new TableQuery <TableEntity>().Where("MessageId eq '" + messageId + "'");
                    var list  = responseTable.ExecuteQuery(query).ToList();
                    if (list.Count > 0)
                    {
                        await pendingQueue.DeleteMessageAsync(await pendingQueue.GetMessageAsync());
                    }
                    else
                    {
                        // Add msg to request queue & delete it from pending queue.
                        message = await pendingQueue.GetMessageAsync();

                        await requestQueue.AddMessageAsync(new CloudQueueMessage(message.AsBytes));

                        await pendingQueue.DeleteMessageAsync(message);

                        BrokerTracing.TraceVerbose(
                            "[AzureStorageTool] .CheckRequestQueue: messageId = {0} is restored into request queue.",
                            messageId);
                    }
                }
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError(
                    "[AzureStorageTool] .CheckRequestQueue: queueName={0}, responseTable={1}, the exception, {2}",
                    pendingQueue.Name,
                    responseTable.Name,
                    e);
                throw;
            }

            await requestQueue.FetchAttributesAsync();
        }
        /// <summary>
        /// Gets the instance of scheduler adapter client
        /// </summary>
        /// <returns>returns the instance of the scheduler adapter client</returns>
        public async Task <ISchedulerAdapter> GetSchedulerAdapterClientAsync()
        {
            // this.CheckClient();
            bool newClientCreated       = false;
            ICommunicationObject client = this.schedulerAdapterClient as ICommunicationObject;

            if (this.schedulerAdapterClient == null || client == null || client.State == CommunicationState.Faulted)
            {
                await this.createClientSS.WaitAsync();

                try
                {
                    if (this.schedulerAdapterClient == null)
                    {
                        await this.CreateClient();

                        if (!SoaCommonConfig.WithoutSessionLayer)
                        {
                            newClientCreated = true;
                        }
                    }
                    else
                    {
                        client = this.schedulerAdapterClient as ICommunicationObject;
                        if (client == null || client.State == CommunicationState.Faulted)
                        {
                            try
                            {
                                Utility.AsyncCloseICommunicationObject(client);
                                await this.CreateClient();

                                if (!SoaCommonConfig.WithoutSessionLayer)
                                {
                                    newClientCreated = true;
                                }
                            }
                            catch (Exception e)
                            {
                                // Swallow exception when creating client
                                BrokerTracing.TraceError("[SchedulerAdapterClientFactory] Exception thrown when creating client: {0}", e);
                            }
                        }
                    }
                }
                finally
                {
                    this.createClientSS.Release();
                }

                if (newClientCreated)
                {
                    await this.monitor.RegisterJob();
                }
            }

            return(this.schedulerAdapterClient);
        }
Exemple #17
0
 /// <summary>
 /// Callback method of the message retriever.
 /// </summary>
 /// <param name="messages">a collection of messages</param>
 private void HandleMessages(IEnumerable <CloudQueueMessage> messages)
 {
     try
     {
         this.requestCache.Enqueue(messages);
         this.semaphoreForRequest.Release();
     }
     catch (Exception e)
     {
         BrokerTracing.TraceError(SoaHelper.CreateTraceMessage("Proxy", "HandleMessages", string.Format("Error occurs, {0}", e)));
     }
 }
 /// <summary>
 /// Callback method of the timer.
 /// </summary>
 /// <param name="state">state object</param>
 private void TimerCallback(object state)
 {
     try
     {
         this.Cleanup().GetAwaiter().GetResult();
     }
     catch (Exception e)
     {
         BrokerTracing.TraceError(
             "[AzureStorageCleaner].TimerCallback: Cleanup failed, {0}",
             e);
     }
 }
Exemple #19
0
        /// <summary>
        /// EndOfMessage arrives
        /// </summary>
        /// <param name="msgCount">indicating the msg count</param>
        /// <param name="timeout">indicating the timeout</param>
        public void EndOfMessage(long msgCount, int batchId, int timeout)
        {
            lock (this.lockState)
            {
                if (this.state != BrokerClientState.ClientConnected)
                {
                    BrokerTracing.EtwTrace.LogBrokerClientRejectEOM(this.sharedData.BrokerInfo.SessionId, this.clientId, this.state.ToString());
                    switch (this.state)
                    {
                    case BrokerClientState.GetResponse:
                        ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_EOMReject_GetResponse, SR.EOMReject_GetResponse);
                        break;

                    case BrokerClientState.EndRequests:
                        ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_EOMReject_EndRequests, SR.EOMReject_EndRequests);
                        break;

                    default:
                        ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_EOMRejected, SR.EOMRejected, this.state.ToString());
                        break;
                    }
                }

                // Stop the timer
                this.timeoutManager.Stop();

                try
                {
                    this.Flush(msgCount, batchId, timeout, true);
                }
                catch (Exception e)
                {
                    BrokerTracing.TraceError("[BrokerClient] Failed to flush messages: {0}", e);

                    // If EndRequests throws exception from broker queue, the
                    // timer is closed and never reactivated without user action.
                    // Thus, the broker client would leak forever and the broker
                    // process would run away if user does not purge the client
                    // or close the session later.
                    this.timeoutManager.RegisterTimeout(this.sharedData.Config.Monitor.ClientIdleTimeout, this.TimeoutToDisconnected, this.state);
                    throw;
                }

                // State will change if flush succeeded
                // If flush failed, the state won't change
                BrokerTracing.TraceInfo("[BrokerClient] Client {0}: State: ClientConnected ==> EndOfMessage", this.clientId);
                this.state = BrokerClientState.EndRequests;
                this.endOfMessageCalled = true;
            }
        }
Exemple #20
0
        /// <summary>
        /// Handle fatal broker queue exception
        /// </summary>
        /// <param name="sender">indicating the sender</param>
        /// <param name="fatalExceptionEventArgs">indicating the exception</param>
        private void Queue_OnFatalExceptionEvent(object sender, ExceptionEventArgs fatalExceptionEventArgs)
        {
            BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Critical, 0, "Fatal exception encountered. Exception = {0}", fatalExceptionEventArgs.Exception);
            BrokerQueueException bqException = fatalExceptionEventArgs.Exception as BrokerQueueException;

            if (bqException != null && bqException.ErrorCode == (int)BrokerQueueErrorCode.E_BQ_PERSIST_STORAGE_INSUFFICIENT)
            {
                this.monitor.FailServiceJob("Insufficient broker queue storage").GetAwaiter().GetResult();
            }
            else
            {
                BrokerTracing.TraceError("Unknown exception: {0}", fatalExceptionEventArgs);
            }
        }
        public static async Task <CloudQueue> CreateQueueAsync(
            string connectString,
            string sessionId,
            string queueName,
            string clientId,
            bool isRequest,
            string note)
        {
            var info = new QueueInfo(sessionId, queueName, clientId, isRequest, note);

            try
            {
                var table = GetTableClient(connectString).GetTableReference(queueTableName);
                await table.CreateIfNotExistsAsync();

                var insertOperation = TableOperation.Insert(info);
                await table.ExecuteAsync(insertOperation);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError(
                    "[AzureStorageTool] .CreateQueueAsync: queueName={0} create info to table failed, the exception, {1}",
                    queueName,
                    e);
                throw;
            }

            try
            {
                var queue = GetQueueClient(connectString).GetQueueReference(queueName);
                if (await queue.CreateIfNotExistsAsync())
                {
                    return(queue);
                }

                BrokerTracing.TraceWarning(
                    "[AzureStorageTool] .CreateQueueAsync: queueName={0} has existed.",
                    queueName);
                throw new Exception("Queue with the queueName has existed.");
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError(
                    "[AzureStorageTool] .CreateQueueAsync: queueName={0} create queue failed, the exception, {1}",
                    queueName,
                    e);
                throw;
            }
        }
        /// <summary>
        /// Callback of the CloudQueue.BeginAddMessage method.
        /// </summary>
        /// <param name="ar">async result</param>
        /// <remarks>
        /// Notice: This method doesn't throw exception. It invokes callback
        /// and pass exception to it in case exception occurs.
        /// </remarks>
        private void BeginAddMessageCallback(IAsyncResult ar)
        {
            BrokerTracing.TraceVerbose("[AzureServiceClient].BeginAddMessageCallback: Enter callback method of BeginAddMessage.");

            var reliableState = ar.AsyncState as ReliableQueueClient.ReliableState;

            QueueAsyncResult asyncResult = reliableState.State as QueueAsyncResult;

            Debug.Assert(asyncResult != null, "reliableState.State must be a QueueAsyncResult.");

            try
            {
                BrokerTracing.TraceVerbose(
                    "[AzureServiceClient].BeginAddMessageCallback: Try to complete adding message {0}",
                    asyncResult.MessageId);

                asyncResult.StorageClient.EndAddMessage(ar);
            }
            catch (StorageException e)
            {
                BrokerTracing.TraceError(
                    "[AzureServiceClient].BeginAddMessageCallback: Failed to complete adding message {0}, {1}",
                    asyncResult.MessageId,
                    e.ToString());

                if (BurstUtility.IsQueueNotFound(e))
                {
                    // StorageException happens here when want to add request
                    // messages, so it must be request queue not found. Handle
                    // the outstanding messages, which are already sent to
                    // request queue, but maybe not got by proxy. And should
                    // consider the multi request queue case when there are
                    // multi azure deployments.
                    this.manager.HandleInvalidRequestQueue(new RequestStorageException(e), this.requestStorageClient.QueueName);
                }

                this.manager.CompleteCallback(asyncResult, null, new RequestStorageException(e));
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError(
                    "[AzureServiceClient].BeginAddMessageCallback: Failed to complete adding message {0}, {1}",
                    asyncResult.MessageId,
                    e.ToString());

                this.manager.CompleteCallback(asyncResult, null, e);
            }
        }
Exemple #23
0
        /// <summary>
        /// Handle client failure
        /// </summary>
        /// <param name="client">targeted client</param>
        private static void HandleClientFailure(AzureServiceClient client)
        {
            try
            {
                BrokerTracing.TraceWarning(
                    "[AzureDispatcher] HandleClientFailure: Handle invalid client, {0}, {1}",
                    client,
                    client.ServiceClient.Endpoint.Address);

                Dictionary <EndpointAddress, ProxyClientPool> .ValueCollection pools;

                lock (LockProxyClientPoolDic)
                {
                    pools = ProxyClientPoolDic.Values;
                }

                foreach (var pool in pools)
                {
                    bool existInPool = false;

                    lock (pool)
                    {
                        BrokerTracing.TraceVerbose(
                            "[AzureDispatcher] HandleClientFailure: Remove client {0} from pool.", client);

                        existInPool = pool.RemoveProxyClient(client);
                    }

                    if (existInPool)
                    {
                        BrokerTracing.TraceVerbose(
                            "[AzureDispatcher] HandleClientFailure: Close client {0}", client);

                        // Close the proxy client if any exception is encountered.
                        // As a result, async pending callback on clients will be
                        // invoked (with exception).
                        client.AsyncClose();

                        return;
                    }
                }
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError(
                    "[AzureDispatcher] HandleClientFailure: Error occurs, {0}", e);
            }
        }
        /// <summary>
        /// Refresh the client.
        /// For on-premise cluster, just create a new client.
        /// </summary>
        /// <param name="clientIndex">client index</param>
        /// <param name="exceptionIndirect">
        ///     it is false for the on-premise cluster
        /// </param>
        /// <param name="messageId">message Id</param>
        /// <returns>should increase the retry count or not</returns>
        public override async Task <bool> RefreshClientAsync(int clientIndex, bool exceptionIndirect, Guid messageId)
        {
            BrokerTracing.TraceError(
                BrokerTracing.GenerateTraceString(
                    "OnPremiseRequestSender",
                    "RefreshClientAsync",
                    this.TaskId,
                    clientIndex,
                    this.Client.ToString(),
                    messageId,
                    string.Format("exceptionIndirect = {0}", exceptionIndirect)));

            await this.CreateClientAsync(false, clientIndex).ConfigureAwait(false);

            return(true);
        }
Exemple #25
0
        /// <summary>
        /// the putting request complete thread proc
        /// </summary>
        /// <param name="state">the thread pool callback state</param>
        private static void PutRequestComplete(PutRequestCallback callback, object state)
        {
            if (callback == null)
            {
                return;
            }

            try
            {
                callback(null, state);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError("[MemoryPersist] .PutRequestComplete: callback failed, Exception:{0}.", e.ToString());
            }
        }
Exemple #26
0
        /// <summary>
        /// Trace error level log.
        /// </summary>
        /// <param name="className">class name</param>
        /// <param name="methodName">method name</param>
        /// <param name="format">message format</param>
        /// <param name="args">arguments of message format</param>
        public static void TraceError(string className, string methodName, string format, params object[] args)
        {
            string traceMessage = SoaHelper.CreateTraceMessage(className, methodName, format, args);

#if PROXY
            Microsoft.Hpc.BrokerProxy.AzureBrokerProxyTrace.TraceError(traceMessage);
#elif DATAPROXY
            Microsoft.Hpc.Scheduler.Session.Data.Internal.DataProxyTrace.TraceError(traceMessage);
#elif DATASVC
            Microsoft.Hpc.Scheduler.Session.Data.Internal.DataServiceTraceHelper.TraceEvent(TraceEventType.Error, traceMessage);
#elif CONSOLE
            Console.Error.WriteLine(string.Format("{0} - {1}", DateTime.Now, traceMessage));
#else
            BrokerTracing.TraceError(traceMessage);
#endif
        }
Exemple #27
0
        /// <summary>
        /// the putting response complete thread proc
        /// </summary>
        /// <param name="state">the thread pool callback state</param>
        private static void PutResponseComplete(int responseCount, int faultResponseCount, bool isLastResponse, PutResponseCallback putResponseCallback, object callbackState)
        {
            if (putResponseCallback == null)
            {
                return;
            }

            try
            {
                putResponseCallback(null, responseCount, faultResponseCount, isLastResponse, null, callbackState);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError("[MemoryPersist] .PutResponseComplete: callback failed, Exception:{0}.", e.ToString());
            }
        }
        /// <summary>
        /// Async method of ProcessMessage.
        /// </summary>
        /// <param name="request">request message</param>
        /// <param name="callback">callback method</param>
        /// <param name="asyncState">async state</param>
        /// <returns>async result</returns>
        public IAsyncResult BeginProcessMessage(Message request, AsyncCallback callback, object asyncState)
        {
            MessageBuffer buffer = request.CreateBufferedCopy(int.MaxValue);

            byte[] messageData = AzureQueueItem.Serialize(buffer.CreateMessage());

            QueueAsyncResult asyncResult = new QueueAsyncResult(callback, asyncState);

            UniqueId messageId = request.Headers.MessageId;

            asyncResult.MessageId = messageId;

            asyncResult.StorageClient = this.requestStorageClient;

            try
            {
                BrokerTracing.TraceVerbose(
                    "[AzureServiceClient].BeginProcessMessage: Try to add message {0} to the request queue.",
                    messageId);

                var reliableState = new ReliableQueueClient.ReliableState(asyncResult, messageId);

                // Notice: It can happen that response message is back before
                // EndAddMessage is called on the request message. So
                // add/update the callback info to AzureQueueManager before
                // calling BeginAddMessage avoid the issue that response comes
                // back but can't find callback info.
                this.manager.AddQueueAsyncResult(asyncResult, this.requestStorageClient.QueueName, this.responseStorageName);

                this.requestStorageClient.BeginAddMessage(messageData, messageId, this.BeginAddMessageCallback, reliableState);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError(
                    "[AzureServiceClient].BeginProcessMessage: Failed to add message {0}, {1}",
                    messageId,
                    e);

                this.manager.CompleteCallback(asyncResult, null, e);
            }
            finally
            {
                buffer.Close();
            }

            return(asyncResult);
        }
Exemple #29
0
        /// <summary>
        /// Service instance is failed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ServiceInstanceFailed(object sender, ServiceInstanceFailedEventArgs e)
        {
            Dispatcher     dispatcher     = sender as Dispatcher;
            DispatcherInfo dispatcherInfo = dispatcher.Info;

            // Filter out duplicate failures
            lock (this.lockFailedDispatcherList)
            {
                if (this.failedDispatcherList.Contains(dispatcher.TaskId))
                {
                    return;
                }

                this.failedDispatcherList.Add(dispatcher.TaskId);
            }

            BrokerTracing.TraceError("[DispatcherManager] Service instance failed! Task id = {0}, node name = {1}", dispatcherInfo.UniqueId, dispatcherInfo.MachineName);

            // If the service is unavailable, just block the dispatcher. We cannot blacklist it because it may have just been preempted and the node is still good.
            // Furthermore the network may be temporarily out but the CN and its app install is fine
            if (e.Fault.Code == (int)SOAFaultCode.Service_Unreachable)
            {
                this.BlockDispatcher(dispatcherInfo);
            }

            // If the service cannot be initialized, remove and blacklist the dispatcher. We know the service cannot be loaded
            else if (e.Fault.Code == (int)SOAFaultCode.Service_InitializeFailed)
            {
                if (this.RemoveDispatcher(dispatcherInfo.UniqueId, /*exitServiceHost =*/ false, false))
                {
                    // Should use the machine virtual name for scheduler API to exclude a node.
                    this.monitor.BlacklistNode(SoaHelper.IsOnAzure() ? dispatcherInfo.MachineVirtualName : dispatcherInfo.MachineName).GetAwaiter().GetResult();
                }
            }

            // If the service host is preempted, remove the dispatcher.
            else if (e.Fault.Code == SOAFaultCode.Service_Preempted)
            {
                this.RemoveDispatcher(dispatcherInfo.UniqueId, true, true);
            }

            // There should be no other possible failure codes
            else
            {
                Debug.Assert(false, String.Format("Invalid fault code sent to ServiceInstanceFailed - {0}", e.Fault.Code));
            }
        }
        public static async Task <CloudTable> CreateTableAsync(
            string connectString,
            string sessionId,
            string tableName,
            string clientId,
            bool isRequest,
            string note)
        {
            var info = new QueueInfo(sessionId, tableName, clientId, isRequest, note);

            try
            {
                var table = GetTableClient(connectString).GetTableReference(queueTableName);
                await table.CreateIfNotExistsAsync();

                var insertOperation = TableOperation.Insert(info);
                await table.ExecuteAsync(insertOperation);
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError(
                    "[AzureStorageTool] .CreateTableAsync: Table={0} insert info in storage table failed, the exception, {1}",
                    tableName,
                    e);
                throw;
            }

            try
            {
                var responseTable = GetTableClient(connectString).GetTableReference(tableName);
                if (await responseTable.CreateIfNotExistsAsync())
                {
                    return(responseTable);
                }

                throw new Exception("Table with the tableName has existed.");
            }
            catch (Exception e)
            {
                BrokerTracing.TraceError(
                    "[AzureStorageTool] .CreateTableAsync: Table={0} create error, the exception, {1}",
                    tableName,
                    e);
                throw;
            }
        }