fix(web): button, float init timer cleanup#7036
Conversation
User Test ResultsTest specification and instructions User tests are not required Test Artifacts
|
mcdurdin
left a comment
There was a problem hiding this comment.
I don't see any real problems, but I am not sure why the loaduserinterface callback was removed?
web/source/kmwuibutton.ts
Outdated
| { | ||
| window.setTimeout(ui.Initialize,250); return; | ||
| if(!keymanweb['initialized']) { | ||
| ui.initTimer = window.setTimeout(ui.Initialize,250); |
There was a problem hiding this comment.
I see this has a timeout of 250 whereas the other init has a timeout of 50. I can't see any good reason to keep this at 250. I reckon 50 is better -- polling every 50msec until init won't be very expensive.
There was a problem hiding this comment.
Just re-read this; it looks like you're thinking of setInterval, rather than setTimeout. setInterval does polling; setTimeout is a one-time check.
I could go the setInterval route, but then I'd need to ignore your comments below about where to place clearTimeout - we should only clear it once we're confirmed to be initializing.
All of that said, I think we can probably just remove the timeout stuff altogether and be done with it; the Toggle and Toolbar UI modules don't set one and seem to load just as well. I just... was going for the less drastic change here.
There was a problem hiding this comment.
Imagine this is called twice before keymanweb.initialized. This would setup two timeouts -- we'd lose the id for the first timeout. (e.g. on the third call, keymanweb.initialized==true. First timeout would not be cancelled, so we'd get a second init call. It may not matter, but it isn't tidy.)
There was a problem hiding this comment.
Okay, so that's a gap in the code as it sits, but that doesn't exactly answer the "polling" / setInterval vs setTimeout question. Unless you were thinking of the 'second timeout' as something akin to a 'polling' call - but that feels like a bit much of an inference to make without clearer confirmation.
There was a problem hiding this comment.
I'm thinking of setTimeout in the circumstance where this init function is called multiple times. Not setInterval. If you do this, you'll get two calls to bar():
function bar() {
console.log('bar');
}
function foo() {
window.setTimeout(bar, 100);
}
foo();
foo();
There was a problem hiding this comment.
polling every 50msec until init won't be very expensive.
Consider that this currently sets up a timeout every 250msec. So, it's effectively 'polling'.
| "} "; | ||
|
|
||
| // Initialize after KMW is fully initialized, if UI already loaded | ||
| keymanweb['addEventListener']('loaduserinterface',ui.Initialize); |
There was a problem hiding this comment.
What's the reason for removing this?
There was a problem hiding this comment.
I'd tried a project-wide search for the event and turned up nothing. Probably shouldn't have tried the search with quotes, though - the related events are defined at the bottom of kmwuimanager.ts. Interestingly, it doesn't look like eliminating 'em caused any issues - and the functions that trigger them are even marked with an interesting tidbit:
keyman/web/source/kmwuimanager.ts
Lines 44 to 54 in 0a22acd
Note line 49 there. That comment does seem to ring true - a project-wide search for doLoad( turns up... nothing else aside from a function in Developer's Pascal code.
There was a problem hiding this comment.
OK, if that's the case, can we remove doLoad() as well so we don't have this vestigial code hanging around?
|
... and the child PR (#7037) had a test failure that I thought this one would've fixed. Looks like there may be another aspect or two to investigate. |
|
With the latest commit, I've re-run the test suite multiple times and no longer see the test failure that sent this back to draft. 4 successes on one build agent, 2 on another. I'm trying to verify this for the build agent (pp-602) that actually produced that error as well, but it's having trouble actually getting the full test suite to run at this time. |
|
... Huh. Build agent |
I've just checked the browserstack-local executable version on both Windows agents and they appear to be identical. That said, the version available for download from browserstack.com differs (it's a different file size even though the file version is the same?!) I can back up the existing executables on the agents and replace with the new version from the downloads site. Don't know if that will make a difference or not, of course; suspect not. UPDATE: we have version 8.6 (metadata on the executable is wrong -- reported to BrowserStack). The latest version is 8.7. Given that, I will update the version on the build agents once my test builds finish running. Here's what I am seeing for the web test build history. I am not seeing the same correlation that you report. It's possible that there are odd real failing tests in this log but most of these builds have no web changes. And the same log for LM layer. Again, I don't see a real correlation between agent and failing build. |
|
I'm going to re-run the build for the latest commit on this PR on all agents and see what emerges. Results:
LMLayer:
|
mcdurdin
left a comment
There was a problem hiding this comment.
Looking pretty good. Just a bit more polish on the timer cleanup needed.
Curious that the toolbar ui doesn't have the same initialization pattern.
Looking at the UI code, I think it needs some serious TLC one day!
web/source/kmwuibutton.ts
Outdated
| // While the `ui.init` check above will prevent the timeout's call from | ||
| // re-evaluating _this instance_'s method, it can have nasty cross-effects | ||
| // in unit testing if not cleared, calling this modules' `Initialize` | ||
| // _on a different module_! | ||
| window.clearTimeout(ui.initTimer); |
There was a problem hiding this comment.
This should be at the top of the function and we should not call clearTimeout if ui.initTimer === null:
if(ui.initTimer !== null) {
window.clearTimeout(ui.initTimer);
ui.initTimer = null;
}
| "} "; | ||
|
|
||
| // Initialize after KMW is fully initialized, if UI already loaded | ||
| keymanweb['addEventListener']('loaduserinterface',ui.Initialize); |
There was a problem hiding this comment.
OK, if that's the case, can we remove doLoad() as well so we don't have this vestigial code hanging around?
web/source/kmwuifloat.ts
Outdated
| } | ||
|
|
||
| if(ui.initialized || util['isTouchDevice']()) return; | ||
| window.clearTimeout(ui.initTimer); |
There was a problem hiding this comment.
This should be at the top of the function, like this:
if(ui.initTimer !== null) {
window.clearTimeout(ui.initTimer);
ui.initTimer = null;
}
Version 8.7 made no difference. So ... pp_602 has a slightly different performance profile than s1_601, so perhaps there's still another race somewhere? |
Unfortunately, those images are irrelevant. Please remember that this PR is making other changes that fix issues underlying what you've observed here. In my test runs so far, this PR fully stabilizes KMW test builds for all agents but
That looks like the "same correlation" to me. Note the lower "tests passed" number (and in the case of the first set, the lower 'ignored' number) and the fact that no tests were marked as failing. Those are the hallmark symptoms of that BrowserStack "failure to capture" problem. |
Even if "we" do, it's wholly external to our code. Our unit tests aren't even "spun up" at that level. |
Righto. Where we are at now, we still have unstable tests. That's not... great. Any suggestions on where to go now? pp-602 and s1-601 are essentially identical VMs in the same datacenter. So it's hard to see what could be causing this. I mean, I can temporarily disable KeymanWeb and Common-LMLayer building on pp-602 but that's going to slow down builds and obviously isn't really a 'solution' so much as a bandaid. |
Co-authored-by: Marc Durdin <marc@durdin.net>
|
Changes in this pull request will be available for download in Keyman version 16.0.48-alpha |


Cleans up some code that's proving problematic for some of our unit tests; there's some cross-UI-module pollution happening on occasion that turns into a race condition of sorts.
@keymanapp-test-bot skip