Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objectify doesn't store synchronously, even with now

My servlet should perform the following : when a user registers at a venue, I check whether he's currently registered somewhere (even if it is the same venue) if so, unregister him and to register him once again.

I have the following code, which I've simplified in order to show my problem :

    Date tempDate = new Date();


    Visit v = ofy().load().type(Visit.class)
            .filter(Visit.USER_ID, 5L)
            .filter(Visit.EXIT_DATE, null).first().get();

    if(v != null)
        exitVenue(5L, 7L, tempDate);

    Visit visit = new Visit(5L, 7L, tempDate);      
    ofy().save().entity(visit).now();

    Date tempDate2 = new Date();


    Visit v2 = ofy().load().type(Visit.class)
            .filter(Visit.USER_ID, 5L)
            .filter(Visit.EXIT_DATE, null).first().get();

    if(v2 != null)
        exitVenue(5L, 7L, tempDate2);

    Visit visit2 = new Visit(5L, 7L, tempDate2);        
    ofy().save().entity(visit2).now();
}


public void exitVenue(Long userID, Long venueID, Date exitDate) {

    Visit visit = ofy().load().type(Visit.class)
            .filter(Visit.USER_ID, userID)
            .filter(Visit.VENUE_ID, venueID)
            .filter(Visit.EXIT_DATE, null).first().get();

    if(visit == null){
        log.info("ERROR : User " + userID + " exited venue " + venueID + ", but Visit was not found");
        return;
    }
    visit.setExitDate(exitDate);

    ofy().save().entity(visit).now();
}

the problem is that when I preform all this operation for the second time, it not always finds that there is already a visit in the datastore (every second test, or so). And I'm confused isn't 'now()' suppose to store it right away and only then to continue running ?

Thank you very much for your help, Dan

like image 961
RCB Avatar asked Dec 11 '22 19:12

RCB


1 Answers

This is happening because GAE Datastore is eventually consistent: when you create/update an entity, the method returns immediately, but indexes are still being built asynchronously. Since queries rely on indexes you do not see the changes immediately.

Also, this has nothing to do with objectify - this is a property of the underlying datastore. The synchronous write (.now()) waits for the commit phase to finish , while asynchronous returns immediately even before that.

like image 186
Peter Knego Avatar answered Jan 10 '23 02:01

Peter Knego