public void run() { final ArrayList<LoginEvent> events = new ArrayList<LoginEvent>(TRANSACTION_SIZE + 1); while (run) { try { LoginEvent take = queue.poll(2, TimeUnit.SECONDS); if (take == null) { continue; } try { events.add(take); queue.drainTo(events, TRANSACTION_SIZE); for (LoginEvent event : events) { if (event instanceof FailedLogin) { logFailure(event); } else { logSuccess(event); } } Collections.sort( events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking // this. KeycloakSession session = factory.createSession(); try { for (LoginEvent event : events) { if (event instanceof FailedLogin) { failure(session, event); } } session.getTransaction().commit(); } catch (Exception e) { session.getTransaction().rollback(); throw e; } finally { for (LoginEvent event : events) { if (event instanceof FailedLogin) { ((FailedLogin) event).latch.countDown(); } } events.clear(); session.close(); } } catch (Exception e) { logger.error("Failed processing event", e); } } catch (InterruptedException e) { break; } finally { shutdownLatch.countDown(); } } }
@Override public void run() { int failedCount = 0; try { long start = EnvironmentEdgeManager.currentTime(); // drain all the queued puts into the tmp list processingList.clear(); queue.drainTo(processingList); if (processingList.size() == 0) { // Nothing to flush return; } currentProcessingCount.set(processingList.size()); // failedCount is decreased whenever a Put is success or resubmit. failedCount = processingList.size(); List<Action<Row>> retainedActions = new ArrayList<>(processingList.size()); MultiAction<Row> actions = new MultiAction<>(); for (int i = 0; i < processingList.size(); i++) { PutStatus putStatus = processingList.get(i); Action<Row> action = new Action<Row>(putStatus.put, i); actions.add(putStatus.regionInfo.getRegionName(), action); retainedActions.add(action); } // Process this multi-put request List<PutStatus> failed = null; Object[] results = new Object[actions.size()]; ServerName server = addr.getServerName(); Map<ServerName, MultiAction<Row>> actionsByServer = Collections.singletonMap(server, actions); try { AsyncRequestFuture arf = ap.submitMultiActions( null, retainedActions, 0L, null, results, true, null, null, actionsByServer, null); arf.waitUntilDone(); if (arf.hasError()) { // We just log and ignore the exception here since failed Puts will be resubmit again. LOG.debug( "Caught some exceptions when flushing puts to region server " + addr.getHostnamePort(), arf.getErrors()); } } finally { for (int i = 0; i < results.length; i++) { if (results[i] instanceof Result) { failedCount--; } else { if (failed == null) { failed = new ArrayList<PutStatus>(); } failed.add(processingList.get(i)); } } } if (failed != null) { // Resubmit failed puts for (PutStatus putStatus : failed) { if (resubmitFailedPut(putStatus, this.addr)) { failedCount--; } } } long elapsed = EnvironmentEdgeManager.currentTime() - start; // Update latency counters averageLatency.add(elapsed); if (elapsed > maxLatency.get()) { maxLatency.set(elapsed); } // Log some basic info if (LOG.isDebugEnabled()) { LOG.debug( "Processed " + currentProcessingCount + " put requests for " + addr.getHostnamePort() + " and " + failedCount + " failed" + ", latency for this send: " + elapsed); } // Reset the current processing put count currentProcessingCount.set(0); } catch (RuntimeException e) { // To make findbugs happy // Log all the exceptions and move on LOG.debug( "Caught some exceptions " + e + " when flushing puts to region server " + addr.getHostnamePort(), e); } catch (Exception e) { if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } // Log all the exceptions and move on LOG.debug( "Caught some exceptions " + e + " when flushing puts to region server " + addr.getHostnamePort(), e); } finally { // Update the totalFailedCount this.totalFailedPutCount.addAndGet(failedCount); } }
@Override public int drainTo(Collection<? super E> c, int maxElements) { return queue.drainTo(c, maxElements); }
@Override public int drainTo(Collection<? super E> c) { return queue.drainTo(c); }
/** {@inheritDoc} */ public int getNextTasks(Collection<? super ScheduledTask> tasks, int max) { return queue.drainTo(tasks, max); }