All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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