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

c# - Better 64-bit byte array hash -

webrtc - Which ICE candidate am I using and why? -

php - Zend Framework / Skeleton-Application / Composer install issue -