I am developing a GAE web application and I need to create and remove associations among instances of two Entities which have no ancestor relationship (also consider the same instance may have multiple associations that may vary in time while the ancestor relationship, once created, can't be removed). I have experienced the 'eventual consistency' policy which means data in my web page are not refreshed coherently with the relationships I am creating/removing. However I have seen that by executing the put() method twice the consistency seems to be force.
This is compliant with the "Eventual Consistency" definition which states that "... provided no new updates are made ..." data will eventually be consistent and, since I am making another update (actually the same two times) I guess the system forces the consistency.
Am I right? Is there any other more elegant way of doing it?
Update: My AIM
Consider I have a list of entities of type A, it doesn't matter what they actually represent, let's say they represent the main entities of my business I have a list of another entities of type B representing services the entities of type A can rely on. it is a many to many relationship so A service b can be used by many entities a of type A An entity a can be served by many services b of type B
I have a web page allowing me to create such relationship, (a Jinja2 template with a Jquery Ajax callback from the client side and a webapp2 python request handler relying on the datastore in the server side). When a relationship is removed from the datastore I refresh the data by making another query on the a entity and depicting the list of b keys it has related. In this case I still see the removed b.key in the list of b keys related to a. Which is not what I would expect.
UPDATE: SOME CODE
here is the model
class A(ndb.Model):
name = ndb.StringProperty()
services = ndb.KeyProperty(repeated=True)
class B(ndb.Model):
name = ndb.StringProperty()
servedEntities = ndb.KeyProperty(repeated=True)
here is the code I use to create the relationship
a.services.append(b.key);
b.servedEntities.append(a.key);
a.put()
b.put()
here is the code I use to remove the relationship
a.services.remove(b.key);
b.servedEntities.remove(a.key);
a.put()
b.put()
There is no ancestor relationship between a and b (and there can not be) After the relationship removal I if retrieve again a from the Datastore I can still see b.key listed in a.services
The answer to your question lies in this statement:
Why do you need a new query?
Let's say a user subscribed to services x, y and z. Now a user tells you to drop service z from the list. You go to the Datastore and make the necessary change. Instead of running a new query, however, which may still show z among the returned entities, you can simply remove z from your user entity on the client side and update the UI accordingly.
This is obviously a simplified example. I faced a similar challenge when I wrote the school scheduling app, which had a more complex use case - a single change may affect many entities in the selected time period (e.g. "schedule a lesson every school day until the end of the quarter"), so I was tempted to simply run a new query to refresh the schedule view. Obviously, I ran into the eventual consistency problem magnified by the fact that sometimes dozens of entities had to be created. Then I realized that I already have all the data that I need to refresh the view without running a new query. It's a bit more code, but it's a clean and reliable solution.