Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add deferred request to models or collections for race condutions #1567

Closed
wants to merge 4 commits into from
Closed

add deferred request to models or collections for race condutions #1567

wants to merge 4 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Aug 21, 2012

About this request

This solves some problems when user interacts backbone rapidly(user click all buttons faster than servers response). This is related to #1325 and #1468. This has some problems.Look at the commits and comments.This pull request is first commit that improving backbone's asynchronous UI feature.

What are you offering Incoming requests?

Backbone offer asynchronous user interfaces but it is not clean when it
comes to rapid model syncing and id generation.Spine offers approximately
similar features, but Spine focus asynchronous interfaces more than backbone.
I do not want to switch to Spine because I was delving deeper to the backbone by
reading annotated source code.After all, I decided to strength asynchronous
UI feature of backbone by whether pulling some requests or writing tiny plug-in

Implementing asynchronous user interfaces

if you create a model then you call Backbone.sync
indirectly, (calling model.fetch,save,destroy collection.fetch,create)
you want to sync with server.Unfortunately there is some problems.

  1. if your model isNew, you cant call Backbone.sync with delete method
    your server is completely unaware this deletion when dealing with your
    update or create methods.
    Thus, client is under the impression that s/he deleted the model,
    but server don't and won't delete.
    SOLUTION: give an id into Backbone.sync on create method.
    probably give cid or guid as a pseudo-id.
    this causes second problem
  2. if your methods cannot reach to the server in their order of sending,
    some race conditions may happen.
    For example, your delete method with pseudo-id is received by server
    before your create method that will turn to the client with real id.
    second example is sending read method with filter A
    then sending read method with filter B. if second read method
    returns to the server first, client see filter A when want to see filter B
    SOLUTION: send all methods one at a time but do this efficiently.
    send one request then defer requests until response. if user send another
    request when there is a deferred request, override previously deferred one
    because user only wants the last change on the model or collection.
    Finally response comes, only change pseudo-id of deferred to the real id
    then send deferred request

NOTE: Look at commit notes for pseudo-codes for solutions

@ghost
Copy link
Author

ghost commented Aug 21, 2012

sorry for my english. if there are some points that you don't understand, I can make these clear

@@ -1387,6 +1399,33 @@
params.processData = false;
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pseudo-code for incoming commits

    // detach update and create. create is like below
    if (!options.data && model && (method === 'create')) {
        // not sending pseudo-id for decoupling from server
        params.data = JSON.stringify(model.toJSON());
        // for calling Backbone.sync with delete method until real id is coming
        model.set({id:model.cid}, {silent:true});
    }

@wookiehangover
Copy link
Collaborator

Why can't you just use the Deferred object that's issued by $.ajax (as the return value for every method that ultimately calls sync)? As long as you're not using Zepto or Ender for your DOM library, you already have a portable, assignable state-object for all server communication... and all the permutations thereof can be managed with logic that's specific to your use-case.

IMO Backbone already does enough by returning the contents of $.ajax from sync...

@braddunbar
Copy link
Collaborator

Hi @namlia, thanks for the patch! Yep, I think the $.ajax deferred object will do. As for how the success and error callbacks are handled, there are several valid ways to handle them which should be left to the user.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants