/// <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));
        }
Example #2
0
 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));
            }
        }
Example #4
0
        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);
        }
Example #5
0
        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);
            }
        }
Example #6
0
 public static ProposalFromResource Create(FProposal message, IActorRef target)
 {
     return(new ProposalFromResource(message: message, target: target));
 }