Git Product home page Git Product logo

Comments (9)

jaime-ez avatar jaime-ez commented on June 14, 2024

Hi, I'm not familiar with codesandbox so I don't know about the details of the platform. I copy pasted the files locally on my computer and run server, then client, then stop and restart server: the client reconnects and continues to be susbscribed as expected and logs the updated values... can you check again? Wasn't able to reproduce the described bug...

from deepstream.io-client-js.

kristofkalocsai avatar kristofkalocsai commented on June 14, 2024

Hi!
Oof, bad news.
Did you prepare the whole project? server, client and dependencies?
Checked again, of course I can reproduce locally, that's where my problems started :)
image
Node version: v18.15.0,
Windows 10
"dependencies": { "@deepstream/client": "6.0.5", "@deepstream/server": "6.2.2" }
Do you have any suggestions where/how can I create a more straightforward env. than the codesandbox?

from deepstream.io-client-js.

jaime-ez avatar jaime-ez commented on June 14, 2024

Ok, I can reproduce the bug only with "dependencies": { "@deepstream/client": "6.0.5", "@deepstream/server": "6.2.2" } when I update the client to v7 there is no bug... can you try again with "dependencies": { "@deepstream/client": "7.0.1", "@deepstream/server": "6.2.2" } ?

from deepstream.io-client-js.

jaime-ez avatar jaime-ez commented on June 14, 2024

I can confirm that client version 7.0.1 fixes the issue, however there are some considerations: what is actually happening is that when using a server without storage, restarting the server actually " deletes" all existing records. Therefore when the client reconnects it thinks that the record was deleted and thus the previous behaviour was to handle the conflict via the merge strategy, since the default merge strstegy is that remote wins, and it thought that remote was deleted, it assumed the record didn't exist anymore and therefore no resubscription was made. This was fixed in in v7 by setting the record as "dirty" when connection is lost.
Let me know if you still have problems

from deepstream.io-client-js.

kristofkalocsai avatar kristofkalocsai commented on June 14, 2024

I can confirm, that for ordinary records, v7 solves this issue, thanks a bunch!

In our case, we'd like to use records with storageExclusionPrefixes, where the issue is still present (if and only if using storage!)
Please see https://codesandbox.io/p/sandbox/recordsubscribereconnect-forked-jg63zb for the source.

Thank you for your continued support!

from deepstream.io-client-js.

jaime-ez avatar jaime-ez commented on June 14, 2024

The problem you're having is due to a race condition between which client logs in first to the server after the restart, and this is more evident when storage is enabled because the server takes longer to start. In your sample code:

const server = new Deepstream(options);
server.start();
// in the following line the client tries to conect inmediately to the server, but the server might not be ready yet,
// thus it triggers a timeout in order to try again in a few milliseconds, 
// and then the producer client might take longer to connect than the consumer depending on when the reconnection is 
// triggered
const dsClient = new DeepstreamClient("ws://127.0.0.1:6020");
await dsClient.login({ username: "producer" });

So if the consumer logs in first, the record won't actually exist yet and the default merge strategy will set it as such.

This is a fix for your sample code:

const server = new Deepstream(options);
server.start();
server.on('started', async () => {
    const dsClient = new DeepstreamClient("ws://localhost:6020");
    await dsClient.login({ username: "producer" });
    // the the rest of the logic...

}

that way the producer will log in inmediately when the server is ready.

And a last note, in your sample code you are a using an upsert method dsClient.record.setDataWithAck that doesn't require to get the record first. Lines 83 and 84 on your server.js file are not necessary when using that method. They are if you set the data as record.setWithAck() check here

from deepstream.io-client-js.

kristofkalocsai avatar kristofkalocsai commented on June 14, 2024

Yes, I indeed took some liberty with my examples, making the producer and the server the same entity.
Take the following example:
https://codesandbox.io/p/sandbox/recordsubscribereconnect-forked-rokwwk
A server and two clients, one is a producer, the other one consumes a record's contents.

According to your response, in case of a server restart, I should somehow guarantee that the producer always reconnects first?
Or implement in every client, that in case of a server drop, after connecting again, acquire new instances of the records which it was subscribed to, and resubscribe?
Or am I in the dark completely? 😀

Please try:

  1. start server
  2. start consumer
  3. start producer
  4. stop producer
  5. stop & immediately restart server
  6. restart producer
  7. correct values, UNSOLICITED_MESSAGE or nothing at all in consumer

from deepstream.io-client-js.

jaime-ez avatar jaime-ez commented on June 14, 2024

The question is, which data you want to preserve? If it is a record that is not saved to storage, you want in case of a server restart to start with an empty record or keep the values the client has?
If you wan't an empty record, you should check in the consumer if the record exists or not before resubscribing, or reset the record also on the client in case of a server drop and that way keep the subscription active. Or another option is to set the merge strategy to LOCAL_WINS for that record like this:

record.setMergeStrategy((localValue, localVersion, remoteValue, remoteVersion, callback) => { callback(null, localValue) })

from deepstream.io-client-js.

jaime-ez avatar jaime-ez commented on June 14, 2024

closing due to inactivity, please reopen if required

from deepstream.io-client-js.

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.