It is currently May 26th, 2024, 11:49 pm

[BUG] Ping Measure's FinishAction

Report bugs with the Rainmeter application and suggest features.
User avatar
Yincognito
Rainmeter Sage
Posts: 7333
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

[BUG] Ping Measure's FinishAction

Post by Yincognito »

Test skin:

Code: Select all

[Rainmeter]
Update=1000
BackgroundMode=2
SolidColor=0,0,0,255

[MeasurePing]
Measure=Plugin
Plugin=PingPlugin
DestAddress=8.8.8.8
FinishAction=[!Log "Finished: [MeasurePing] ms"]
DynamicVariables=1

[MeterPing]
Meter=String
MeasureName=MeasurePing
X=5
Y=5
W=200
H=20
FontColor=255,255,255,255
Text=Ping Test: %1ms
Watching the log shows that the moment when the bangs in the FinishAction are executed has nothing to do with when they are supposed to be executed, i.e. when "a successful value is returned, or when the number of milliseconds set in the Timeout option is reached", according to the manual. For example, they execute right on refresh and yield "0 ms" even though they should wait for an actual result like, say, "19 ms", after the reply from the server was issued successfully.

Basically, it appears that the value returned in the log is the value returned one measure update ago in the meter.

P.S. A workaround to this is to use OnChangeAction on the measure instead, for the time being.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Brian
Developer
Posts: 2696
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: [BUG] Ping Measure's FinishAction

Post by Brian »

Seems to work as designed.

You are self-referencing in your FinishAction, so it will always be the previous value. The first time, it will always show "0ms", then it will be previous result.

You probably need another measure to properly log this. Something like:

Code: Select all

[Rainmeter]
Update=1000
BackgroundMode=2
SolidColor=0,0,0,255

[MeasurePing]
Measure=Plugin
Plugin=PingPlugin
DestAddress=8.8.8.8
FinishAction=[!EnableMeasure MeasurePingResult][!UpdateMeasure MeasurePingResult]

[MeasurePingResult]
Measure=Calc
Formula=MeasurePing
OnChangeAction=[!Log "Finished: [MeasurePing] ms"][!DisableMeasure MeasurePingResult]
Disabled=1

[MeterPing]
Meter=String
MeasureName=MeasurePing
X=5
Y=5
W=200
H=20
FontColor=255,255,255,255
Text=Ping Test: %1ms
-Brian
User avatar
Yincognito
Rainmeter Sage
Posts: 7333
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG] Ping Measure's FinishAction

Post by Yincognito »

Brian wrote: July 31st, 2023, 4:07 pmSeems to work as designed. You are self-referencing in your FinishAction, so it will always be the previous value. The first time, it will always show "0ms", then it will be previous result.
Really?! :jawdrop :o :jawdrop Well, if you say so, you're the developer... :confused:

But, we regularly "self-referencing" measures in the code, and even a "threaded" measure like WebParser is always providing its most recent value when we do that, in the FinishAction or otherwise, assuming DynamicVariables=1 was set in the right places. I was expecting the same behavior from the Ping measure, since, after all, having the value from one ping request ago (which, if UpdateRate is set to, for example, the equivalent of 1 hour, it would be from 1 hour ago!) is irrelevant to the user, what he's interested in is the latency that the measure just received, as soon as it received it (which is the whole point of a FinishAction in the first place, isn't it?).

Anyway, I'm well aware the Ping measure is a strange one, one of my first posts on the forum were about that, see here and especially here (disregard all the side talk, I was still wrapping my head around the way Rainmeter worked then - apparently I'm still trapped into that process, lol).
Brian wrote: July 31st, 2023, 4:07 pmYou probably need another measure to properly log this. Something like [...]
No need for an additional measure, OnChangeAction would work even if attached to the Ping measure itself. It's the FinishAction that has an ... unexpected behavior here, at least compared to how the same option operates in the rest of the other measures having it, that was my point. :???:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Brian
Developer
Posts: 2696
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: [BUG] Ping Measure's FinishAction

Post by Brian »

Hmmmmm.........

You are right. I initially thought this was a "the measure 's options are parsed when reading the option" type of issue. But I forgot that in actions, bracketed measures should be dynamic. And they are.

The issue here is timing. The FinishAction is firing before the thread sets the plugins internal value. To make matters worse, the measure doesn't retrieve the "new" value from the plugin until the next update.

You can test this by using your test skin and changing the Update value of the skin to something larger, like: [Update 5000]. Even though the ping happens quickly, the value isn't retrieved until after 5 seconds.


So basically, the value within the plugin is retrieved at the right time, but Rainmeter doesn't get that value until the next Update cycle. I'll have to think about this for a bit to figure out the timing. I did find another work around, but it isn't ideal either:

