mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 08:41:16 +00:00
feat!: Remove Device::TransitionTo()
without replacement
BREAKING CHANGE However, this API was never advertised nor used by anyone.
This commit is contained in:
parent
57a6c926aa
commit
4a612ba9a7
|
@ -91,7 +91,6 @@ Device::Device(ProgOptions* config, tools::Version version)
|
||||||
, fVersion(version)
|
, fVersion(version)
|
||||||
, fRate(DefaultRate)
|
, fRate(DefaultRate)
|
||||||
, fInitializationTimeoutInS(DefaultInitTimeout)
|
, fInitializationTimeoutInS(DefaultInitTimeout)
|
||||||
, fTransitioning(false)
|
|
||||||
{
|
{
|
||||||
SubscribeToNewTransition("device", [&](Transition transition) {
|
SubscribeToNewTransition("device", [&](Transition transition) {
|
||||||
LOG(trace) << "device notified on new transition: " << transition;
|
LOG(trace) << "device notified on new transition: " << transition;
|
||||||
|
@ -143,73 +142,6 @@ Device::Device(ProgOptions* config, tools::Version version)
|
||||||
}
|
}
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
void Device::TransitionTo(State s)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
lock_guard<mutex> lock(fTransitionMtx);
|
|
||||||
if (fTransitioning) {
|
|
||||||
LOG(debug) << "Attempting a transition with TransitionTo() while another one is already in progress";
|
|
||||||
throw OngoingTransition("Attempting a transition with TransitionTo() while another one is already in progress");
|
|
||||||
}
|
|
||||||
fTransitioning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
using mq::State;
|
|
||||||
|
|
||||||
StateQueue sq;
|
|
||||||
StateSubscription ss(tools::ToString(fId, ".TransitionTo"), fStateMachine, sq);
|
|
||||||
|
|
||||||
State currentState = GetCurrentState();
|
|
||||||
|
|
||||||
while (s != currentState) {
|
|
||||||
switch (currentState) {
|
|
||||||
case State::Idle:
|
|
||||||
if (s == State::Exiting) { ChangeStateOrThrow(Transition::End); }
|
|
||||||
else { ChangeStateOrThrow(Transition::InitDevice); }
|
|
||||||
break;
|
|
||||||
case State::InitializingDevice:
|
|
||||||
ChangeStateOrThrow(Transition::CompleteInit);
|
|
||||||
break;
|
|
||||||
case State::Initialized:
|
|
||||||
if (s == State::Exiting || s == State::Idle) { ChangeStateOrThrow(Transition::ResetDevice); }
|
|
||||||
else { ChangeStateOrThrow(Transition::Bind); }
|
|
||||||
break;
|
|
||||||
case State::Bound:
|
|
||||||
if (s == State::DeviceReady || s == State::Ready || s == State::Running) { ChangeStateOrThrow(Transition::Connect); }
|
|
||||||
else { ChangeStateOrThrow(Transition::ResetDevice); }
|
|
||||||
break;
|
|
||||||
case State::DeviceReady:
|
|
||||||
if (s == State::Running || s == State::Ready) { ChangeStateOrThrow(Transition::InitTask); }
|
|
||||||
else { ChangeStateOrThrow(Transition::ResetDevice); }
|
|
||||||
break;
|
|
||||||
case State::Ready:
|
|
||||||
if (s == State::Running) { ChangeStateOrThrow(Transition::Run); }
|
|
||||||
else { ChangeStateOrThrow(Transition::ResetTask); }
|
|
||||||
break;
|
|
||||||
case State::Running:
|
|
||||||
ChangeStateOrThrow(Transition::Stop);
|
|
||||||
break;
|
|
||||||
case State::Binding:
|
|
||||||
case State::Connecting:
|
|
||||||
case State::InitializingTask:
|
|
||||||
case State::ResettingDevice:
|
|
||||||
case State::ResettingTask:
|
|
||||||
LOG(debug) << "TransitionTo ignoring state: " << currentState << " (expected, automatic transition).";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(debug) << "TransitionTo ignoring state: " << currentState;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentState = sq.WaitForNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
lock_guard<mutex> lock(fTransitionMtx);
|
|
||||||
fTransitioning = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::InitWrapper()
|
void Device::InitWrapper()
|
||||||
{
|
{
|
||||||
// run initialization once CompleteInit transition is requested
|
// run initialization once CompleteInit transition is requested
|
||||||
|
|
|
@ -552,8 +552,6 @@ class Device
|
||||||
/// @param state state to wait for
|
/// @param state state to wait for
|
||||||
void WaitForState(const std::string& state) { WaitForState(GetState(state)); }
|
void WaitForState(const std::string& state) { WaitForState(GetState(state)); }
|
||||||
|
|
||||||
void TransitionTo(State state);
|
|
||||||
|
|
||||||
/// @brief Subscribe with a callback to state changes
|
/// @brief Subscribe with a callback to state changes
|
||||||
/// @param key id to identify your subscription
|
/// @param key id to identify your subscription
|
||||||
/// @param callback callback (called with the new state as the parameter)
|
/// @param callback callback (called with the new state as the parameter)
|
||||||
|
@ -683,8 +681,6 @@ class Device
|
||||||
StateQueue fStateQueue;
|
StateQueue fStateQueue;
|
||||||
|
|
||||||
std::mutex fTransportMtx; ///< guards access to transports container
|
std::mutex fTransportMtx; ///< guards access to transports container
|
||||||
std::mutex fTransitionMtx;
|
|
||||||
bool fTransitioning;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace fair::mq
|
} // namespace fair::mq
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -20,83 +20,6 @@ namespace
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace fair::mq;
|
using namespace fair::mq;
|
||||||
|
|
||||||
class SlowDevice : public Device
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SlowDevice() = default;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void Init() override
|
|
||||||
{
|
|
||||||
this_thread::sleep_for(chrono::milliseconds(100));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void transitionTo(const vector<State>& states, int numExpectedStates)
|
|
||||||
{
|
|
||||||
Device device;
|
|
||||||
|
|
||||||
thread t([&] {
|
|
||||||
for (const auto& s : states) {
|
|
||||||
device.TransitionTo(s);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
int numStates = 0;
|
|
||||||
|
|
||||||
device.SubscribeToStateChange("testRunner", [&numStates](State /* state */) {
|
|
||||||
numStates++;
|
|
||||||
});
|
|
||||||
|
|
||||||
device.RunStateMachine();
|
|
||||||
|
|
||||||
if (t.joinable()) {
|
|
||||||
t.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(info) << "expected " << numExpectedStates << ", encountered " << numStates << " states";
|
|
||||||
EXPECT_EQ(numStates, numExpectedStates);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Transitions, TransitionTo)
|
|
||||||
{
|
|
||||||
transitionTo({State::Exiting}, 2);
|
|
||||||
transitionTo({State::InitializingDevice, State::Initialized, State::Exiting}, 6);
|
|
||||||
transitionTo({State::Initialized, State::Exiting}, 6);
|
|
||||||
transitionTo({State::DeviceReady, State::Bound, State::Running, State::Exiting}, 24);
|
|
||||||
transitionTo({State::Ready, State::Exiting}, 14);
|
|
||||||
transitionTo({State::Running, State::Exiting}, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Transitions, ConcurrentTransitionTos)
|
|
||||||
{
|
|
||||||
fair::Logger::SetConsoleSeverity("debug");
|
|
||||||
SlowDevice slowDevice;
|
|
||||||
|
|
||||||
vector<State> states({State::Ready, State::Exiting});
|
|
||||||
|
|
||||||
thread t1([&] {
|
|
||||||
for (const auto& s : states) {
|
|
||||||
slowDevice.TransitionTo(s);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
thread t2([&] {
|
|
||||||
this_thread::sleep_for(chrono::milliseconds(50));
|
|
||||||
ASSERT_THROW(slowDevice.TransitionTo(State::Exiting), OngoingTransition);
|
|
||||||
});
|
|
||||||
|
|
||||||
slowDevice.RunStateMachine();
|
|
||||||
|
|
||||||
if (t1.joinable()) {
|
|
||||||
t1.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t2.joinable()) {
|
|
||||||
t2.join();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Transitions, InvalidChangeState)
|
TEST(Transitions, InvalidChangeState)
|
||||||
{
|
{
|
||||||
Device device;
|
Device device;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user