Merge: Server part of fix 23106017. Server sends busy reply instead of timing out
1.1 --- a/logger/uihandler.api/src/org/netbeans/server/uihandler/api/bugs/BugReporterFacade.java Mon Oct 10 17:24:33 2016 +0200
1.2 +++ b/logger/uihandler.api/src/org/netbeans/server/uihandler/api/bugs/BugReporterFacade.java Mon Oct 24 10:57:45 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:33 2016 +0200
2.2 +++ b/logger/uihandlerserver/src/java/org/netbeans/server/uihandler/DbInsertion.java Mon Oct 24 10:57:45 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