Skip to content
This repository has been archived by the owner on Apr 7, 2021. It is now read-only.

How should I distinguish when a generared list has recieved an initial value from the server? #88

Open
Iiridayn opened this issue Nov 16, 2016 · 5 comments

Comments

@Iiridayn
Copy link

In our system we make extensive use of generated lists, such as by the rethink search provider. Unfortunately, we sometimes need to be able to distinguish between a default falsey value and an actual generated falsey value - such as to show a "loading" message to the user, or because we generate a lot of data iff it is missing - and we don't know if we've received a reply of false or are only looking at the default value. (Actual current need for the generated data case: find last user week record; if none, set to user's hire date. Show a list of all weeks from last user week record till now.)

Asking on Slack, a user suggested emitting a deepstream event when the calculation is done - while I admit that this is possible, I am uncomfortable treating that as a general solution, much less the official mechanism for the rethink search provider (which we heavily use). There appears to be no reason the deepstream protocol should be changed to support this - the client merely needs to set a flag / emit / whatever when it gets the first value from the deepstream server, to distinguish it from the whenReady event (unless the server is preemptively generating that default value for the client, in which case the rabbit hole goes deeper).

If there is an easy solution, it might be worth documenting it - otherwise, some pointers would be very helpful.

@ronag
Copy link

ronag commented Nov 17, 2016

server:

const resultRecord = ds.record.getRecord(id)
resultRecord.set('result', result)
resultRecord.discard()

client

const resultRecord = ds.record.getRecord(id)
resultRecord.whenReady(() => {
  if (resultRecord.get('result')) {
   // exists
  } else {
    // does not exists
  }
  resultRecord.discard()
})

@yasserf
Copy link
Contributor

yasserf commented Nov 17, 2016

You could theoretically accept the query via the listener only after the query was made which means when hasProvider === true you know the data has been loaded.

The disadvantage of this approach is the listener timeout will need to be big enough to take your query into consideration but tbh, listener timeouts are there incase of worst case scenarios ( badly written providers that end up hanging or unreliable connections )

// client
list.on( 'hasProvider', ( hasProvider ) => {
  if ( hasProvider ) {
     // list is read and populated
  }
}

// provider
record.listen( regex, ( name, response ) => {
  doQuery( (err, data) => {
     if(!err) {
        // set data on list
       response.accept() // this line will set hasProvider to true *after* data is set on list
     }
  })
} )

@Iiridayn
Copy link
Author

@ronag while that would probably work well for a record, I am generating lists, upon which properties cannot be set.
@yasserf that's not a bad approach, I will continue to look into it. If I have multiple instances of the listener in the cluster, would this cause issues? Or does Deepstream send the request to only a single listener at a time, then wait for accept/reject/timeout before trying another?

@yasserf
Copy link
Contributor

yasserf commented Dec 21, 2016

Yeah, that's exactly how it works!

@layanto
Copy link

layanto commented Dec 28, 2016

Will rethinkdb search provider be updated to call response.accept() after providing data? What about the ready event? Is it only emitted when data is available?

@yasserf yasserf transferred this issue from deepstreamIO/deepstream.io-client-js Jun 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants