
com.huaweicloud.dws.client.worker.ReadActionExecutor Maven / Gradle / Ivy
package com.huaweicloud.dws.client.worker;
import com.huaweicloud.dws.client.DwsClient;
import com.huaweicloud.dws.client.DwsConfig;
import com.huaweicloud.dws.client.collector.ActionCollector;
import com.huaweicloud.dws.client.exception.DwsClientException;
import com.huaweicloud.dws.client.exception.DwsClientRecordException;
import com.huaweicloud.dws.client.function.DwsClientExceptionFunction;
import com.huaweicloud.dws.client.op.Get;
import com.huaweicloud.dws.client.util.LogUtil;
import lombok.extern.slf4j.Slf4j;
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
/**
* @ProjectName: dws-client
* @Description: ReadActionExecutor
* 监控所有的查询Action,提交給Worker.
* 读和写机制不一样。
* 写是攒批满足条件后提交給Worker;
* 读需要一个专门的线程把读队列里的请求第一时间取出并提交給Worker来保证latency.
* @Date: 2023/09/26
*/
@Slf4j
public class ReadActionExecutor implements Runnable, Closeable {
private final int batchSize;
private final DwsConfig config;
private final DwsClient client;
private final AtomicBoolean started;
private final ActionCollector collector;
private final AtomicBoolean running = new AtomicBoolean(true);
private DwsClientException lastException;
private final AtomicReference lastRecordException = new AtomicReference<>(null);
public ReadActionExecutor(DwsConfig config, AtomicBoolean started, ActionCollector collector, DwsClient client,
int batchSize) {
this.config = config;
this.started = started;
this.collector = collector;
this.client = client;
this.batchSize = batchSize;
}
@Override
public void run() {
ArrayList batchList = new ArrayList<>(batchSize);
while (started.get() && running.get()) {
try {
submit(batchList, batchSize);
} catch (DwsClientRecordException recordException) {
lastRecordException.accumulateAndGet(recordException, (last, n) -> {
if (last == null) {
return n;
}
return last.merge(n);
});
} catch (DwsClientException e) {
log.error("background task submit error.", e);
lastException = e;
} catch (Throwable unknown) {
log.error("background task submit error.", unknown);
}
}
}
public void submit(List batchList, int batchSize) throws DwsClientException {
try {
collector.submit(batchList, batchSize);
} catch (DwsClientException e) {
DwsClientExceptionFunction function = config.getErrorFunction();
if (function == null) {
LogUtil.withLogSwitch(config, () -> log.info("try submit error, no exception handler "));
throw e;
}
LogUtil.withLogSwitch(config, () -> log.info("try submit error, will apply exception handler."));
function.apply(e, client);
}
}
/**
* 检查后台任务异常
*/
public void tryException() throws DwsClientException {
DwsClientException t = lastRecordException.getAndSet(null);
if (t != null) {
throw t;
}
t = lastException;
if (t != null) {
lastException = null;
throw t;
}
}
@Override
public String toString() {
return "ReadActionExecutor{" + "batchSize=" + batchSize + '}';
}
@Override
public synchronized void close() throws IOException {
running.compareAndSet(true, false);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy