private void queue(List<QCMutation> mutations) { List<QCMutation> failures = new ArrayList<>(); Map<String,TabletServerMutations<QCMutation>> binnedMutations = new HashMap<>(); try { locator.binMutations(context, mutations, binnedMutations, failures); if (failures.size() == mutations.size()) if (!Tables.exists(context, tableId)) throw new TableDeletedException(tableId.canonicalID()); else if (Tables.getTableState(context, tableId) == TableState.OFFLINE) throw new TableOfflineException(Tables.getTableOfflineMsg(context, tableId)); } catch (Exception e) { for (QCMutation qcm : mutations) qcm.queueResult(new Result(e, qcm, null)); // do not want to queue anything that was put in before binMutations() failed failures.clear(); binnedMutations.clear(); } if (failures.size() > 0) queueRetry(failures, null); for (Entry<String,TabletServerMutations<QCMutation>> entry : binnedMutations.entrySet()) { queue(entry.getKey(), entry.getValue()); } }
@Override public Iterator<Result> write(Iterator<ConditionalMutation> mutations) { BlockingQueue<Result> resultQueue = new LinkedBlockingQueue<>(); List<QCMutation> mutationList = new ArrayList<>(); int count = 0; long entryTime = System.currentTimeMillis(); mloop: while (mutations.hasNext()) { ConditionalMutation mut = mutations.next(); count++; if (mut.getConditions().size() == 0) throw new IllegalArgumentException( "ConditionalMutation had no conditions " + new String(mut.getRow(), UTF_8)); for (Condition cond : mut.getConditions()) { if (!isVisible(cond.getVisibility())) { resultQueue.add(new Result(Status.INVISIBLE_VISIBILITY, mut, null)); continue mloop; } } // copy the mutations so that even if caller changes it, it will not matter mutationList.add(new QCMutation(mut, resultQueue, entryTime)); } queue(mutationList); return new RQIterator(resultQueue, count); }
ConditionalWriterImpl(ClientContext context, Table.ID tableId, ConditionalWriterConfig config) { this.context = context; this.auths = config.getAuthorizations(); this.ve = new VisibilityEvaluator(config.getAuthorizations()); this.threadPool = new ScheduledThreadPoolExecutor(config.getMaxWriteThreads(), new NamingThreadFactory(this.getClass().getSimpleName())); this.locator = new SyncingTabletLocator(context, tableId); this.serverQueues = new HashMap<>(); this.tableId = tableId; this.timeout = config.getTimeout(TimeUnit.MILLISECONDS); this.durability = config.getDurability(); this.classLoaderContext = config.getClassLoaderContext(); Runnable failureHandler = () -> { List<QCMutation> mutations = new ArrayList<>(); failedMutations.drainTo(mutations); if (mutations.size() > 0) queue(mutations); }; failureHandler = new LoggingRunnable(log, failureHandler); threadPool.scheduleAtFixedRate(failureHandler, 250, 250, TimeUnit.MILLISECONDS); }