In one of my object I needed a sequence I would use to increment an Id field just like we often do with classical databases. As I have not found a suitable solution, I wrote one. This solution uses objectify.
The first approach I came with was to have a class with a static AtomicInteger field like this:
public class MySequence {
static AtomicInteger sequence = new AtomicInteger(0);
}
I would then just call it each time I need it.
Problem:
Every time the server is restarted, the sequence is too. So we need to persist the last value.
Second approach:
Persist the last value with objectify:
public class MySequence {
private static AtomicInteger sequence = new AtomicInteger(0);
private static List<PersistSequence> l = null;
private static PersistSequence newPs = null;
/**
* @param user_id the id of the user we want to get the last value of the sequence
* @return last value of PersistSequence
*/
public static int getNextValue( String user_id){
if( sequence.get() == 0){//first time we run it or it has been restarted
l = ofy().load().type( PersistSequence.class).filter("user_id", user_id).limit(1).list();//grabs PersistSequence object bounded to user_id
if( l != null){
int dataStoreSeq = -1;
if ( l.size() > 0) dataStoreSeq = l.get(0).getLastId();
if ( dataStoreSeq > sequence.get()) sequence.set( dataStoreSeq);
persistCounter( user_id, sequence.incrementAndGet());
return sequence.get();
}else{
persistCounter( user_id, sequence.incrementAndGet());
return sequence.get();
}
}else{
persistCounter( user_id, sequence.incrementAndGet());
return sequence.get();
}
}
/**
* @param user_id the id of the user
* @param lastId last used Id
*/
private static void persistCounter( String user_id, int lastId){
//we only want one PersistSequence object per user so we delete the previous one before saving the new PersistSequence object
List<Key<PersistSequence>> keys = ofy().load().type(PersistSequence.class).filter("user_id", user_id).keys().list();
ofy().delete().keys(keys).now();
//save the new one
newPs = new PersistSequence();
newPs.setLastId(lastId);
newPs.setUserId(user_id);
ofy().save().entities( newPs).now();
}
}
I am happy with this code as it works well. However, I wonder if it still will rock if there is a high volume of users calling it.