Code: Select all

[Rainmeter]
Update=1000
BackgroundMode=2
SolidColor=0,0,0,255

[MeasurePing]
Measure=Plugin
Plugin=PingPlugin
DestAddress=8.8.8.8
FinishAction=[!Delay 1005][!Log "Finished: [MeasurePing] ms"]

[MeterPing]
Meter=String
MeasureName=MeasurePing
X=5
Y=5
W=200
H=20
FontColor=255,255,255,255
Text=Ping Test: %1ms
I just added a delay that is just a bit longer than the regular Update value of the skin.

-Brian
User avatar
Yincognito
Rainmeter Sage
Posts: 7333
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG] Ping Measure's FinishAction

Post by Yincognito »

EDIT: You basically realized the same thing above, but since I already typed the whole thing below in the meantime, here it is. :D

A clearer picture, both literally and figuratively speaking, of what I mean - a Ping vs WebParser comparison in terms of their FinishAction behavior. I set the UpdateRate on both to 60 seconds aka 1 minute, and they both target the same site, as well as having similar FinishAction, OnChangeAction and DynamicVariables options:

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1
BackgroundMode=2
SolidColor=0,0,0,255

[MeasurePing]
Measure=Plugin
Plugin=PingPlugin
DestAddress=www.google.com
UpdateRate=60
FinishAction=[!Log "Ping Finished: [MeasurePing] ms"]
OnChangeAction=[!Log "Ping Changed: [MeasurePing] ms"]
DynamicVariables=1

[MeasureWebParser]
Measure=WebParser
URL=https://www.google.com
RegExp=(?siU)^(.{15}).*$
StringIndex=1
UpdateRate=60
FinishAction=[!Log "WebParser Finished: [MeasureWebParser]"]
OnChangeAction=[!Log "WebParser Changed: [MeasureWebParser]"]
DynamicVariables=1

[MeterPingWebParser]
Meter=String
MeasureName=MeasurePing
MeasureName2=MeasureWebParser
X=5
Y=5
FontColor=255,255,255,255
Text=Ping Test: %1ms#CRLF#WebParser Test: %2
PingWebParser.jpg
After letting them run for 2 updates, WebParser correctly displayed its self referenced value in the FinishAction, OnChangeAction and the meter (obviously, without the initial change from nothing to something like explained in the manual), while Ping displayed its similar value correctly only in the OnChangeAction and the meter, with the value displayed by the FinishAction being always from the previous update and not its current aka most recent update. Basically, Ping should have displayed its FinishAction at about the same timestamps as its OnChangeAction, but with the value the OnChangeAction displayed, i.e. 37 ms on its 1st "finish" and 28 ms on its 2nd "finish". Instead, it displayed 0 ms the 1st time and 37 ms the 2nd time.

Imagine someone sets his Ping update rate to 3600 aka 1 hour, and loads his skin at 09:00:00 AM. Besides the Ping's OnChangeAction and FinishAction giving conflicting initial values after a couple of moments (the 1st correct, the 2nd wrong, like seen in the screenshot above), that someone would have to wait till 10:00:00 AM... to get his ping value from 9:00:00 AM in the FinishAction (which was received and available for a whole hour in the meantime in the OnChangeAction).

Now, maybe there are some technicalities that make using the correct and most recent value in the FinishAction difficult or impossible for the Ping measure, I won't argue on that, but otherwise this outcome wouldn't look logical and useful to the said person if he was using FinishAction. The whole purpose of FinishAction is to provide the ability to react when a "threaded" measure like this finally gets its value, not to wait till the next finish event to get the measure value from the previous event's occurrence - correct me if I'm wrong. :confused:
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Brian
Developer
Posts: 2696
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: [BUG] Ping Measure's FinishAction

Post by Brian »

So, I have some answers for this...

First, I have the FinishAction firing at the correct time. So, that part of the puzzle is fixed.
Second, I am unable to directly update the measures value with the plugin's value since the correct value is located in the plugin code, not the Rainmeter code. This would require a API change/addition....which might be a good idea at some point. This issue really only affects some plugins that run in a separate thread. As far as I know, this plugin is the only bundled plugin that behaves this way.

However, I can get around the second issue by "force" updating the measure value via calling a bang directly from the plugin (specifically !UpdateMeasure, with the name of the measure). This would happen just after the ping returns and sets the plugin's version of the number value, and just before the FinishAction. Normally I don't like to do things like this, but there is no way around it without changes to the skin code which might not be obvious to the skin author.

So for your example, if I directly force an update, your FinishAction would look like this:
FinishAction=[!Log "Finished: [MeasurePing] ms"][!UpdateMeter MeterPing][!Redraw]

