Server part of fix 23106017. Server sends busy reply instead of timing out jdev_excrep-stable
authorJakub Lehotsky <jlehotsky@netbeans.org>
Mon, 24 Oct 2016 10:57:16 +0200
branchjdev_excrep-stable
changeset 636554ce9faaa533
parent 6363 4818e7ddfcc8
child 6366 77a6a156724c
child 6368 f62db7e29075
Server part of fix 23106017. Server sends busy reply instead of timing out
logger/uihandler.api/src/org/netbeans/server/uihandler/api/bugs/BugReporterFacade.java
logger/uihandlerserver/src/java/org/netbeans/server/uihandler/DbInsertion.java
     1.1 --- a/logger/uihandler.api/src/org/netbeans/server/uihandler/api/bugs/BugReporterFacade.java	Mon Oct 10 17:24:12 2016 +0200
     1.2 +++ b/logger/uihandler.api/src/org/netbeans/server/uihandler/api/bugs/BugReporterFacade.java	Mon Oct 24 10:57:16 2016 +0200
     1.3 @@ -117,26 +117,31 @@
     1.4                  }
     1.5              }
     1.6              
     1.7 -        private void processAsyncContextReply(AsyncContext asyncContext, int reportId, int bugNo, String action) {
     1.8 -            
     1.9 -            try {
    1.10 -                LOG.log(Level.INFO, "Sending async servlet reply..."); // NOI18N
    1.11 +            private void processAsyncContextReply(AsyncContext asyncContext, int reportId, int bugNo, String action) {
    1.12  
    1.13 -                ServletRequest request = asyncContext.getRequest();
    1.14 -                ServletResponse response = asyncContext.getResponse();
    1.15 -                request.setAttribute("action", action);
    1.16 -                request.setAttribute("reportNo", reportId);
    1.17 -                request.setAttribute("bugNo", bugNo);
    1.18 -                request.getRequestDispatcher("/uploadredirect.jsp").forward(request, response); // NOI18N
    1.19 -                asyncContext.complete();
    1.20 -                
    1.21 -            } catch (ServletException | IOException | IllegalStateException ex) {
    1.22 -                // Illegal state : in case response has timed out - we still need to have a bug stored in db
    1.23 -                //     although we have entered it late (after async server response http timeout in this case)
    1.24 -                //     - thereofore no rethrow
    1.25 -                LOG.log(Level.SEVERE, ex.getMessage(), ex);
    1.26 +                try {
    1.27 +                    LOG.log(Level.INFO, "Sending async servlet reply..."); // NOI18N 
    1.28 +
    1.29 +                    ServletRequest request = asyncContext.getRequest();
    1.30 +                    ServletResponse response = asyncContext.getResponse();
    1.31 +                    request.setAttribute("action", action);
    1.32 +                    request.setAttribute("reportNo", reportId);
    1.33 +                    request.setAttribute("bugNo", bugNo);
    1.34 +                    request.getRequestDispatcher("/uploadredirect.jsp").forward(request, response); // NOI18N
    1.35 +                    asyncContext.complete();
    1.36 +
    1.37 +                } catch (ServletException | IOException | IllegalStateException ex) {
    1.38 +                    // Illegal state : in case response has timed out - we still need to have a bug stored in db
    1.39 +                    //     although we have entered it late (after async server response http timeout in this case)
    1.40 +                    //     - thereofore no rethrow
    1.41 +
    1.42 +                    // This is a not very clean code but there's really no check like "isComplete()" on AsyncContext API
    1.43 +                    // (Note: if there's one in the future, it needs to be synchronided)
    1.44 +                    if (!(ex instanceof IllegalStateException) || !ex.getMessage().contains("already completed")) {
    1.45 +                        LOG.log(Level.SEVERE, ex.getMessage(), ex);
    1.46 +                    }
    1.47 +                }
    1.48              }
    1.49 -        }
    1.50  
    1.51          });
    1.52      }
     2.1 --- a/logger/uihandlerserver/src/java/org/netbeans/server/uihandler/DbInsertion.java	Mon Oct 10 17:24:12 2016 +0200
     2.2 +++ b/logger/uihandlerserver/src/java/org/netbeans/server/uihandler/DbInsertion.java	Mon Oct 24 10:57:16 2016 +0200
     2.3 @@ -55,6 +55,9 @@
     2.4  import java.util.Queue;
     2.5  import java.util.Timer;
     2.6  import java.util.TimerTask;
     2.7 +import java.util.concurrent.Executors;
     2.8 +import java.util.concurrent.ScheduledExecutorService;
     2.9 +import java.util.concurrent.TimeUnit;
    2.10  import java.util.concurrent.atomic.AtomicBoolean;
    2.11  import java.util.logging.Level;
    2.12  import java.util.logging.LogRecord;
    2.13 @@ -95,6 +98,7 @@
    2.14      private static final Logger LOG = Logger.getLogger("org.netbeans.modules.exceptions.entity.Report.IssueChanges"); // NOI18N
    2.15      private static Logger INSERTION_LOG = Logger.getLogger("org.netbeans.server.uihandler.DbInsertion"); // NOI18N
    2.16      private static Logger MATCHER_LOG = Logger.getLogger("org.netbeans.server.uihandler.matcher"); // NOI18N
    2.17 +    private static final int SERVER_BUSY_REPLY_IN_SECONDS = 45;    
    2.18      private static final int MAXMESSAGELENGTH = 1024;
    2.19      private static final int CHANGESET_RADIX = 16;
    2.20      private static final Component DEFAULT_JDEV_COMPONENT;
    2.21 @@ -132,6 +136,12 @@
    2.22      private static final int CLEANUP_TASK_INTERVAL = 100;
    2.23      private final BugReporterFacade bugReporter;
    2.24      private final BugTrackerCategorizer categorizer;        
    2.25 +
    2.26 +    private static final ScheduledExecutorService scheduledExecutor;
    2.27 +    
    2.28 +    static {
    2.29 +        scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
    2.30 +    }
    2.31      
    2.32      DbInsertion(LogRecord data, Throwable thrown, LogRecord buildInfo, Long slownessTime, SlownessType slownessType, String latestAction) {
    2.33          this(data, thrown, buildInfo, null, slownessTime, slownessType, latestAction);
    2.34 @@ -248,7 +258,7 @@
    2.35              }
    2.36          }
    2.37      }
    2.38 -        
    2.39 +
    2.40      /** issueId is an ID of newly created issue if not duplicate
    2.41       *  if duplicate issueId is an ID of issue to be duplicate of
    2.42       *  issuezillaId is 0 if not assigned, otherwise an issuezilla Id
    2.43 @@ -338,6 +348,42 @@
    2.44          }
    2.45          
    2.46          if (submit != null){
    2.47 +
    2.48 +            
    2.49 +        final int reportId = submit.getReportId().getId();
    2.50 +        final int submitId = submit.getId();
    2.51 +            
    2.52 +        // then, when you want to schedule a task
    2.53 +        Runnable task = new Runnable() {
    2.54 +            @Override
    2.55 +            public void run() {
    2.56 +                try {
    2.57 +                    
    2.58 +                    ServletRequest request = thisTask.getAsyncContext().getRequest();
    2.59 +                    ServletResponse response = thisTask.getAsyncContext().getResponse();
    2.60 +                    request.setAttribute("action", "BUSY"); // NOI18N
    2.61 +                    request.setAttribute("reportNo", reportId); // NOI18N
    2.62 +                    request.setAttribute("bugNo", "0"); // NOI18N
    2.63 +                    request.getRequestDispatcher("/uploadredirect.jsp").forward(request, response); // NOI18N
    2.64 +                    LOG.log(Level.INFO, "Server busy - sending async servlet reply..."); // NOI18N
    2.65 +                    thisTask.getAsyncContext().complete();
    2.66 +
    2.67 +                } catch (ServletException | IOException | IllegalStateException ex) {
    2.68 +                    // Illegal state : in case response has timed out - we still need to have a bug stored in db
    2.69 +                    //     although we have entered it late (after async server response http timeout in this case)
    2.70 +                    //     - thereofore no rethrow
    2.71 +
    2.72 +                    // This is not very clean code, but there's really no check like "isComplete()" on AsyncContext API
    2.73 +                    // (Note: if there's one in the future, it needs to be synchronided)
    2.74 +                    if (!(ex instanceof IllegalStateException) || !ex.getMessage().contains("already completed")) {
    2.75 +                        LOG.log(Level.SEVERE, ex.getMessage(), ex);
    2.76 +                    }
    2.77 +                }
    2.78 +            }
    2.79 +        };
    2.80 +        
    2.81 +        scheduledExecutor.schedule(task, SERVER_BUSY_REPLY_IN_SECONDS, TimeUnit.SECONDS);
    2.82 +                        
    2.83              Integer beforeReopenId = null;
    2.84              if (duplicatesReport != null){
    2.85                  beforeReopenId = duplicatesReport.getId();
    2.86 @@ -422,17 +468,24 @@
    2.87              if (thisTask.isAsyncProcessing()) {
    2.88                  INSERTION_LOG.log(Level.INFO, "Sending async servlet reply..."); // NOI18N
    2.89                  AsyncContext asyncContext = thisTask.getAsyncContext();
    2.90 -                ServletRequest request = asyncContext.getRequest();
    2.91 -                ServletResponse response = asyncContext.getResponse();
    2.92 -                request.setAttribute("action", action);
    2.93 -                request.setAttribute("reportNo", report.getId());
    2.94 -                request.setAttribute("bugNo", report.getIssueId());
    2.95 -                request.getRequestDispatcher("/uploadredirect.jsp").forward(request, response); // NOI18N
    2.96 -                asyncContext.complete();
    2.97 -            }
    2.98 -            
    2.99 -        } catch (ServletException | IOException ex) {
   2.100 -            INSERTION_LOG.log(Level.SEVERE, ex.getMessage(), ex);
   2.101 +                    ServletRequest request = asyncContext.getRequest();
   2.102 +                    ServletResponse response = asyncContext.getResponse();
   2.103 +                    request.setAttribute("action", action);
   2.104 +                    request.setAttribute("reportNo", report.getId());
   2.105 +                    request.setAttribute("bugNo", report.getIssueId());
   2.106 +                    request.getRequestDispatcher("/uploadredirect.jsp").forward(request, response); // NOI18N
   2.107 +                    asyncContext.complete();
   2.108 +            }            
   2.109 +        } catch (ServletException | IOException | IllegalStateException ex) {
   2.110 +            // Illegal state : in case response has timed out - we still need to have a bug stored in db
   2.111 +            //     although we have entered it late (after async server response http timeout in this case)
   2.112 +            //     - thereofore no rethrow
   2.113 +
   2.114 +            // This is a little hack, but there's really no check like "isComplete()" on AsyncContext API
   2.115 +            // (Note: if there's one in the future, it needs to be synchronided)
   2.116 +            if (!(ex instanceof IllegalStateException) || !ex.getMessage().contains("already completed")) {
   2.117 +                INSERTION_LOG.log(Level.SEVERE, ex.getMessage(), ex);
   2.118 +            }    
   2.119          }
   2.120      }
   2.121