/// <summary> /// Send Proposal to Hub Client /// </summary> /// <param name="jobItem"></param> internal void SendProposalTo(IJob jobItem) { var setupDuration = GetSetupTime(jobItem: jobItem); var queuePosition = _planingQueue.GetQueueAbleTime(job: jobItem , currentTime: Agent.CurrentTime , resourceIsBlockedUntil: _jobInProgress.ResourceIsBusyUntil , processingQueueLength: _processingQueue.SumDurations , setupDuration: setupDuration); if (queuePosition.IsQueueAble) { Agent.DebugMessage(msg: $"IsQueueable: {queuePosition.IsQueueAble} with EstimatedStart: {queuePosition.EstimatedStart}"); } var fPostponed = new FPostponed(offset: queuePosition.IsQueueAble ? 0 : _planingQueue.Limit); if (fPostponed.IsPostponed) { Agent.DebugMessage(msg: $"Postponed: { fPostponed.IsPostponed } with Offset: { fPostponed.Offset} "); } // calculate proposal var proposal = new FProposal(possibleSchedule: queuePosition.EstimatedStart , postponed: fPostponed , resourceAgent: Agent.Context.Self , jobKey: jobItem.Key); Agent.Send(instruction: Hub.Instruction.ProposalFromResource.Create(message: proposal, target: Agent.Context.Sender)); }
public void Add(FProposal proposal) { if (_proposals.Any(x => x.ResourceAgent == proposal.ResourceAgent)) { throw new Exception("proposal for resourceAgent already exits"); } // check if proposal for same resource already exits --> override ?? _proposals.Add(proposal); }
/// <summary> /// /// </summary> /// <param name="proposal"></param> private void ProposalFromResource(FProposal fProposal) { // get related operation and add proposal. var fOperation = _operationList.Single(predicate: x => x.Key == fProposal.JobKey); fOperation.Proposals.RemoveAll(x => x.ResourceAgent.Equals(fProposal.ResourceAgent)); // add New Proposal fOperation.Proposals.Add(item: fProposal); Agent.DebugMessage(msg: $"Proposal for {fOperation.Operation.Name} with Schedule: {fProposal.PossibleSchedule} Id: {fProposal.JobKey} from: {fProposal.ResourceAgent}!"); // if all Machines Answered if (fOperation.Proposals.Count == _resourceManager.GetResourceByTool(fOperation.Operation.ResourceTool).Count) { // item Postponed by All Machines ? -> requeue after given amount of time. if (fOperation.Proposals.TrueForAll(match: x => x.Postponed.IsPostponed)) { var postPonedFor = fOperation.Proposals.Min(x => x.Postponed.Offset); Agent.DebugMessage(msg: $"{fOperation.Operation.Name} {fOperation.Key} postponed to {postPonedFor}"); // Call Hub Agent to Requeue fOperation = fOperation.UpdateResourceAgent(r: ActorRefs.NoSender); _operationList.Replace(val: fOperation); Agent.Send(instruction: Hub.Instruction.EnqueueJob.Create(message: fOperation, target: Agent.Context.Self), waitFor: postPonedFor); return; } // acknowledge Machine -> therefore get Machine -> send acknowledgement var earliestPossibleStart = fOperation.Proposals.Where(predicate: y => y.Postponed.IsPostponed == false) .Min(selector: p => p.PossibleSchedule); var acknowledgement = fOperation.Proposals.First(predicate: x => x.PossibleSchedule == earliestPossibleStart && x.Postponed.IsPostponed == false); fOperation = ((IJob)fOperation).UpdateEstimations(acknowledgement.PossibleSchedule, acknowledgement.ResourceAgent) as FOperation; Agent.DebugMessage(msg: $"Start AcknowledgeProposal for {fOperation.Operation.Name} {fOperation.Key} on resource {acknowledgement.ResourceAgent}"); // set Proposal Start for Machine to Requeue if time slot is closed. _operationList.Replace(fOperation); Agent.Send(instruction: Resource.Instruction.AcknowledgeProposal.Create(message: fOperation, target: acknowledgement.ResourceAgent)); } }
public ProposalForCapabilityProviderSet AddProposal(FProposal fProposal, IActorRef sender) { if (!_proposalDictionary.TryGetValue(fProposal.JobKey, out var proposalForSetupDefinitionSet)) { return(null); } foreach (var proposalForCapabilityProvider in proposalForSetupDefinitionSet) { foreach (var resource in proposalForCapabilityProvider.GetAllResources()) { if (resource.Equals(sender)) { proposalForCapabilityProvider.Add(fProposal); } } } return(proposalForSetupDefinitionSet); }
internal void ProposalFromResource(FProposal fProposal) { // get related operation and add proposal. var jobConfirmation = _bucketManager.GetConfirmationByBucketKey(fProposal.JobKey); if (jobConfirmation == null) { return; } var bucket = jobConfirmation.Job as FBucket; var resourceAgent = fProposal.ResourceAgent as IActorRef; var required = _proposalManager.AddProposal(fProposal, Agent.Sender); var schedules = fProposal.PossibleSchedule as List <FQueueingScope>; var propSet = _proposalManager.GetProposalForSetupDefinitionSet(fProposal.JobKey); Agent.DebugMessage(msg: $"Proposal({propSet.ReceivedProposals} of {propSet.RequiredProposals}) " + $"for {bucket.Name} {bucket.Key} with Schedule: {schedules.First().Scope.Start} " + $"JobKey: {fProposal.JobKey} from: {resourceAgent.Path.Name}!", CustomLogger.PROPOSAL, LogLevel.Warn); // if all resources replied if (propSet.AllProposalsReceived) { // item Postponed by All resources ? -> requeue after given amount of time. var proposalForCapabilityProvider = propSet.GetValidProposal(); if (proposalForCapabilityProvider.Count == 0) { var postponedFor = propSet.PostponedFor; _proposalManager.RemoveAllProposalsFor(bucket.Key); Agent.Send(instruction: Hub.Instruction.BucketScope.EnqueueBucket.Create(bucket.Key, target: Agent.Context.Self), waitFor: postponedFor); Agent.DebugMessage($"{bucket.Name} {bucket.Key} has been postponed for {postponedFor}", CustomLogger.PROPOSAL, LogLevel.Warn); return; } List <PossibleProcessingPosition> possibleProcessingPositions = _proposalManager.CreatePossibleProcessingPositions(proposalForCapabilityProvider, bucket); if (possibleProcessingPositions.Count == 0) { _proposalManager.RemoveAllProposalsFor(bucket.Key); //TODO check wether this can be adjustable var postponedFor = (long)(bucket.MaxBucketSize * 0.5); Agent.Send(instruction: Hub.Instruction.BucketScope.EnqueueBucket.Create(bucket.Key, target: Agent.Context.Self), waitFor: postponedFor); return; } var possiblePosition = possibleProcessingPositions.OrderBy(x => x._processingPosition).First(); jobConfirmation.CapabilityProvider = possiblePosition.ResourceCapabilityProvider; var jobResourceConfirmation = new FJobResourceConfirmation(jobConfirmation.ToImmutable(), new Dictionary <IActorRef, FScopeConfirmation>()); var setups = jobConfirmation.CapabilityProvider.ResourceSetups.Where(x => x.Resource.IsPhysical).ToList(); foreach (var setup in setups) { var resourceRef = setup.Resource.IResourceRef as IActorRef; var(actorRef, pos) = possiblePosition._queuingDictionary.FirstOrDefault(x => x.Key.Equals(setup.Resource.IResourceRef)); if (pos == null) { continue; } jobResourceConfirmation.ScopeConfirmations.Add(resourceRef, pos); } Agent.Send(Job.Instruction.AcknowledgeJob.Create(jobResourceConfirmation, jobConfirmation.JobAgentRef)); Agent.DebugMessage($"Send Acknwoledge Job for {jobResourceConfirmation.JobConfirmation.Job.Name}" , CustomLogger.PROPOSAL, LogLevel.Warn); _proposalManager.Remove(bucket.Key); } }
public static ProposalFromResource Create(FProposal message, IActorRef target) { return(new ProposalFromResource(message: message, target: target)); }