Without the forced update, the FinishAction would need to look like this:
FinishAction=[!UpdateMeasure #CURRENTSECTION#][!Log "Finished: [MeasurePing] ms"][!UpdateMeter MeterPing][!Redraw]

I added the !UpdateMeter and !Redraw to get instant results for the meter.

-Brian
User avatar
Yincognito
Rainmeter Sage
Posts: 7333
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG] Ping Measure's FinishAction

Post by Yincognito »

I see - well, Ping is a strange plugin / measure indeed. :?

Firing the FinishAction at the right time is great news, the other part, well, not so much. The reasons are simple:
- if the user wants to do other things in the OnUpdateAction than in the FinishAction, then having to update the measure in the FinishAction could mess things up in terms of skin functionality, since both sets of bangs would be executed
- as far as I can tell, since the plugin doesn't have a [!CommandMeasure "Update"] thingy, updating the measure in the FinishAction (whether it's done internally or not, unless there is a way to only get the value without actually pinging again) would basically mean the measure will issue another Ping request, so that would be logically inconsistent as well (e.g. which ping would we measure, the one corresponding to this FinishAction or the one we just sent by updating the measure?)
- updating the measure in the FinishAction would, as mentioned above, ping the address again, in turn creating another future FinishAction, which would have to update the measure again, creating a potential endless loop with questionable effects on the skin functionality (again, unless there is a way internally to just get the value via updating the measure, without triggering its actual execution again)

My code isn't that important in this case, as I don't have anything using a Ping measure's FinishAction in my skins and I only noticed this when trying to help another user, so I'm just trying to put myself in the shoes of the regular user for this one. I think the choice you'll make regarding this should consider going for the variant that messes things up the least, so as to be as clear as possible for others.

I was thinking that FinishAction could somehow "steal" the value from the correctly behaving OnChangeAction, but if the approach for the latter is also located in the plugin code, then that's a dead end as well (plus, not sure you could steal the value if it didn't change in the first place, besides the fact that this would be dependend on which event fires first, the OnChange or the Finish one).

Another possibility would be, now that the FinishAction fires at the right time, to have a note in the manual instructing user that if they need bangs to react to the measure value they should use OnChangeAction (assuming they wouldn't want the bangs to be executed if the value stays the same, that is), and if they need bangs to react to the moment when the ping response is received they should use the FinishAction. This wouldn't be the perfect solution either, as there might be some cases that would need to react to both at the same time, but at least wouldn't force anything anywhere.

Of course, there is also the "silent approach" in which we pretend this bug hasn't been discovered yet and that everything is just fine - after all, it's been at least 8 years without anyone but me noticing it, from what I'm aware of. A bit of an "imoral" choice, but it would leave fixing this properly for a time when it would be possible, e.g. a hypothetical update of the Ping plugin or such.

As far as I can tell, it's a difficult choice to make here. The irony is that almost all the other ways of getting or reacting to the value work, just not this one. The OnChangeAction would be the perfect way to provide either the value or the actions that would normally go in the FinishAction, except that it doesn't react when the value stays the same. Getting the right value in the FinishAction via cheating and stealing it from the almost concurrent OnChange action is tricky as well because of that and the possibility that the OnChange event happens after the Finish one, which would make getting the value for the latter by using the former impossible. :???:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Brian
Developer
Posts: 2696
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: [BUG] Ping Measure's FinishAction

Post by Brian »

Actually, forcing an !UpdateMeasure won't do any those things. This wouldn't trigger another new ping depending on the Update and UpdateRate options.

It would only decrease the time until the next ping by 1 update. But...I could also manually adjust for that as well.

OnChangeAction would still only fire once (if it did change) since the change only happens once. Rainmeter tracks and fires the OnChangeAction, not the plugin.

However....an extra OnUpdateAction would still fire, and the plugin can't stop that. This is the only side-effect I can see for forcing Rainmeter to see the results for an option like FinishAction. But the skin author could still do that manually by FinishAction=[!UpdateMeasure #CURRENTSECTION#].... followed but the bangs they want. We might just have to make note of all this in the docs.
Yincognito wrote: August 1st, 2023, 1:00 am Of course, there is also the "silent approach" ...
I'm liking this option A LOT!

In all seriousness, I think I am going to omit the forced !UpdateMeasure given its effect to OnUpdateAction.

-Brian
User avatar
Yincognito
Rainmeter Sage
Posts: 7333
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG] Ping Measure's FinishAction

Post by Yincognito »

Ha! I knew you'd like at least one of the approaches I so viciously presented! Thanks, you made my day! :rolmfao:

No worries, it's your decision - like I always say, the most important thing is that you're now aware of the issue. Solutions come depending on circumstances, and in this particular case, the latter are not that fortunate indeed. :confused:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth