Implement "Verify Local Data" function (EC/amuled/amulegui) - #491
Conversation
|
Reviewed and built all three variants (monolithic, daemon, amulegui) — clean follow-up to #381 overall. The One thing worth simplifying before merge: the daemon handler routes through the GUI-notify layer ( case EC_OP_VERIFY_LOCAL_DATA: {
CMD4Hash hash = request->GetTagByNameSafe(EC_TAG_KNOWNFILE)->GetMD4Data();
CKnownFile *file = theApp->sharedfiles->GetFileByID(hash);
if (file)
theApp->sharedfiles->VerifyLocalData(file);
response = new CECPacket(EC_OP_NOOP);
break;
}That lets you drop (The Everything else looks good — just that one simplification and it's good to merge. |
70eccd8 to
bcadd89
Compare
|
Simplification looks perfect — merged. Thanks for the quick turnaround! |
|
Thanks for the review! Since you are the expert of amuleapi, can I let you handle the development of this function there (if you wish to have it there, of course)? |
|
Thanks @danim7 — I took the amuleapi side, it's up as #528: Two things worth flagging that came out of building it. First, Verify Local Data currently has no way to return its result to any client. Second, it's gated to completed files only — the task bails on So the natural follow-up is result handling in the UI plus the EC protocol — a completion notification off the task, an EC event carrying the per-file verdict (corrupt MD4 parts / AICH blocks), and the clients surfacing that instead of leaving users to read the log — with partfile support alongside it. Since you implemented the feature, would you want to drive that part? I'll wire up the amuleapi and SSE side once the EC event exists. |
|
Thanks for integrating this functionality @got3nks. Concerning the following steps, I must say I have some open questions because i'm not 100% convinced on what is the best approach now, specially on the UI. Maybe I could open a fresh new issue for discussion. The next steps could be:
After writting all of the above, I want to take a minute to look at the bigger picture:
My take:
Your thoughts? |
|
On the persistence/recovery design — I think we can lean much harder on what already exists for downloads rather than build a parallel path for shared files. The partfile engine already does exactly this: when a part fails its hash it's marked corrupt ( So instead of storing corrupt-block lists in
The GUI mostly falls out too: the file just appears in the transfer window as a download for the corrupt parts, so we don't strictly need a new column/details area to start. And partfiles are even simpler — they already carry The one genuinely new piece is a clean "un-complete" path: turning a shared One thing worth deciding up front, though: whether we recover into a copy or invalidate the shared file in place. Converting in place is risky if the file has no sources — we'd leave it stuck as an incompletable partfile, and the user's complete-but-slightly-corrupt copy can't return to Incoming without the missing parts. Recovering into a separate partfile and only swapping the original once the good copy finishes is safer: a sourceless or failed recovery just leaves the original intact and still shared. The cost is temporary extra disk — or we gate the in-place convert on actually finding sources first. |
|
One more on the UI side: right now Verify Local Data has no user feedback at all — While a check runs we could reuse an existing status rather than invent one — it's effectively a re-hash, so |
|
Thanks for your detailed answer. It contains a lot of valuable information on how to continue developing this feature. Just one question: if I'm understanding your comment right, the recovery workflow is automatically initiated if the "verify local data" finds any corruption? It is not really what I had in mind: if I identify a wrong file, maybe I have a backup somewhere else, and I don't need to download it from the network. Or maybe I had an issue with my disk/filesystem, I run a test on the whole library, but I don't want it to automatically add hundreds of files to download in case they are wrong. That's is why I wanted to separate the check from the recover.
If we take this approach, I think we shall recover into a copy, so the user can still access the complete-but-slightly-corrupt file he has. He can always delete the file if he doesn't want to pay the temporary extra disk cost. The hashing progress from your second comment seems like a nice addition. I may begin with that point while I try to think of a convincing UI/UX (maybe 2 options: one for verify-only, one for verify+fix...?). |
|
Good — separating the check from the recovery is the right call, and it changes the design in a way I think is cleaner. Let me lay out where I've landed. The verdict lives on the shared file, persisted. A verify run records its result on the Surfacing it in the Shared Files view. Note the existing amuled becomes aware of corrupted shared files. This is the key consequence of keeping the file complete-and-shared instead of auto-converting it: the upload path has to consult the persisted corrupt-part list and refuse to serve those parts (still happily serving the good ones). In the auto-convert design that fell out for free — a partfile just doesn't advertise its gaps — but here we suppress the bad parts explicitly from the same list we persisted. Net effect is the same (no corrupt data goes out), without pulling the file out of the share. Recovery is a separate, explicit action. A context-menu entry — "Recover corrupted parts" — enabled only when the file is flagged corrupt. It hands the file to the existing partfile engine, recovering into a copy: good parts kept complete, corrupt parts marked as gaps, then the normal Temp → Incoming flow re-fetches only the bad parts (with AICH recovering individual blocks where we trust a MasterHash). The original complete-but-corrupt file stays intact and shared until the good copy finishes, so a sourceless or failed recovery costs nothing but the click. This is your verify-only-vs-verify+fix split, made concrete: Verify only ever marks; fixing is always a deliberate second step, per file. So the flow end to end: Verify marks + persists + suppresses the bad parts from upload; the shared view shows the flag; the user decides, per file, whether to Recover, which spins up a clean copy via the engine we already have. Sequencing-wise I agree with your priorities — NAT-T and the next release come first; this proceeds in the background. The hashing-progress indicator you mentioned starting with is a good standalone first step (it just needs wiring into the shared view too, since that's where the file sits during the check). Partfile support and the EC/amuleapi/SSE surface come after the monolithic path works. |
|
I like this design, thanks for the feedback. Will try to do it at some point if I find time :) |
Follow-up to #381
Implement a new OP code in EC protocol: EC_OP_VERIFY_LOCAL_DATA. It instructs the daemon to verify the local data of a given file.
The daemon launches the same thread as in #381 that checks the file and prints the result to the log.
On amulegui, the result can be checked in the log.
Tests: