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

Modbus performance and logging improvements #4304

Merged
merged 6 commits into from Dec 9, 2018

Conversation

ssalonen
Copy link
Contributor

@ssalonen ssalonen commented Dec 2, 2018

Some small performance improvements identified using JProfiler:

  • avoid calling isLinked(String) and prefer isLinked(ChannelUID)
  • avoid creating ChanneUID, now reusing same instances
  • some diagnostic (e.g. last read success) channels were updated even though they were not linked. Turns out DateTimeType unnecessary construction shows up profiler

Furthermore, logging improved to give clear outline of bottle necks (from raspberry pi 3B):

Modbus operation ended, timing info: {total: 476 ms, connection: 15, transaction=4, callback=412} [operation ID 2379c461-b4bc-473f-96f0-0c23987f3250]

(currently most of the time is spent in the binding.modbus when data has been already received from the slave)

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
Signed-off-by: Sami Salonen <ssalonen@gmail.com>
This was introduced to get high-level split down for each operation

Example log statement:
  Modbus operation ended, timing info: {total: 476 ms, connection: 15, transaction=4, callback=412} [operation ID 2379c461-b4bc-473f-96f0-0c23987f3250]

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
Signed-off-by: Sami Salonen <ssalonen@gmail.com>
}
}
}
Exception exception = lastError.get();
if (exception != null) {
// All retries failed with some error
if (callback != null) {
callbackThreadPool.execute(() -> {
Copy link
Contributor Author

@ssalonen ssalonen Dec 2, 2018

Choose a reason for hiding this comment

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

We want to run in some thread right away, similar to other callbacks. Thus, removing call to ExecutorService.execute and invoking the callback directly.

Should have spotted this already in https://github.com/openhab/openhab2-addons/pull/4158

return Optional.empty();
}
if (!connection.isPresent()) {
logger.warn("Could not connect to endpoint {} -- aborting request {} [operation ID {}]", endpoint, request,
operationId);
if (callback != null) {
callbackPool.execute(() -> {
Copy link
Contributor Author

@ssalonen ssalonen Dec 2, 2018

Choose a reason for hiding this comment

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

We want to run in some thread right away, similar to other callbacks. Thus, removing call to ExecutorService.execute and invoking the callback directly.

Should have spotted this already in https://github.com/openhab/openhab2-addons/pull/4158

DateTimeType now = new DateTimeType();
updateStatus(ThingStatus.ONLINE);
updateState(ModbusBindingConstantsInternal.CHANNEL_LAST_WRITE_SUCCESS, now);
if (getThing().getStatus() != ThingStatus.ONLINE) {
Copy link
Member

Choose a reason for hiding this comment

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

@kaikreuzer do we want to optimize such things as this one and line 765

Copy link
Member

Choose a reason for hiding this comment

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

Or should the framework be optimized better, @ssalonen how expensive was this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's expensive enough to show up in my profiling studies... Modbus is a tough case since some users have very high poll rates..

Haven't looked into the framework if there is any obvious optimizations

Copy link
Member

Choose a reason for hiding this comment

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

The general suggestion is to throttle it in the binding this way if there are status updates every few seconds. I guess that's the case for modbus, so this optimisation is fine. We could also think about moving something like that to the framework, but having it transparent in the binding is imho not bad.

Copy link
Member

Choose a reason for hiding this comment

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

Great thanks 👍

Copy link
Member

Choose a reason for hiding this comment

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

The LIFX binding had a similar issue which was addressed with eclipse-archived/smarthome#3816. It sends the same update at most once a second. That way it can still be used for the "last seen online" feature that will be there some day. 😉

Copy link
Contributor Author

@ssalonen ssalonen Dec 9, 2018

Choose a reason for hiding this comment

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

Nice find @wborn. I adapted the code to follow the convention set by LIFX:
f75be1a

Now throttling all state updates in data thing with the same logic as in LIFX.

@martinvw
Copy link
Member

martinvw commented Dec 7, 2018

Results :
Failed tests: 
  ModbusDataHandlerTest.testOnRegistersRealTransformationNoLinks:781->assertSingleStateUpdate:426 
Expected: is is not null
     but: was null

@ssalonen
Copy link
Contributor Author

ssalonen commented Dec 9, 2018

@martinvw fixed the tests in 0e4e05a

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
Even "last successful read" will not get an update if it is not linked

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
Copy link
Member

@wborn wborn left a comment

Choose a reason for hiding this comment

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

Thanks!

@wborn wborn merged commit 6e9f7d8 into openhab:master Dec 9, 2018
@openhab-bot
Copy link
Collaborator

This pull request has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/many-100-modbus-pollers-is-it-slowing-down-the-binding/53496/22

limdul79 pushed a commit to limdul79/openhab2-addons that referenced this pull request Dec 23, 2018
* Cache ChannelUID creation for no reason
* Timing information for modbus operations

This was introduced to get high-level split down for each operation

Example log statement:
  Modbus operation ended, timing info: {total: 476 ms, connection: 15, transaction=4, callback=412} [operation ID 2379c461-b4bc-473f-96f0-0c23987f3250]

* Avoid creating DateTimeType for no reason
* Throttle ONLINE updates to 1 second

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
limdul79 pushed a commit to limdul79/openhab2-addons that referenced this pull request Dec 23, 2018
* Cache ChannelUID creation for no reason
* Timing information for modbus operations

This was introduced to get high-level split down for each operation

Example log statement:
  Modbus operation ended, timing info: {total: 476 ms, connection: 15, transaction=4, callback=412} [operation ID 2379c461-b4bc-473f-96f0-0c23987f3250]

* Avoid creating DateTimeType for no reason
* Throttle ONLINE updates to 1 second

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
@openhab-bot
Copy link
Collaborator

This pull request has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/modbus-binding-with-wago-controller/60642/21

ssalonen added a commit to ssalonen/openhab2-addons that referenced this pull request Dec 27, 2018
Regression introduced in PR openhab#4304: the thing status description is not
passed to thing status updates.

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
cweitkamp pushed a commit that referenced this pull request Dec 28, 2018
* [modbus] data thing: update thing status including description

Regression introduced in PR #4304: the thing status description is not
passed to thing status updates.

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
chaton78 pushed a commit to chaton78/openhab-addons that referenced this pull request Jan 1, 2019
* Cache ChannelUID creation for no reason
* Timing information for modbus operations

This was introduced to get high-level split down for each operation

Example log statement:
  Modbus operation ended, timing info: {total: 476 ms, connection: 15, transaction=4, callback=412} [operation ID 2379c461-b4bc-473f-96f0-0c23987f3250]

* Avoid creating DateTimeType for no reason
* Throttle ONLINE updates to 1 second

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
Signed-off-by: Pascal Larin <plarin@gmail.com>
chaton78 pushed a commit to chaton78/openhab-addons that referenced this pull request Jan 1, 2019
* [modbus] data thing: update thing status including description

Regression introduced in PR openhab#4304: the thing status description is not
passed to thing status updates.

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
Signed-off-by: Pascal Larin <plarin@gmail.com>
ne0h pushed a commit to ne0h/openhab-addons that referenced this pull request Sep 15, 2019
* Cache ChannelUID creation for no reason
* Timing information for modbus operations

This was introduced to get high-level split down for each operation

Example log statement:
  Modbus operation ended, timing info: {total: 476 ms, connection: 15, transaction=4, callback=412} [operation ID 2379c461-b4bc-473f-96f0-0c23987f3250]

* Avoid creating DateTimeType for no reason
* Throttle ONLINE updates to 1 second

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
Signed-off-by: Maximilian Hess <mail@ne0h.de>
ne0h pushed a commit to ne0h/openhab-addons that referenced this pull request Sep 15, 2019
* [modbus] data thing: update thing status including description

Regression introduced in PR openhab#4304: the thing status description is not
passed to thing status updates.

Signed-off-by: Sami Salonen <ssalonen@gmail.com>
Signed-off-by: Maximilian Hess <mail@ne0h.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants