java - Google App Engine Modules + HttpServlet with static values; -


i developing application delivers notifications android , ios devices. using basic scaling , have implemented logic (modifying example) appropriate number of workers active @ given time without using resident instance.

public class notificationworkerservlet extends httpservlet {  /**  *   */ private static final long serialversionuid = 1l; private static final logger log = logger         .getlogger(notificationworkerservlet.class.getname()); private static final int max_worker_count = 5; private static final int milliseconds_to_wait_when_no_tasks_leased = 2500; private static final int ten_minutes = (10 * 60 * 1000);  // area of concern private static synccounter counter;  /**  * used keep number of running workers in sync  */ private class synccounter {      private int c = 0;      public synccounter(){         log.info("sync counter instantiated");     }      public synchronized void increment() {         c++;         log.info("increment sync counter, workers:" + c);      }      public synchronized void decrement() {         c--;         log.info("decrement sync counter, workers:" + c);     }      public synchronized int value() {         return c;     } }  /**  * call made module when notification added task queue  */ @override protected void dopost(httpservletrequest req, httpservletresponse resp)         throws servletexception, ioexception {     super.dopost(req, resp);     // instantiate counter first call     if(counter == null){         counter = new synccounter();     }      log.info("starting build workers");      (int workerno = counter.value(); workerno < max_worker_count; workerno++) {         log.info("starting thread worker: " + workerno);          // current queue check it's statistics         queue notificationqueue = queuefactory                 .getqueue("notification-delivery");         if (notificationqueue.fetchstatistics().getnumtasks() > 30 * workerno) {             counter.increment();             thread thread = threadmanager                     .createbackgroundthread(new runnable() {                          @override                         public void run() {                             try {                                 dopolling();                             } catch (exception e) {                                 e.printstacktrace();                             }                          }                      });              thread.start();         } else {             break; // current number of threads sufficient.         }     }      resp.setstatus(httpservletresponse.sc_ok);  }  /**  * poll task queue , lease tasks  *   * wait 10 minutes tasks added queue before killing  * tasks  *   */ private void dopolling() {     log.info("doing pulling");      try {          int loopswithoutprocessedtasks = 0;         queue notificationqueue = queuefactory                 .getqueue("notification-delivery");         notificationworker worker = new notificationworker(                 notificationqueue);          while (!lifecyclemanager.getinstance().isshuttingdown()) {             boolean tasksprocessed = worker.processbatchoftasks();             apiproxy.flushlogs();              if (!tasksprocessed) {                 log.info("waiting tasks");                  // wait before trying lease tasks again.                 try {                     loopswithoutprocessedtasks++;                      // if worker hasn't had tasks 30 min, kill it.                     if (loopswithoutprocessedtasks >= (ten_minutes / milliseconds_to_wait_when_no_tasks_leased)) {                         break;                     } else {                         // else, wait , try again (to avoid tearing down                         // useful notification senders)                         thread.sleep(milliseconds_to_wait_when_no_tasks_leased);                     }                  } catch (interruptedexception e) {                     log.info("notification worker thread interrupted");                     break;                 }             } else {                 log.info("processed batch of tasks");                 loopswithoutprocessedtasks = 0;             }         }     } catch (exception e) {         log.warning("exception caught , handled in notification worker: "                 + e.getlocalizedmessage());     } {         counter.decrement();     }      log.info("instance shutting down");  } 

}

in controlled testing scenario, works fine. however, know static, mutable values bad news in servlets multiple users potentially connecting @ same time.

has done similar , had issues pushing multiple notifications same device, lost tasks or had idle tasks burning hole in bank?


Comments

Popular posts from this blog

rewrite asp to php based on asp query -

android - questions about switching from C2DM to GCM -

visual studio 2010 - Error on RDLC Expression -