Comments (14)
The main reason the above code is broken is that it assumes the presence set is uniquified by clientId, which it isn't, it's uniquified by clientId+connectionId
That's the main reason, but not the only reason. The former is easy to explain to a developers and they can reason about (users can be present more than once with different connection IDs), but the latter is much harder (enter events don't necessarily mean the user has entered because a leave event can arrive after but with an earlier timestamp). I think we should fix that latter problem in our SDK API because emitting the raw protocol events is not the API a developer would expect to see. We should have an abstraction over our underlying protocol instead of exposing it. That's not a big change (and requires not realtime system changes), but would materially reduce the likelihood of developers mistakenly using this API. WDYT?
from docs.
@paddybyers @SimonWoolf @owenpearson @ttypic I was just looking at that presence code again, and it got me thinking about whether this is a documentation issue, or in fact an SDK / API issue.
Right now, SDKs emit the raw protocol message presence events for enter
, leave
, update
(and sync
), which is where the problem lies. There is not really any good reason for us to emit these raw events from a consumer of the API's perspective. Our raw protocol messages are not all that useful to customers given they need to understand that messages can arrive out of order and they need to understand how to apply CRDT-like logic to get the intended result set
If we focus on what the customer would want instead of how this works internally, I would change things as following:
We only ever emit enter, leave, and update events in a way that makes sense to the consuming user i.e. if they wrote code like above, it would work- We include an argument in the callback with a reference to the complete presence set anyway to encourage developers to use that when they need the entire presence set as opposed to knowing what has changed
WDYT?
from docs.
This seems to be a react example. where they want to update the view when the dataset changes.
More specifically, they want to get updated
data set whenever any change to the dataset happens.
I think get
only returns a snapshot of members at a particular moment.
That said, laravel-echo
devs exposed minimum required methods for presence.
https://github.com/laravel/echo/blob/master/src/channel/presence-channel.ts#L10
In the Echo.join().here(members => {}) implementation, the callback is called with updated members when a new member joins, updates, or leaves the channel.
To expose this we had to update the code in ably laravel echo fork =>
https://github.com/ably-forks/laravel-echo/blob/cee1b7b51196dfab9f56bc95d5deb5880eb5411d/src/channel/ably-presence-channel.ts#L27-L35
here(callback: Function): AblyPresenceChannel {
this.channel.presence.subscribe(['enter', 'update', 'leave'], () =>
this.channel.presence.get((err, members) =>
callback(members.map(({data}) => data), err)
)
);
return this;
}
from docs.
I think get only returns a snapshot of members at a particular moment.
Yup, why's that an issue?
To expose this we had to update the code in ably laravel echo fork =>
Yup, and it just calls presence.get
which IS the recommended behaviour because trying to build your own presence set from the events is painfully difficult and error prone.
from docs.
I think it will be better if we can just expose a method like here
to avoid adding complex documentation in all SDK's : (
from docs.
I think it will be better if we can just expose a method like here to avoid adding complex documentation in all SDK's : (
here
=> get
though? I don't follow
Or do you mean an equivalent here_now
callback? If so, that's what I'm loosely proposing above.. although perhaps we could go with an event / method name that is painfully simple
from docs.
Almost all of the mobile/web UI frameworks update components based on state change, so we expose a method on presence
channel like
channel.presence.onMembersUpdated( updatedMembers => {
})
instead of them doing
// This can get complex based on each SDK api style
this.channel.presence.subscribe(['enter', 'update', 'leave'], () =>
this.channel.presence.get((err, members) =>
callback(members.map(({data}) => data), err)
)
);
from docs.
FWIW. My thinking on my comment:
We include an argument in the callback with a reference to the complete presence set anyway to encourage developers to use that when they need the entire presence set as opposed to knowing what has changed
Was that we could introduce a change potentially that is not breaking as follows:
channel.presence.subscribe(function(member, allMembers) {
console.log(member.data); // => the user who has entered, left, etc
console.log(allMembers); // => the presence set from `presence.get`
});
from docs.
Yeah, introducing any breaking/non-breaking change that can make it easier for users to subscribe to changed members 👍
from docs.
We do document this: https://ably.com/docs/best-practice-guide#use-existing-presence-set . I know because I wrote most of that entry. The problem is that it's in the best practice guide, which is hard to discover and no-one ever reads. The solution is to move it into the normal presence docs, which is a change that was agreed some time ago.
We only ever emit enter, leave, and update events in a way that makes sense to the consuming user i.e. if they wrote code like above, it would work.
The main reason the above code is broken is that it assumes the presence set is uniquified by clientId, which it isn't, it's uniquified by clientId+connectionId. This is not a thing we can change just with a client library api change, it would require a completely different presence model, client and serverside. I don't think this is a change it would be sensible to make at this point, to put it mildly.
We include an argument in the callback with a reference to the complete presence set anyway to encourage developers to use that when they need the entire presence set as opposed to knowing what has changed
Sure, no objection to this. Trivial and backwards-compatible change for ably-js.
from docs.
Apologies for the noise in this issue (I made a mistake). I've corrected my first follow on comment
Saying all that, I do think we should:
- Improve the docs, as mentioned by @SimonWoolf
- We should include the presence set in the presence event callback, as suggested in #2073 (comment)
from docs.
Related Issues (20)
- Add how-to guide for using Netlify template HOT 3
- Document extras.headers attributes HOT 12
- History 'next' returns undefined in js not null
- Documentation renders `"*\":[\` as `<a href="[\">*\</a>`
- Connection.errorReason displays an incomplete sentence
- Anchor links embed language - is this intentional?
- Document `routingKey` interpolation somewhere more prominently
- State Persistence docs
- Authentication Capabilities Title is cropped HOT 1
- testing gh jira int
- jira -gh int test
- Authentication Capabilities Title is cropped HOT 1
- Add CNAME update example for ClientOptions in platform customisations HOT 1
- Add note to channel namespaces about not explicitly defining them
- Missing example PHP code - Javascript leakage to PHP docs HOT 2
- Add note to MQTT (Python) tutorial stating unix-only
- Tutorial on Java authentication doesn't work HOT 1
- Message type does not list all supported values for extras HOT 1
- Document batch publish/presence and token revocation
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from docs.