FairMQ: Implement PluginServices - Control

This commit is contained in:
Dennis Klein
2017-06-26 15:30:08 +02:00
committed by Mohammad Al-Turany
parent 9b61b924b2
commit 739460b2fe
8 changed files with 200 additions and 50 deletions

View File

@@ -11,8 +11,10 @@
#include <FairMQDevice.h>
#include <options/FairMQProgOptions.h>
#include <atomic>
#include <functional>
#include <string>
#include <unordered_map>
namespace fair
{
@@ -30,56 +32,175 @@ class PluginServices
{
public:
/// See https://github.com/FairRootGroup/FairRoot/blob/dev/fairmq/docs/Device.md#13-state-machine
enum class DeviceState
{
Ok,
Error,
Idle,
InitializingDevice,
DeviceReady,
InitializingTask,
Ready,
Running,
Paused,
ResettingTask,
ResettingDevice,
Exiting
};
enum class DeviceStateTransition // transition event between DeviceStates
{
InitDevice,
InitTask,
Run,
Pause,
Stop,
ResetTask,
ResetDevice,
End,
ErrorFound
};
PluginServices() = delete;
PluginServices(FairMQProgOptions& config, FairMQDevice& device)
: fDevice{device}
, fConfig{config}
{}
, fConfigEnabled{false}
, fkDeviceStateStrMap{
{"Ok", DeviceState::Ok},
{"Error", DeviceState::Error},
{"Idle", DeviceState::Idle},
{"InitializingDevice", DeviceState::InitializingDevice},
{"DeviceReady", DeviceState::DeviceReady},
{"InitializingTask", DeviceState::InitializingTask},
{"Ready", DeviceState::Ready},
{"Running", DeviceState::Running},
{"Paused", DeviceState::Paused},
{"ResettingTask", DeviceState::ResettingTask},
{"ResettingDevice", DeviceState::ResettingDevice},
{"Exiting", DeviceState::Exiting}
}
, fkStrDeviceStateMap{
{DeviceState::Ok, "Ok"},
{DeviceState::Error, "Error"},
{DeviceState::Idle, "Idle"},
{DeviceState::InitializingDevice, "InitializingDevice"},
{DeviceState::DeviceReady, "DeviceReady"},
{DeviceState::InitializingTask, "InitializingTask"},
{DeviceState::Ready, "Ready"},
{DeviceState::Running, "Running"},
{DeviceState::Paused, "Paused"},
{DeviceState::ResettingTask, "ResettingTask"},
{DeviceState::ResettingDevice, "ResettingDevice"},
{DeviceState::Exiting, "Exiting"}
}
, fkDeviceStateMap{
{FairMQDevice::OK, DeviceState::Ok},
{FairMQDevice::ERROR, DeviceState::Error},
{FairMQDevice::IDLE, DeviceState::Idle},
{FairMQDevice::INITIALIZING_DEVICE, DeviceState::InitializingDevice},
{FairMQDevice::DEVICE_READY, DeviceState::DeviceReady},
{FairMQDevice::INITIALIZING_TASK, DeviceState::InitializingTask},
{FairMQDevice::READY, DeviceState::Ready},
{FairMQDevice::RUNNING, DeviceState::Running},
{FairMQDevice::PAUSED, DeviceState::Paused},
{FairMQDevice::RESETTING_TASK, DeviceState::ResettingTask},
{FairMQDevice::RESETTING_DEVICE, DeviceState::ResettingDevice},
{FairMQDevice::EXITING, DeviceState::Exiting}
}
, fkDeviceStateTransitionMap{
{DeviceStateTransition::InitDevice, FairMQDevice::INIT_DEVICE},
{DeviceStateTransition::InitTask, FairMQDevice::INIT_TASK},
{DeviceStateTransition::Run, FairMQDevice::RUN},
{DeviceStateTransition::Pause, FairMQDevice::PAUSE},
{DeviceStateTransition::Stop, FairMQDevice::STOP},
{DeviceStateTransition::ResetTask, FairMQDevice::RESET_TASK},
{DeviceStateTransition::ResetDevice, FairMQDevice::RESET_DEVICE},
{DeviceStateTransition::End, FairMQDevice::END},
{DeviceStateTransition::ErrorFound, FairMQDevice::ERROR_FOUND}
}
{
}
// Control
//enum class DeviceState
//{
//Error,
//Idle,
//Initializing_device,
//Device_ready,
//Initializing_task,
//Ready,
//Running,
//Paused,
//Resetting_task,
//Resetting_device,
//Exiting
//}
//auto ToDeviceState(std::string state) const -> DeviceState;
/// @brief Convert string to DeviceState
/// @param state to convert
/// @return DeviceState enum entry
/// @throw std::out_of_range if a string cannot be resolved to a DeviceState
auto ToDeviceState(const std::string& state) const -> DeviceState
{
return fkDeviceStateStrMap.at(state);
}
//auto ChangeDeviceState(DeviceState next) -> void;
/// @brief Convert DeviceState to string
/// @param string to convert
/// @return string representation of DeviceState enum entry
auto ToStr(DeviceState state) const -> std::string
{
return fkStrDeviceStateMap.at(state);
}
//auto SubscribeToDeviceStateChange(std::function<void(DeviceState [>new<])> callback) -> void;
//auto UnsubscribeFromDeviceChange() -> void;
/// @return current device state
auto GetCurrentDeviceState() const -> DeviceState
{
return fkDeviceStateMap.at(static_cast<FairMQDevice::State>(fDevice.GetCurrentState()));
}
//// Configuration
/// @brief Trigger a device state transition
/// @param next state transition
///
/// The state transition may not happen immediately, but when the current state evaluates the
/// pending transition event and terminates. In other words, the device states are scheduled cooperatively.
auto ChangeDeviceState(const DeviceStateTransition next) -> void
{
fDevice.ChangeState(fkDeviceStateTransitionMap.at(next));
}
//// Writing only works during Initializing_device state
//template<typename T>
//auto SetProperty(const std::string& key, T val) -> void;
/// @brief Subscribe with a callback to device state changes
/// @param InputMsgCallback
///
/// The callback will be called at the beginning of a new state. The callback is called from the thread
/// the state is running in.
auto SubscribeToDeviceStateChange(const std::string& key, std::function<void(DeviceState /*newState*/)> callback) -> void
{
fDevice.OnStateChange(key, [&,callback](FairMQDevice::State newState){
callback(fkDeviceStateMap.at(newState));
});
}
//template<typename T>
//auto GetProperty(const std::string& key) const -> T;
//auto GetPropertyAsString(const std::string& key) const -> std::string;
auto UnsubscribeFromDeviceStateChange(const std::string& key) -> void
{
fDevice.UnsubscribeFromStateChange(key);
}
//template<typename T>
//auto SubscribeToPropertyChange(
//const std::string& key,
//std::function<void(const std::string& [>key*/, const T /*newValue<])> callback
//) const -> void;
//auto UnsubscribeFromPropertyChange(const std::string& key) -> void;
//// Configuration
//// Writing only works during Initializing_device state
//template<typename T>
//auto SetProperty(const std::string& key, T val) -> void;
//template<typename T>
//auto GetProperty(const std::string& key) const -> T;
//auto GetPropertyAsString(const std::string& key) const -> std::string;
//template<typename T>
//auto SubscribeToPropertyChange(
//const std::string& key,
//std::function<void(const std::string& [>key*/, const T /*newValue<])> callback
//) const -> void;
//auto UnsubscribeFromPropertyChange(const std::string& key) -> void;
private:
FairMQDevice& fDevice;
FairMQProgOptions& fConfig;
FairMQDevice& fDevice;
std::atomic<bool> fConfigEnabled;
const std::unordered_map<std::string, DeviceState> fkDeviceStateStrMap;
const std::unordered_map<DeviceState, std::string> fkStrDeviceStateMap;
const std::unordered_map<FairMQDevice::State, DeviceState> fkDeviceStateMap;
const std::unordered_map<DeviceStateTransition, FairMQDevice::Event> fkDeviceStateTransitionMap;
}; /* class PluginServices */
} /* namespace mq */