private void ProcessRequests(object notUsed) { try { // process rules and run handlers as required BasicServerState state = this.GetState(); if (state != BasicServerState.Running) { return; } // subscription is ready and callback flood has stopped List <InternalRequest> existingRequests = new List <InternalRequest>(); List <InternalRequest> enqueuedRequests = new List <InternalRequest>(); List <InternalRequest> cancelledRequests = new List <InternalRequest>(); var requestItems = _AssignedRequestsCache.Items; var cancellationItems = _CancellationsCache.Items; var responseItems = _WorkerResponseCache.Items; _InternalRequests.Locked((internalRequests) => { // - process responses foreach (ICoreItem item in responseItems) { try { WorkerResponse response = (WorkerResponse)item.Data; Guid requestId = Guid.Parse(response.RequestId); InternalRequest internalRequest; if (!internalRequests.TryGetValue(requestId, out internalRequest)) { internalRequest = new InternalRequest(requestId); } internalRequest.Status = response.Status; internalRequests[requestId] = internalRequest; } catch (Exception excp) { Logger.Log(excp); } } // - process requests foreach (ICoreItem item in requestItems) { try { AssignedWorkflowRequest request = (AssignedWorkflowRequest)item.Data; Guid requestId = Guid.Parse(request.RequestId); InternalRequest internalRequest; if (!internalRequests.TryGetValue(requestId, out internalRequest)) { internalRequest = new InternalRequest(requestId); } internalRequest.ExternalRequest = request; internalRequests[requestId] = internalRequest; } catch (Exception excp) { Logger.Log(excp); } } // - process cancellations foreach (ICoreItem item in cancellationItems) { try { CancellationRequest cancellation = (CancellationRequest)item.Data; Guid requestId = Guid.Parse(cancellation.RequestId); InternalRequest internalRequest; if (!internalRequests.TryGetValue(requestId, out internalRequest)) { internalRequest = new InternalRequest(requestId); } internalRequest.Cancellation = cancellation; internalRequests[requestId] = internalRequest; } catch (Exception excp) { Logger.Log(excp); } } // determine requests to be launched or cancelled foreach (InternalRequest internalRequest in internalRequests.Values) { if ((internalRequest.ExternalRequest != null) && ((internalRequest.Status == RequestStatusEnum.Undefined) || (internalRequest.Status == RequestStatusEnum.Enqueued))) { // find requests to launch if (internalRequest.Cancellation == null) { if (internalRequest.Status != RequestStatusEnum.Enqueued) { // new request internalRequest.Status = RequestStatusEnum.Enqueued; enqueuedRequests.Add(internalRequest); } existingRequests.Add(internalRequest); } else { // cancelled internalRequest.Status = RequestStatusEnum.Cancelled; cancelledRequests.Add(internalRequest); } } } }); // publish status for cancelled and enqueued requests foreach (InternalRequest request in cancelledRequests) { PublishWorkerResponse(_IntClient.Target, request, HostInstance); } // now find handlers to launch foreach (InternalRequest request in enqueuedRequests) { // publish enqueued status PublishWorkerResponse(_IntClient.Target, request, HostInstance); } foreach (InternalRequest request in existingRequests) { // launch if handler available int count = Interlocked.Decrement(ref _HandlersAvailable); if (count >= 0) { Interlocked.Increment(ref _AvailabilityChangeCount); Interlocked.Increment(ref _HandlersExecuting); // publish launched status request.Status = RequestStatusEnum.Launched; PublishWorkerResponse(_IntClient.Target, request, HostInstance); // launch ThreadPool.QueueUserWorkItem(Launch, new LaunchPackage(_IntClient, request)); } else { Interlocked.Increment(ref _HandlersAvailable); } } // publish availability (throttled) int changeCount = Interlocked.Exchange(ref _AvailabilityChangeCount, 0); if ((changeCount > 0) || ((DateTimeOffset.Now - _AvailabilityLastPublished) > TimeSpan.FromSeconds(5))) { _IntClient.Target.SaveObject <WorkerAvailability>(new WorkerAvailability() { WorkerHostComputer = Environment.MachineName, WorkerHostInstance = this.HostInstance, AvailableNodeCount = Interlocked.Add(ref _HandlersAvailable, 0) }); _AvailabilityLastPublished = DateTimeOffset.Now; } } catch (Exception e) { Logger.Log(e); } }
private void ProcessRequests(object notUsed) { try { BasicServerState state = this.GetState(); if (state != BasicServerState.Running) { return; } List <InternalRequest> existingRequests = new List <InternalRequest>(); List <InternalRequest> receivedRequests = new List <InternalRequest>(); List <InternalRequest> cancelledRequests = new List <InternalRequest>(); //Dictionary<string, InternalAvailability> availableWorkers = new Dictionary<string, InternalAvailability>(); _State.Locked((managerState) => { // - process responses foreach (ICoreItem item in _ManagerResponseCache.Items) { try { ManagerResponse response = (ManagerResponse)item.Data; Guid requestId = Guid.Parse(response.RequestId); InternalRequest internalRequest; if (!managerState.InternalRequests.TryGetValue(requestId, out internalRequest)) { internalRequest = new InternalRequest(requestId); } internalRequest.Status = response.Status; managerState.InternalRequests[requestId] = internalRequest; } catch (Exception excp) { Logger.Log(excp); } } // - process requests foreach (ICoreItem item in _UnassignedRequestsCache.Items) { try { UnassignedWorkflowRequest request = (UnassignedWorkflowRequest)item.Data; Guid requestId = Guid.Parse(request.RequestId); InternalRequest internalRequest; if (!managerState.InternalRequests.TryGetValue(requestId, out internalRequest)) { internalRequest = new InternalRequest(requestId); } internalRequest.ExternalRequest = request; managerState.InternalRequests[requestId] = internalRequest; } catch (Exception excp) { Logger.Log(excp); } } // - process cancellations foreach (ICoreItem item in _CancellationsCache.Items) { try { CancellationRequest cancellation = (CancellationRequest)item.Data; Guid requestId = Guid.Parse(cancellation.RequestId); InternalRequest internalRequest; if (!managerState.InternalRequests.TryGetValue(requestId, out internalRequest)) { internalRequest = new InternalRequest(requestId); } internalRequest.Cancellation = cancellation; managerState.InternalRequests[requestId] = internalRequest; } catch (Exception excp) { Logger.Log(excp); } } // determine requests to be launched or cancelled foreach (InternalRequest internalRequest in managerState.InternalRequests.Values) { if ((internalRequest.ExternalRequest != null) && ((internalRequest.Status == RequestStatusEnum.Undefined) || (internalRequest.Status == RequestStatusEnum.Received))) { // find requests to launch if (internalRequest.Cancellation == null) { if (internalRequest.Status != RequestStatusEnum.Received) { // new request internalRequest.Status = RequestStatusEnum.Received; receivedRequests.Add(internalRequest); } existingRequests.Add(internalRequest); } else { // cancelled internalRequest.Status = RequestStatusEnum.Cancelled; cancelledRequests.Add(internalRequest); } } } }); // publish cancelled requests foreach (InternalRequest request in cancelledRequests) { PublishManagerResponse(_IntClient.Target, request); } // publish received status foreach (InternalRequest request in receivedRequests) { PublishManagerResponse(_IntClient.Target, request); } // find available workers for received requests //Logger.LogDebug("Assigning {0} requests ...", existingRequests.Count); foreach (InternalRequest request in existingRequests) { //Logger.LogDebug("----- Request: {0}", request.RequestId); WorkerAvailability chosenWorker = null; int highestAvailability = 0; foreach (var item in _WorkerAvailabilityCache.Items) { WorkerAvailability worker = (WorkerAvailability)item.Data; //Logger.LogDebug("----- Worker: {0} ({1})", worker.PrivateKey, worker.AvailableNodeCount); if (worker.AvailableNodeCount > highestAvailability) { highestAvailability = worker.AvailableNodeCount; chosenWorker = worker; } } // exit if no workers available if (chosenWorker == null) { break; } Logger.LogDebug("Assigned request '{0}' to {1} ({2})", request.RequestId, chosenWorker.PrivateKey, chosenWorker.AvailableNodeCount); chosenWorker.AvailableNodeCount = chosenWorker.AvailableNodeCount - 1; // publish assigned status request.Status = RequestStatusEnum.Assigned; PublishManagerResponse(_IntClient.Target, request); // reassign to worker RequestBase.TransferToWorker(_IntClient.Target, request.ExternalRequest, chosenWorker.WorkerHostComputer, chosenWorker.WorkerHostInstance); } //Logger.LogDebug("Assigned."); } catch (Exception e) { Logger.Log(e); } }