fix(ec): emit full detail for ECIDs the client hasn't received yet - #857
Merged
mrjimenez merged 1 commit intoJun 5, 2026
Merged
Conversation
…_FILES / GET_DLOAD_QUEUE The EC skip-unchanged opt-in (93a0676 "EC skip-unchanged (4/5)") gates the per-file emit on `m_ecGen <= ec_threshold` in three handlers. For unchanged files the server either emits a childless alive-marker tag (legacy clients) or skips silently (partial-update clients). Both shortcuts assume the client has previously received the ECID with full detail. If it hasn't, the alive marker constructs a ghost CKnownFile from an empty tag (amule-project#810 surface) and the silent skip leaves the file invisible. The CValueMap-driven identity suppression on subsequent emissions extends the surface to INC_UPDATE tags that have children but no identifying fields (amule-project#819 surface). The amulegui-side guards in amule-project#810 and amule-project#819 cover that client specifically. Other legacy EC consumers — amuleweb, amulecmd, and third-party clients — have no analogous guard and silently lose newly-shared files until restart. Fix at the source: track per-connection, per-handler ECIDs that have been sent with full detail. Gate the alive-marker / silent- skip shortcut on membership in that set. Files the client hasn't seen fall through to full-detail emission unconditionally, and the emission populates the per-connection CObjTagMap (so subsequent INC_UPDATE diffs work) and inserts into the new sent-with-detail set. Three handlers, three sets — one per request path because each handler has its own `m_lastEcGenSeen*` cadence. Memory cost: bounded by alive-file ECID count per connection (~360 KB at 91k files; insignificant). Never pruned — re-share bumps m_ecGen via SetFilePath / Init so any resurrected ECID naturally takes the full-detail branch again. The amulegui guards from amule-project#810 and amule-project#819 stay as defensive belt-and- suspenders for amulegui talking to unpatched / older daemons.
got3nks
added a commit
to got3nks/amule
that referenced
this pull request
Jun 7, 2026
…ule-project#912) Extends existing categories (preferring extensions over new lines): - Performance/Upload: amule-project#898 SlotAllocation default raised. - Networking & Discovery: wire-parser hardening list extended with amule-project#879/amule-project#882/amule-project#890/amule-project#886; new amuleweb security hardening bullet consolidating ngosang's amule-project#869-amule-project#874 triage (all landed in amule-project#875); amulegui list extended with amule-project#857; shared-folder watcher extended with amule-project#858. - Packaging: Windows installer i18n line extended with amule-project#899. - Internals & Refactoring: new docs-polish + code-quality bullets covering amule-project#851/amule-project#855/amule-project#862/amule-project#888/amule-project#900/amule-project#866/amule-project#867/amule-project#895 and amule-project#909/amule-project#910/amule-project#912. - Translations: new pre-release final-wave bullet covering amule-project#847/amule-project#856/ amule-project#891/amule-project#908/amule-project#860/amule-project#904/amule-project#859/amule-project#863/amule-project#861/amule-project#880/amule-project#911/amule-project#901/amule-project#902/amule-project#889/amule-project#868/amule-project#853. - Bug Fixes & Stability: amule-project#850/amule-project#854/amule-project#878/amule-project#906. - CI: ccache wiring (amule-project#892, amule-project#903) + CodeQL binutils-dev (amule-project#907). Contributors footer gains mifritscher and nguyenhoangminhhieu2004-gif (both first-time contributors). PR index extended through amule-project#912.
mrjimenez
pushed a commit
that referenced
this pull request
Jun 8, 2026
Extends existing categories (preferring extensions over new lines): - Performance/Upload: #898 SlotAllocation default raised. - Networking & Discovery: wire-parser hardening list extended with #879/#882/#890/#886; new amuleweb security hardening bullet consolidating ngosang's #869-#874 triage (all landed in #875); amulegui list extended with #857; shared-folder watcher extended with #858. - Packaging: Windows installer i18n line extended with #899. - Internals & Refactoring: new docs-polish + code-quality bullets covering #851/#855/#862/#888/#900/#866/#867/#895 and #909/#910/#912. - Translations: new pre-release final-wave bullet covering #847/#856/ #891/#908/#860/#904/#859/#863/#861/#880/#911/#901/#902/#889/#868/#853. - Bug Fixes & Stability: #850/#854/#878/#906. - CI: ccache wiring (#892, #903) + CodeQL binutils-dev (#907). Contributors footer gains mifritscher and nguyenhoangminhhieu2004-gif (both first-time contributors). PR index extended through #912.
mrjimenez
pushed a commit
to mrjimenez/amule
that referenced
this pull request
Aug 8, 2026
…st (amule-project#857) Two gaps in the comments/ratings dialog, plus one piece of dead code found alongside them. The sort caret went with amule-project#855's downgrade from CMuleListCtrl to a plain wxListCtrl, which tracks no sort state of its own; ShowSortIndicator() drives the glyph explicitly, and all three ports draw it -- macOS and GTK through the generic implementation, Windows through wxMSW's override. The rating smiley was never there, on master either: the column has always been GetRateString() text alone while every other list showing a rating draws the icon beside it. The images are already in the app's shared list, so it needs SetImageList() plus a per-row SetItemColumnImage(). Borrowed rather than assigned, so this modal does not delete the app's list on close. Unrated rows stay blank rather than drawing a "not rated" glyph on each one. The cell also fell back to an untranslated "on" for a rating of -1, which cannot occur: the wire value is a uint8 and CUpDownClient clamps anything above 5 to 0, so the range is 0..5 with 0 meaning a comment carrying no rating.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Server-side fix for the #808 ghost-entry bug class. Where the partial-update opt-in's
m_ecGen <= ec_thresholdshortcut produces either a childless alive-marker (legacy clients) or a silent skip (partial-update clients), gate the shortcut on whether the client has previously received the ECID with full detail. If not, fall through to full-detail emission.Why
PR #810 and #819 fixed two surfaces of the same bug in
amulegui— childless alive-markers andCValueMap-suppressed identity tags both produced 0-byte unnamed ghost entries when amulegui hadn't yet received the file's metadata. Both fixes are amulegui-side guards.Other EC consumers —
amulewebandamulecmd, both of which advertiseEC_TAG_CAN_PARTIAL_UPDATEviaCRemoteConnectand so sit on the partial-update silent-skip path, plus genuinely-legacy third-party clients that don't advertise the tag and hit the childless alive-marker path — have no analogous guard. Both variants of the shortcut produce a file the client never gets metadata for: silent absence in partial-update mode, empty cache entry in legacy mode. They lose newly-shared files until restart, with intermittent symptoms depending on when their poll cycle aligns with the daemon'sm_ecGenaccounting and whichCValueMapcache state the server happens to be in.Fixing at the daemon ends the per-client patch treadmill and restores the invariant that any tag the server emits carries enough metadata for the client to construct the entry.
What
Three handlers in
src/ExternalConn.cpp:Get_EC_Response_GetUpdate— covers both legacy alive-marker and partial-update silent-skip pathsGet_EC_Response_GetSharedFiles— partial-update silent-skip pathGet_EC_Response_GetDownloadQueue— partial-update silent-skip pathEach takes an additional
std::set<uint32> &io_sentWithDetailIdsand only takes the shortcut ifio_sentWithDetailIds.count(ecid)is true. When the shortcut is skipped (first-sight ECID) the handler falls through to full-detail emission and inserts the ECID into the set.Three corresponding
std::set<uint32>fields onCECServerSocket— one per request path because each handler has its ownm_lastEcGenSeen*cadence.Cost
Bounded by alive-file ECID count per connection. ~360 KB at 91k shared files; immaterial vs. existing per-connection encoder +
CObjTagMapstate. The set is never pruned — re-share bumpsm_ecGenviaSetFilePath/Initso any resurrected ECID naturally takes the full-detail branch on its first post-resurrection cycle.Refs #808 #810 #819