Propose an alternative to PathEvent.bubbles to make intent clearer#2223
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughThe PR refactors path-based subscription notification routing by replacing a bubbling-flag approach with ordered candidate paths. ChangesPath Subscription Notification Routing
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| * Candidate paths for surfacing this event to subscriptions. For a given | ||
| * subscription, the first candidate path it covers is used as the path of | ||
| * `event.object` passed to its listener. The caller is responsible for | ||
| * ordering this array so that the preferred path comes first when more |
There was a problem hiding this comment.
I also considered just making the rule be shortest-path-wins, which would achieve the same thing but perhaps not be as clear
There was a problem hiding this comment.
I think letting the caller decide is fine, and we can just write it out explicitly in the caller (_notifyPathSubscriptions) that the intention is to have shortest-path-win semantics
There was a problem hiding this comment.
Have added a comment alluding to this
There was a problem hiding this comment.
From what I can tell, it exists to make sure that if there's a map at path "myMap", and this map emits a LiveMapUpdate having key "myKey", then a subscription that covers the path "myMap" will only receive one event (for "myMap"), as opposed to two (for "myMap" and "myMap.myKey").
If that is the only reason that this mechanism exists
Correct. I like the new approach, no need to have different path notification resolutions based on bubbling, and no concept of bubbling at all. Update just now says "here are all affected paths that subscribers might be interested in, in priority order", and subscribers react to that.
LGTM, with some minor nitpicks below. Also linter has failed
| bubbles: false, | ||
| }); | ||
|
|
||
| // For each subscription, emit at most one event per path-to-this |
There was a problem hiding this comment.
don't think this comment belongs in _notifyPathSubscriptions, it's reads to me more like something PathObjectSubscriptionRegister manages - ensuring that for each subscritpion at most one event per path is emitted
There was a problem hiding this comment.
Yes but PathObjectSubscriptionRegister isn't aware that it's being invoked once for each path-to-this; all that it does is ensure that each subscription emits at most one event per invocation. It's _notifyPathSubscriptions which is responsible for doing one invocation per path-to-this
There was a problem hiding this comment.
Will try making it clearer though
There was a problem hiding this comment.
Tweaked the message
| * ordering this array so that the preferred path comes first when more | ||
| * than one is covered. | ||
| */ | ||
| candidatePaths: Path[]; |
There was a problem hiding this comment.
make it orderedCandidatePaths so it's a bit clearer to the caller
There was a problem hiding this comment.
Called it priorityOrderedCandidatePaths
|
|
||
| { | ||
| description: | ||
| 'PathObject.subscribe() fires once per path when the same object is referenced from multiple paths', |
There was a problem hiding this comment.
I don't know whether the current behaviour is intentional or not, but it
seemed worth writing a test for since Claude told me I'd introduced a
regression of this behaviour when I was trying to do a refactor.
Intentional, if an object is observable from multiple paths then each path should be notified of a change.
It is correct that current Realtime API doesn't allow to end with such a state, but it is possible via REST API atm, and we also discussed before that we may have such a functionality for Realtime - you would pass an Instance to collection set methods (map.set, list.add etc) instead of a ValueType.
Thanks for closing the gap
There was a problem hiding this comment.
Thanks, I've updated the commit message
| * Candidate paths for surfacing this event to subscriptions. For a given | ||
| * subscription, the first candidate path it covers is used as the path of | ||
| * `event.object` passed to its listener. The caller is responsible for | ||
| * ordering this array so that the preferred path comes first when more |
There was a problem hiding this comment.
I think letting the caller decide is fine, and we can just write it out explicitly in the caller (_notifyPathSubscriptions) that the intention is to have shortest-path-win semantics
d3e8b5b to
e454f57
Compare
Claude told me I'd introduced a regression of this behaviour when I was trying to do a refactor. Wasn't initially sure whether it was an intentional behaviour or not, but Andrii has confirmed [1] that it is, so worth a test. [1] #2223 (comment) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
63be5ab to
067102a
Compare
fixed in #2225 |
067102a to
4b8352d
Compare
Claude told me I'd introduced a regression of this behaviour when I was trying to do a refactor. Wasn't initially sure whether it was an intentional behaviour or not, but Andrii has confirmed [1] that it is, so worth a test. [1] #2223 (comment) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4b8352d to
f0238d8
Compare
After noticing that the path-based API spec PR [1] didn't include map-entry events nor the bubbling-exclusion mechanism that's implemented in ably-js, I wanted to get a better understanding of this exclusion mechanism and why it exists. From what I can tell, it exists to make sure that if there's a map at path "myMap", and this map emits a LiveMapUpdate having key "myKey", then a subscription that covers the path "myMap" will only receive one event (for "myMap"), as opposed to two (for "myMap" and "myMap.myKey"). If that _is_ the only reason that this mechanism exists, then I don't think it's very obvious currently; the intended behaviour isn't documented. I think the implementation could be clearer if it makes the rules explicit: - for a given LiveObjectUpdate, a given subscription receives at most one event per path-to-object - in the case where a subscription covers both the "myMap" and "myMap.myKey" paths, "myMap" wins That's what I've tried to do here. Perhaps I've misunderstood the intent of `bubbles` (which, given that the tests still pass, would suggest a test gap), or perhaps others don't find what I'm proposing clearer (in which case, `bubbles` needs better documentation that explains its motivation). Thoughts, please. [1] ably/specification#427 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
f0238d8 to
3abbc4d
Compare
Note: This PR is based on top of #2222.
After noticing that the path-based API spec PR (ably/specification#427) didn't include map-entry events nor the bubbling-exclusion mechanism that's implemented in
ably-js, I wanted to get a better understanding of this exclusion mechanism and why it exists.From what I can tell, it exists to make sure that if there's a map at path "myMap", and this map emits a
LiveMapUpdatehaving key "myKey", then a subscription that covers the path "myMap" will only receive one event (for "myMap"), as opposed to two (for "myMap" and "myMap.myKey").If that is the only reason that this mechanism exists, then I don't think it's very obvious currently; the intended behaviour isn't documented. I think the implementation could be clearer if it makes the rules explicit:
LiveObjectUpdate, a given subscription receives at most one event per path-to-rootThat's what I've tried to do here.
Perhaps I've misunderstood the intent of
bubbles(which, given that the tests still pass, would suggest a test gap), or perhaps others don't find what I'm proposing clearer (in which case,bubblesneeds better documentation that explains its motivation). Thoughts, please.Summary by CodeRabbit
Bug Fixes
Tests