#pragma once #include #include #include #include #include #include #include #include #include #include namespace wfr { // Forward declarations namespace wep { class WorkflowExecutionPlan; class AtomicWepNode; } namespace enactment { class EnactmentEngine; } namespace execution { class ExecutionManager; } namespace prediction { class PredictionManager; } namespace resource { class ResourceManager; } // Main namespace namespace scheduling { // Forward declaration class SchedulingDecision; /* * Represents the interface every scheduler needs to implement. * * Workflow execution sequence: * 1) registerWEP() is called by enactment engine to register new workflow instance * 2) notifyWEPUpdate() is called by enactment engine to notify scheduler of workflow progress * 3) The scheduler creates scheduling decisions objects and passes them to the execution layer * - uses convenience function SchedulerBase::executeSchedulingDecision, or * - directly calls ExecutionManager::executeSchedulingDecision * 4) The execution layer calls notifySchedulingDecisionStatusUpdate to notify scheduler about executed (or failed) activities. * - the scheduler needs then to call EnactmentEngine::notifyActivityInstanceStateUpdate() to notify the enactment engine. * - SchedulerBase already automatically notifies the enactment engine. * 5) Goto 2) till unregisterWEP() is called. */ class AbstractScheduler { public: virtual ~AbstractScheduler() noexcept {} /* * Is called by the enactment engine to let the scheduler know of a new workflow instance. * * @param wep workflow execution plan object representing the workflow instance * @param ee reference to enactment engine */ virtual void registerWEP(wep::WorkflowExecutionPlan& wep, enactment::EnactmentEngine& ee) noexcept = 0; /* * Is called by the enactment engine to let the scheduler know that a workflow instance has finished * * @param wep workflow execution plan object representing the workflow instance */ virtual void unregisterWEP(wep::WorkflowExecutionPlan& wep) noexcept = 0; /* * Is called by the enactment engine to let the scheduler know about changes to the workflow execution plan. * * @param wep workflow execution plan object representing the workflow instance * @param readytoExecute set of new ready-to-execute activities (for convenience) */ virtual void notifyWEPUpdate(wep::WorkflowExecutionPlan& wep, std::set readyToExecute) noexcept = 0; /* * Called by the execution layer to notify the scheduler that an activity finished (or failed) execution. * * @param sd reference to scheduling decision object. */ virtual void notifySchedulingDecisionStatusUpdate(std::shared_ptr sd) noexcept = 0; virtual double getCummulativePredictionTime() noexcept = 0; }; /* * Scheduler base class implementing common scheduler functionality. */ class SchedulerBase : public AbstractScheduler { public: struct WepMapEntry { WepMapEntry(enactment::EnactmentEngine* engine, wep::WorkflowExecutionPlan* wep) : engine(engine), wep(wep) {} enactment::EnactmentEngine* engine; wep::WorkflowExecutionPlan* wep; std::set> decisions; void* userData = nullptr; }; protected: typedef std::map wepMap_t; std::mutex schedulerMutex; wepMap_t wepMap; bool simulationMode; double cummulativePredictionTime = 0; std::map>> scheduledTasks; protected: // Hook functions for AbstractScheduler functions below to allow customisation of common functionality virtual void _registerWEP(WepMapEntry& wepe, std::unique_lock& schedulerLock) {}; virtual void _unregisterWEP(WepMapEntry& wepe, std::unique_lock& schedulerLock) {} virtual void _notifyWEPUpdate(WepMapEntry& wepe, std::set readyToExecute, std::unique_lock& schedulerLock) {} virtual void _notifySchedulingDecisionStatusUpdate(WepMapEntry& wepe, std::shared_ptr sd, std::unique_lock& schedulerLock) {} virtual double _getResourceEstimatedAvailableTime(resource::ComputingResource* resource); // Convenience functions for passing a scheduling decision to the execution layer. bool executeSchedulingDecision(WepMapEntry& wepe, std::shared_ptr sd, std::unique_lock& schedulerLock) noexcept; public: SchedulerBase(); virtual ~SchedulerBase() noexcept; // From AbstractScheduler class virtual void registerWEP(wep::WorkflowExecutionPlan& wep, enactment::EnactmentEngine& ee) noexcept override; virtual void unregisterWEP(wep::WorkflowExecutionPlan& wep) noexcept override; virtual void notifyWEPUpdate(wep::WorkflowExecutionPlan& wep, std::set readyToExecute) noexcept override; virtual void notifySchedulingDecisionStatusUpdate(std::shared_ptr wep) noexcept override; virtual double getCummulativePredictionTime() noexcept override { return cummulativePredictionTime; } }; } /* namespace scheduling */ } /* namespace wfr */