Ejemplo n.º 1
0
 /// <summary>
 /// set event new schedule created
 /// </summary>
 /// <param name="e"></param>
 private void OnNewScheduleCreated(SchedulingInformationEventArgs e)
 {
     if (NewScheduleCreatedEvent != null)
     {
         NewScheduleCreatedEvent(this, e);
     }
 }
Ejemplo n.º 2
0
        //==================================
        #endregion

        #region Scheduling algorithms
        //==================================
        /// <summary>
        /// The main method of creating scheduler
        /// </summary>
        private void Schedule(bool reschedule = false)
        {
            lock (_unscheduledRequests)
            {
                lock (_scheduledRequests)
                {
                    // Set need reschedule to false in order to avoid more schedule from other threads
                    _needReschedule = false;

                    #region Manage history and find services to schedule
                    // ------------------------------------

                    // Move pending uninitialized services to the unscheduled list so they can be rescheduled
                    foreach (SchedulingRequest request in _scheduledRequests.RemoveNotActivated())
                    {
                        if (request.RequestedTime + request.Rule.MaxDeviationAfter > DateTime.Now)
                        {
                            _unscheduledRequests.Add(request);
                        }
                        else
                        {
                            request.SchedulingStatus = SchedulingStatus.Expired;
                        }
                    }

                    // Get Services for next time line
                    foreach (SchedulingRequest request in GetServicesForTimeLine(reschedule))
                    {
                        _unscheduledRequests.Add(request);
                    }

                    // Copy unscheduled requests to an ordered list
                    var servicesForNextTimeLine = new List <SchedulingRequest>(_unscheduledRequests
                                                                               .OrderBy(schedulingdata => schedulingdata.RequestedTime)
                                                                               .ThenByDescending(schedulingdata => schedulingdata.Configuration.Priority)
                                                                               );

                    // ------------------------------------
                    #endregion

                    #region Find Match services
                    // ------------------------------------

                    //Same services or same services with same profile
                    foreach (SchedulingRequest schedulingRequest in servicesForNextTimeLine)
                    {
                        //Get all services with same configurationID
                        var requestsWithSameConfiguration = _scheduledRequests.GetWithSameConfiguration(schedulingRequest);

                        //Get all services with same profileID
                        var requestsWithSameProfile = _scheduledRequests.GetWithSameProfile(schedulingRequest);

                        //Find the first available time this service with specific service and profile
                        TimeSpan avgExecutionTime = GetAverageExecutionTime(schedulingRequest.Configuration.Name, schedulingRequest.Configuration.Profile.ID, _percentile);

                        DateTime baseStartTime       = (schedulingRequest.RequestedTime < DateTime.Now) ? DateTime.Now : schedulingRequest.RequestedTime;
                        DateTime baseEndTime         = baseStartTime.Add(avgExecutionTime);
                        DateTime calculatedStartTime = baseStartTime;
                        DateTime calculatedEndTime   = baseEndTime;

                        bool found = false;
                        while (!found)
                        {
                            IOrderedEnumerable <SchedulingRequest> whereToLookNext = null;

                            int countedPerConfiguration = requestsWithSameConfiguration.Count(s => (calculatedStartTime >= s.ScheduledStartTime && calculatedStartTime <= s.ScheduledEndTime) || (calculatedEndTime >= s.ScheduledStartTime && calculatedEndTime <= s.ScheduledEndTime));
                            if (countedPerConfiguration < schedulingRequest.Configuration.MaxConcurrent)
                            {
                                int countedPerProfile = requestsWithSameProfile.Count(s => (calculatedStartTime >= s.ScheduledStartTime && calculatedStartTime <= s.ScheduledEndTime) || (calculatedEndTime >= s.ScheduledStartTime && calculatedEndTime <= s.ScheduledEndTime));
                                if (countedPerProfile < schedulingRequest.Configuration.MaxConcurrentPerProfile)
                                {
                                    if (!(schedulingRequest.Configuration is ServiceInstanceConfiguration))
                                    {
                                        // Not a child instance, so we need to create a new instance
                                        ServiceInstance serviceInstance = ServiceInstance.FromLegacyInstance(
                                            Legacy.Service.CreateInstance(schedulingRequest.Configuration.LegacyConfiguration, int.Parse(schedulingRequest.Configuration.Profile.Settings["AccountID"].ToString())),
                                            schedulingRequest.Configuration
                                            );

                                        // Make the request point to the instance configuration now that we have it
                                        schedulingRequest.Configuration = serviceInstance.Configuration;
                                    }

                                    schedulingRequest.ScheduledStartTime = calculatedStartTime;
                                    schedulingRequest.ScheduledEndTime   = calculatedEndTime;

                                    schedulingRequest.Instance.SchedulingRequest = schedulingRequest;
                                    schedulingRequest.Instance.StateChanged     += new EventHandler(Instance_StateChanged);
                                    schedulingRequest.Instance.OutcomeReported  += new EventHandler(Instance_OutcomeReported);

                                    // Legacy stuff
                                    TimeSpan maxExecutionTime = TimeSpan.FromMilliseconds(avgExecutionTime.TotalMilliseconds * double.Parse(AppSettings.Get(this, "MaxExecutionTimeProduct")));
                                    schedulingRequest.Configuration.MaxExecutionTime = maxExecutionTime;

                                    found = true;
                                }
                                else
                                {
                                    whereToLookNext = requestsWithSameProfile;
                                }
                            }
                            else
                            {
                                whereToLookNext = requestsWithSameConfiguration;
                            }

                            if (!found)
                            {
                                if (whereToLookNext == null)
                                {
                                    throw new Exception("This should not have happened.");
                                }

                                calculatedStartTime = whereToLookNext.Where(s => s.ScheduledEndTime >= calculatedStartTime).Min(s => s.ScheduledEndTime);
                                if (calculatedStartTime < DateTime.Now)
                                {
                                    calculatedStartTime = DateTime.Now;
                                }

                                //Get end time
                                calculatedEndTime = calculatedStartTime.Add(avgExecutionTime);

                                ////remove unfree time from servicePerConfiguration and servicePerProfile
                                if (calculatedStartTime <= _timeLineTo)
                                {
                                    requestsWithSameConfiguration = from s in requestsWithSameConfiguration
                                                                    where s.ScheduledEndTime > calculatedStartTime
                                                                    orderby s.ScheduledStartTime
                                                                    select s;

                                    requestsWithSameProfile = from s in requestsWithSameProfile
                                                              where s.ScheduledEndTime > calculatedStartTime
                                                              orderby s.ScheduledStartTime
                                                              select s;
                                }
                            }
                        }

                        if (schedulingRequest.ActualDeviation <= schedulingRequest.Rule.MaxDeviationAfter || schedulingRequest.Rule.MaxDeviationAfter == TimeSpan.Zero)
                        {
                            _scheduledRequests.Add(schedulingRequest);
                            _unscheduledRequests.Remove(schedulingRequest);
                            schedulingRequest.SchedulingStatus = SchedulingStatus.Scheduled;
                        }
                    }
                    #endregion
                }


                SchedulingInformationEventArgs args = new SchedulingInformationEventArgs();
                args.ScheduleInformation = new List <SchedulingRequest>();
                foreach (var scheduleService in _scheduledRequests)
                {
                    args.ScheduleInformation.Add(scheduleService);
                }
                OnNewScheduleCreated(args);
                NotifyServicesToRun();
            }
        }