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

[avmfritz] Added initial refresh of Call Monitor channels and improved thread handling #9734

Conversation

cweitkamp
Copy link
Contributor

@cweitkamp cweitkamp commented Jan 7, 2021

  • Added initial refresh of Call Monitor channels
  • Improved CallMonitorThread handling

Fixes #9712

Signed-off-by: Christoph Weitkamp [email protected]

@cweitkamp cweitkamp added the enhancement An enhancement or new feature for an existing add-on label Jan 7, 2021
Signed-off-by: Christoph Weitkamp <[email protected]>
@cweitkamp cweitkamp added bug An unexpected problem or unintended behavior of an add-on and removed enhancement An enhancement or new feature for an existing add-on labels Jan 8, 2021
@cweitkamp cweitkamp changed the title [avmfritz] Added initial refresh of Call Monitor channels [avmfritz] Added initial refresh of Call Monitor channels and improved thread handling Jan 8, 2021
} else if (this.callMonitor != null && !callChannelsLinked()) {
CallMonitor cm = this.callMonitor;
// initialize states of call monitor channels
scheduler.schedule(this::refreshCallChannels, refreshInterval, TimeUnit.SECONDS);
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it be more elegant to do this in the constructor of CallMonitorThread?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice idea but I do not think that it makes a difference because we just set default values without querying the real data (which btw is not possible as the call Monitor is an event based communication).

Copy link
Contributor

Choose a reason for hiding this comment

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

It probably doesn't, it just would avoid potential race conditions since this refresh calls happens asynchronously, and so does the thread creation. If a call came in right after thread creation, we might wrongly reset the state during the call.
Hypothetical, I know, but moving the initialization avoids that scenario :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is a valid point. On the opposite side we have the 2 hour recreation of the thread which will then lead to repeated initialization ... Might happen during an active call too.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good point. Maybe do the initialization in the CallMonitor constructor then?

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 is not a real thread, but periodically scheduled jobs. What I mean is that the variable refreshInterval is a protected property within the AVMFritzBaseThingHandler and I have no access to it in CallMonitor constructor unless I add a method to expose it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you need refreshInterval though? I thought the point of that initial refresh is to have the channels have undef/idle instead of NULL on startup. Is that correct? If so, how is the timing of that initialization dependent on the box poll interval?

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 can be 5sec either. We just need a short time span to wait for the thread to be started as ist is done asynchronously too.

Copy link
Contributor

@maniac103 maniac103 Jan 11, 2021

Choose a reason for hiding this comment

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

It can be 5sec either

I figured so, but in that case you don't need to access refreshInterval and could initialize the channels in the CallMonitor constructor (in the main thread, before starting the call monitor thread) just fine.
The method for resetting the channels could be moved from CallMonitorThread to CallMonitor (basically remove refreshChannels and move resetChannels to its place), since the former can also call into the latter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed it.

@wborn wborn added rebuild Triggers Jenkins PR build and removed rebuild Triggers Jenkins PR build labels Jan 8, 2021
Signed-off-by: Christoph Weitkamp <[email protected]>
@cweitkamp cweitkamp force-pushed the feature-avmfritz-refresh-call-monitor-channels branch from 2df4067 to f3a311a Compare January 12, 2021 07:42
Signed-off-by: Christoph Weitkamp <[email protected]>
Copy link
Contributor

@maniac103 maniac103 left a comment

Choose a reason for hiding this comment

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

LGTM now 👍

@@ -106,7 +113,7 @@ public void run() {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// reset the retry interval
reconnectTime = 60000L;
} catch (Exception e) {
} catch (IOException e) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this is a custom thread uncaught runtime exceptions will not be logged if they occur. To make troubleshooting easier I think that you should add an UncaughtExceptionHandler to the thread so that unexpected thread deaths can be logged.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Something like 1533478?

Signed-off-by: Christoph Weitkamp <[email protected]>
Signed-off-by: Christoph Weitkamp <[email protected]>
public void uncaughtException(@Nullable Thread thread, @Nullable Throwable throwable) {
logger.debug("Lost connection to FRITZ!Box because of an uncaught exception: ", throwable);
handler.setStatusInfo(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, String.format(
"Lost connection to FRITZ!Box: %s", throwable == null ? "null" : throwable.getMessage()));
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this a bit harsh? My suggestion would be making CallMonitor implement the uncaught exception handler interface and from there logging the error and respawning the thread.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Isn't the 2h reconnect job sufficient?

Copy link
Contributor

@maniac103 maniac103 Jan 14, 2021

Choose a reason for hiding this comment

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

It probably is, but I don't really see why we need to wait with reconnection when we

  • know we need reconnection anyway and
  • there is a trivial way to do that reconnection?

Things would be different if we needed to write a lot of code to respawn the thread, but I don't see how that would be the case here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I usually implement the UncaughtExceptionHandler as a lambda.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cpmeister Done.

@maniac103 Yes, valid points. But I think the 2h reconnect is enough. I now changed the LOG level to warn and do not set the handler to OFFLINE anymore.

Signed-off-by: Christoph Weitkamp <[email protected]>
Copy link
Contributor

@cpmeister cpmeister left a comment

Choose a reason for hiding this comment

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

LGTM

@cpmeister cpmeister added rebuild Triggers Jenkins PR build and removed rebuild Triggers Jenkins PR build labels Jan 15, 2021
@cweitkamp cweitkamp added rebuild Triggers Jenkins PR build and removed rebuild Triggers Jenkins PR build labels Jan 16, 2021
@cpmeister cpmeister merged commit 3c27aeb into openhab:main Jan 17, 2021
@cpmeister cpmeister added this to the 3.1 milestone Jan 17, 2021
@cweitkamp cweitkamp deleted the feature-avmfritz-refresh-call-monitor-channels branch January 18, 2021 05:49
themillhousegroup pushed a commit to themillhousegroup/openhab2-addons that referenced this pull request May 10, 2021
…d thread handling (openhab#9734)

* Added initial refresh of Call Monitor channels

Signed-off-by: Christoph Weitkamp <[email protected]>
Signed-off-by: John Marshall <[email protected]>
thinkingstone pushed a commit to thinkingstone/openhab-addons that referenced this pull request Nov 7, 2021
…d thread handling (openhab#9734)

* Added initial refresh of Call Monitor channels

Signed-off-by: Christoph Weitkamp <[email protected]>
marcfischerboschio pushed a commit to bosch-io/openhab-addons that referenced this pull request May 5, 2022
…d thread handling (openhab#9734)

* Added initial refresh of Call Monitor channels

Signed-off-by: Christoph Weitkamp <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An unexpected problem or unintended behavior of an add-on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[avmfritz] Call monitoring does not work
4 participants