java - Multi Threading in Google App Engine Datastore -


how can make operations of getting , setting property datastore, thread safe?

currently, have code puts tasks in queue , each task perform task , updates property called of numberoftasks of type int. fetches current value of property , increments it.

however tasks executed in queue, final value not coming correct because of threading issue. sometimes, 2 tasks tries update proeprty @ same time , hence sometime increment isnt done.

could please in getting done correctly?

datastore property getter method:

private string doget(string rowid) throws entitynotfoundexception {     key egskey = keyfactory.createkey(datastore_kind, rowid);      entity egsentity = datastore.get(egskey);      // schema changed string text type. transparently handle here.     object propertyvalue = egsentity.getproperty(property_key);      if (propertyvalue instanceof string) {         return (string) propertyvalue;     }      text text = (text) propertyvalue;      return text.getvalue(); } 

datastore property setter method:

private void doput(string rowid, list<string> list) {     entity entity = new entity(datastore_kind, rowid);     entity.setproperty(property_key, list);      datastore.put(entity); } 

setter , getter methods:

public synchronized int getpendingusersforprocessing() {     string pendingusersforprocessingasstring = null;     try {         pendingusersforprocessingasstring = doget(pending_users_for_processing);         return integer.valueof(pendingusersforprocessingasstring);     } catch (numberformatexception e) {         throw new illegalstateexception("the num of last batches processed in datastore not number: "                 + pendingusersforprocessingasstring);     } catch (entitynotfoundexception e) {         return default_pending_users_for_processing;     } }  /** {@inheritdoc } */ @override public synchronized void setpendingusersforprocessing(int pendingusersforprocessing) {     doput(pending_users_for_processing, string.valueof(pendingusersforprocessing));     log.info("number of pending users processing set : " + pendingusersforprocessing); } 

code trying update property:

int pendingusers = appproperties.getpendingusersforprocessing(); int requestusers = request.getuserkeys().size(); appproperties.setpendingusersforprocessing(pendingusers + requestusers); 

this not threading issue may have multiple instances of app performing tasks, , instances not know each other. contention situation.

you have several options on how resolve it.

  1. use sharding counters.

  2. instead of updating same entity, create new entity each completed task, using time when task completed id. advantage of approach creates audit trail , can stats number of tasks completed today, within last hour, etc. count number of entities can use keys-only query, free , fast. disadvantage higher cost of writing these entities - not solution if have large number of tasks complete.

  3. instead of counting tasks, count results of these tasks. example, if task updates user status, can count number of users "pending" status using free , fast keys-only query. approach if have indexed property can use flag count tasks completed.


Comments

Popular posts from this blog

java - Plugin org.apache.maven.plugins:maven-install-plugin:2.4 or one of its dependencies could not be resolved -

Round ImageView Android -

How can I utilize Yahoo Weather API in android -