Giter Site home page Giter Site logo

Comments (14)

mattheworiordan avatar mattheworiordan commented on July 20, 2024 1

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.

mattheworiordan avatar mattheworiordan commented on July 20, 2024

@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.

⚠️ Note I got a lot of this wrong. The SDKs do in fact emit enter, leave and update events correctly, as defined in https://sdk.ably.com/builds/ably/specification/main/features/#RTP2g, so a lot of below is wrong ⚠️

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.

sacOO7 avatar sacOO7 commented on July 20, 2024

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.

mattheworiordan avatar mattheworiordan commented on July 20, 2024

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.

sacOO7 avatar sacOO7 commented on July 20, 2024

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.

mattheworiordan avatar mattheworiordan commented on July 20, 2024

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.

sacOO7 avatar sacOO7 commented on July 20, 2024

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.

mattheworiordan avatar mattheworiordan commented on July 20, 2024

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.

sacOO7 avatar sacOO7 commented on July 20, 2024

Yeah, introducing any breaking/non-breaking change that can make it easier for users to subscribe to changed members 👍

from docs.

SimonWoolf avatar SimonWoolf commented on July 20, 2024

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.

mattheworiordan avatar mattheworiordan commented on July 20, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.