Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix reconfiguration of fast modbus events #831

Merged
merged 2 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
wb-mqtt-serial (2.147.1) stable; urgency=medium

* Reconfigure fast modbus events after device restart

-- Petr Krasnoshchekov <[email protected]> Tue, 12 Nov 2024 21:25:35 +0500

KraPete marked this conversation as resolved.
Show resolved Hide resolved
wb-mqtt-serial (2.147.0) stable; urgency=medium

* Store press_counter register values as soon as possible.
Expand Down
20 changes: 20 additions & 0 deletions src/poll_plan.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ template<typename TItem> class TPriorityQueue: public std::priority_queue<TItem>
{
return std::find_if(this->c.cbegin(), this->c.cend(), pred) != this->c.cend();
}

template<typename Pred> void Remove(Pred pred)
{
auto it = std::find_if(this->c.begin(), this->c.end(), pred);
if (it != this->c.end()) {
this->c.erase(it);
std::make_heap(this->c.begin(), this->c.end(), this->comp);
}
}
};

template<class TEntry, typename ComparePredicate> class TPriorityQueueSchedule
Expand Down Expand Up @@ -72,6 +81,11 @@ template<class TEntry, typename ComparePredicate> class TPriorityQueueSchedule
return Entries.Contains([&](const TItem& item) { return item.Data == entry; });
}

void Remove(TEntry entry)
{
Entries.Remove([&](const TItem& item) { return item.Data == entry; });
}

private:
TPriorityQueue<TItem> Entries;
};
Expand Down Expand Up @@ -293,6 +307,12 @@ template<class TEntry, class TComparePredicate = std::less<TEntry>> class TSched
return LowPriorityQueue.Contains(entry) || HighPriorityQueue.Contains(entry);
}

void Remove(TEntry entry)
{
LowPriorityQueue.Remove(entry);
HighPriorityQueue.Remove(entry);
}

bool IsEmpty() const
{
return LowPriorityQueue.IsEmpty() && HighPriorityQueue.IsEmpty();
Expand Down
22 changes: 18 additions & 4 deletions src/serial_client_register_poller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ void TSerialClientRegisterPoller::ClosedPortCycle(steady_clock::time_point curre
{
Scheduler.ResetLoadBalancing();

RescheduleDisconnectedDevices();

TClosedPortDeviceReader reader(currentTime);
do {
reader.ClearRegisters();
Expand Down Expand Up @@ -180,6 +182,8 @@ TPollResult TSerialClientRegisterPoller::OpenPortCycle(TPort& port,
TSerialClientDeviceAccessHandler& lastAccessedDevice,
TRegisterCallback callback)
{
RescheduleDisconnectedDevices();

TPollResult res;

TDeviceReader reader(spentTime, maxPollingTime, readAtLeastOneRegister, lastAccessedDevice);
Expand Down Expand Up @@ -237,10 +241,7 @@ TPollResult TSerialClientRegisterPoller::OpenPortCycle(TPort& port,
void TSerialClientRegisterPoller::OnDeviceConnectionStateChanged(PSerialDevice device)
{
if (device->GetConnectionState() == TDeviceConnectionState::DISCONNECTED) {
auto range = Devices.equal_range(device);
for (auto it = range.first; it != range.second; ++it) {
it->second->RescheduleAllRegisters();
}
DisconnectedDevicesWaitingForReschedule.push_back(device);
}
KraPete marked this conversation as resolved.
Show resolved Hide resolved
}

Expand All @@ -263,3 +264,16 @@ std::string TThrottlingStateLogger::GetMessage()
}
return std::string();
}

void TSerialClientRegisterPoller::RescheduleDisconnectedDevices()
{
for (auto& device: DisconnectedDevicesWaitingForReschedule) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (auto& device: DisconnectedDevicesWaitingForReschedule) {
for (const auto& device: DisconnectedDevicesWaitingForReschedule) {

auto range = Devices.equal_range(device);
for (auto it = range.first; it != range.second; ++it) {
Scheduler.Remove(it->second);
it->second->RescheduleAllRegisters();
Scheduler.AddEntry(it->second, it->second->GetDeadline(), it->second->GetPriority());
}
}
DisconnectedDevicesWaitingForReschedule.clear();
}
KraPete marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 3 additions & 0 deletions src/serial_client_register_poller.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class TSerialClientRegisterPoller
std::chrono::steady_clock::time_point GetDeadline(bool lowPriorityRateLimitIsExceeded,
const util::TSpentTimeMeter& spentTime) const;
void OnDeviceConnectionStateChanged(PSerialDevice device);
void RescheduleDisconnectedDevices();

std::multimap<PSerialDevice, PPollableDevice> Devices;

Expand All @@ -61,4 +62,6 @@ class TSerialClientRegisterPoller
TThrottlingStateLogger ThrottlingStateLogger;

TRateLimiter LowPriorityRateLimiter;

std::vector<PSerialDevice> DisconnectedDevicesWaitingForReschedule;
KraPete marked this conversation as resolved.
Show resolved Hide resolved
};