-
Notifications
You must be signed in to change notification settings - Fork 210
Fix: not all signature images are uploaded in offline-capable forms #373
Fix: not all signature images are uploaded in offline-capable forms #373
Conversation
Hi @eyelidlessness, thanks for working on this. I have some questions about the code, but before getting into that, did you plan on changing the 1500 ms delay in enketo-core to complement this PR? When testing this change alone in the browser, I still observed data loss when clicking submit less than 1500ms after ending the last stroke in a signature widget. Although it's not useful for multi-stroke signatures, a quick visual indicator as to whether or not the signature would be included in the submission was whether or not the download icon appeared: |
Oof, in hindsight this is totally unsurprising! That's what I get for testing with a 5000ms timer for convenience. I'll probably want to sleep on this, but my gut instinct right now is:
Longer term, I think it's worth looking at how libraries designed for consistent, concurrent state management and rendering handle this. (Or, just using one.) Like I said in the issue tracking this bug, I'm expecting there are more issues like this we haven't discovered yet. |
519d0f9
to
ff7df0b
Compare
@jnm I've pushed up a much smaller, simpler solution (though unfortunately without automated tests). I've also removed the delay here, because I found it's unnecessary. Part of the reason it took so long to get here is that, while I thought was able to verify data loss as you described with the previous change, I had forgotten that Enketo caches the offline script and does not (currently) invalidate that cache for dev changes (because it's cached based on the version number). So I was actually verifying it against a different build, from a different branch I'd worked on in the meantime. This is an issue I intend to fix next, because it's been a frequent source of false positives/negatives and time lost. Anyway, I bring this up because I suspect this may be why you continued to see data loss as well. With these changes (as with the previous approach), I was able to verify successful submission even with the enketo-core delay extended well past submission. The reason this works (even after removing the delay here) is:
All of that said, you should be able to verify this by ensuring the offline cache is up to date. There are two ways to do that:
|
The reasoning here seems sound to me. Let’s give @jnm a day or two to chime in and if he doesn’t I’ll do a deeper review and we can decide whether or not to release with it. |
Catching up here now. Thanks for your patience! |
Aha, the reason I could (and still can) reproduce data loss within the 1500-ms enketo-core delay interval is that I'm using a touchscreen on a desktop browser 🙃 The // This event does not fire on touchscreens for which we use the .hide-canvas-btn click
// to do the same thing. I'm happy to confirm that with the 500-ms delay removed, I can no longer reproduce any signature data loss with a mouse, nor can I reproduce it using touch on an Android phone. 🎉 My only remaining question: is the locking around
I see that both |
Also, I'm in favor of releasing a change that removes some risk of data loss, even if it doesn't cover touch on a desktop browser. Sorry to have not made that clear in my last post. I think that's a fairly rare use case so far(?) or at least none of these reports reference that scenario:
I tried to reproduce data loss after simply removing the 500 ms delay (and not adding any locking around
|
@jnm thank you for the detail around touch, that definitely explains why you're still seeing data loss in that case. While it may seem like a rare use case, I can easily imagine this being an issue on tablets/larger form factor touch devices in general. So I'm thinking about next steps on how to address that.
Unfortunately it is necessary without other changes (more on that below). Without locking (or, alternatively, awaiting a potentially redundant call to
According to the comment there (and I can confirm), this is to ensure that any unchanged files which were populated from a previous auto-saved record are included when queueing the record for submission. This is also the case when submitting a previously saved draft. I've investigated changing the way this works, to use only the current state of the record. I would like to make that change, but I've found it difficult to follow all of the data flow in order to find a coherent way to make that change. As far as I can tell, that data flow goes through at least:
I decided to prioritize getting this simpler (albeit incomplete) fix through, and investigate a more holistic change to simplify and (hopefully) unify that flow later on.
Just checking out of an abundance of caution: are you sure that the offline script was updated after you made that change? Until #382 (or something like it) lands, the caching issue I described above applies for every change made in dev. I can imagine it becomes much harder to trigger that data loss (with a mouse or on a touchscreen phone) by removing the delay, but because |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Punch list for myself of things to actually test:
- Named drafts
- Auto-saved drafts
- Encrypted forms
- Named drafts
- Auto-saved drafts
That's quite eye-opening, thanks! Knowing that now, I'm surprised
…but perhaps the rationale is lost to history. In any case, I certainly recognize now why you've proposed this locking and fully agree that it's necessary. Thanks also for emphasizing the caching pitfall. I feel confident that I'm running the intended code because I'm starting a factory-fresh browser with a temporary home directory each time I test a new revision. It's likely not cross-platform, but in case you're curious, I'm using this bash function: tmpchrome ()
{
td=$(mktemp --tmpdir --directory tmpchrome.XXX);
mkdir -p "$td/.config/google-chrome";
touch "$td/.config/google-chrome/First Run";
HOME="$td" google-chrome "$@";
rm -r "$td"
} I added a few questions to the code in review form. Thank you again 🙏 |
- No longer assigns `null` to `autoSavePromise` - Auto-save locks/waits on its previously assigned promise directly, so outside calls to it do not need to `await` it implicitly
@jnm Thank you for taking time to review! I've addressed your questions. I also:
We're hoping to include this in the pending #384 3.0.5 release, would you mind taking another look to see if these changes look good? |
@yanokwa can we get this branch on the QA server, please? We can do a quick round with it before merging and releasing. |
QA server now has this change in -FROM ghcr.io/enketo/enketo-express:3.0.4
+FROM ghcr.io/eyelidlessness/enketo-express:fix-339-signatures-data-loss |
I tested a variety of scenarios and everything looked good 🚀 I did encounter enketo/enketo#1023 ( |
Thanks so much for the careful follow-up here, @jnm!! Similar results from QA -- looks like they also ran into enketo/enketo#1023. |
Closes enketo/enketo#1043.
The details of the bug are described in more depth here.
I'm really not sure what the actual name of this solution should be (please feel free to bikeshed it), but this is how it works:
Promise
, which acts as a lock, blocking the request togetCurrentFiles
when saving an offline record, ensuring signatures are auto-saved before the record is saveddelay
only execute the last call if prior timers have not completeddelay
where prior timers have completed blockwait
until they all resolve.I have verified this PR works with
[ ] Editing submissions[ ] Form previewWhat else has been done to verify that this works as intended?
Manual testing, with a particularly long delay and a lot of logging to be sure the claims I made above are true.
Why is this the best possible solution? Were any other approaches considered?
It's probably not the best solution, see discussion of that in the comment linked above.
How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?
Locks are hard, this might deadlock in ways I haven't thought about.
Do we need any specific form for testing your changes? If so, please attach one.
See enketo/enketo#1043.