lundi 1 juin 2015

How to handle race-condition in ember-data when live-polling filtered array and saving records

I have an Ember Route that polls for new records every 5 seconds.

Here is the Route's model function:

model: ->
  @store.filter "event", "status": "created", (instance) =>
    instance.get("status") == "created"

Here is the Route's polling mechanism:

setupController: (controller, model) ->
  @_super(controller, model)
  @startPolling() unless @get('polling')

startPolling: ->
  @set('polling', true)
  Ember.run.later @, ->
    @poll()
  , 5000

poll: ->
  return unless @get('polling')
  @model().then =>
    @poller = Ember.run.later @, ->
      @poll()
    , 5000

This functionality works fine except in one scenario.

A user may alter the state attribute of an Event model.

For example, a user can choose to hide an Event instance, which calls the following code:

changeStatusAndDisplayFlash: (event, status) ->
  event.set('status', status)
  event.save().then (event) =>
    @queueFlashMessage(event)

The problem is that if the Events poller is currently making a request and the individual record save promise returns before the poller's request completes, the record will have its state reverted when the poller's request finally does complete.

This is a classic race-condition, however, I am unsure of how to handle this in ember-data.

In short, I'm trying to figure out how to:

Honor the state of a model based on the most recently triggered request rather than the most recently completed request.

So if we have the following requests (in order of when they were initiated):

  1. Original model request which returns the filtered collection.
  2. Polling request that updates the filtered collection (with new models and/or updated attributes to existing models).
  3. Save request that updates the attributes of a single model in the collection.

And the order of completion is such:

1, 3, 2

I would like the outcome of request #3 to be the final result, however, as it stands, the last request to complete (which is currently #2) is the one that sets the outcome.

Does anyone know of a strategy for achieving this in ember/ember-data?

Thank you for your time.




Aucun commentaire:

Enregistrer un commentaire