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

com.huaweicloud.dws.client.collector.ActionCollector Maven / Gradle / Ivy


package com.huaweicloud.dws.client.collector;

import com.huaweicloud.dws.client.DwsConfig;
import com.huaweicloud.dws.client.action.GetAction;
import com.huaweicloud.dws.client.exception.DwsClientException;
import com.huaweicloud.dws.client.exception.ExceptionCode;
import com.huaweicloud.dws.client.model.Record;
import com.huaweicloud.dws.client.model.TableName;
import com.huaweicloud.dws.client.model.TableSchema;
import com.huaweicloud.dws.client.op.Get;
import com.huaweicloud.dws.client.util.LogUtil;
import com.huaweicloud.dws.client.worker.ExecutionPool;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * @ProjectName: dws-connector
 * @ClassName: ActionCollector
 * @Description: 所有事件收集
 * @Date: 2023/1/10 15:47
 * @Version: 1.0
 */
@Slf4j
@Getter
public class ActionCollector implements ICollector {
    // 插入queue等待时间,默认10s
    private static final long OFFER_QUEUE_TIME_OUT = 10000L;
    private static final long POLL_QUEUE_TIME_OUT = 2000L;


    /**
     * 为每个表设置一个事件收集器,避免不同表之间相互影响
     */
    final Map tableCollectors = new ConcurrentHashMap<>();

    /**
     * 全局配置
     */
    protected final DwsConfig config;

    /**
     * 资源池
     */
    protected final ExecutionPool pool;

    /**
     * get请求队列
     */
    final ArrayBlockingQueue queue;

    /**
     * 保存最后的执行异常
     */
    public ActionCollector(DwsConfig config, ExecutionPool pool) {
        this.config = config;
        this.pool = pool;
        this.queue = pool.getQueue();
    }

    /**
     * 尝试缓存入库
     */
    @Override
    public void tryFlush() throws DwsClientException {
        flush(false);
    }



    private void flush(boolean force) throws DwsClientException {
        for (ICollector value : tableCollectors.values()) {
            try {
                if (force) {
                    value.flush();
                } else {
                    value.tryFlush();
                }
            } catch (Exception e) {
                log.error("action collector flush error. force = {}", force, e);
                throw DwsClientException.fromException(e);
            }
        }
    }


    /**
     * 强制入库
     */
    @Override
    public void flush() throws DwsClientException {
        flush(true);
    }


    @Override
    public ITableCollector getTableActionCollector(TableSchema schema) {
        return tableCollectors.computeIfAbsent(schema.getTableName(), table -> {
            if (config.getTableConfig(table).isSecurityMode()) {
                return new SecurityModeCollector(config, pool, schema);
            }
            return new TableActionCollector(config, pool, schema);
        });
    }

    public void submit(List recordList, int batchSize) throws DwsClientException {
        DwsClientException exception;
        recordList.clear();
        try {
            Get firstGet = queue.poll(POLL_QUEUE_TIME_OUT, TimeUnit.MILLISECONDS);
            if (firstGet != null) {
                recordList.add(firstGet);
                queue.drainTo(recordList, batchSize - 1);
                if (config.isLogSwitch()) {
                    log.info("submit gets action to dws, size: {}", recordList.size());
                }
                submit(recordList);
            }
        } catch (Exception e) {
            exception = DwsClientException.fromException(e);
            for (Get get : recordList) {
                if (!get.getFuture().isDone()) {
                    get.getFuture().completeExceptionally(exception);
                }
            }
        }
    }

    public void submit(List recordList) throws DwsClientException {
        Map> getsByTable = new HashMap<>();
        for (Get get : recordList) {
            if (config.getReadTimeoutMilliseconds() > 0) {
                long waitingTime = (System.nanoTime() - get.getStartTime()) / 1000000L;
                if (waitingTime - config.getReadTimeoutMilliseconds() > 0) {
                    get.getFuture()
                            .completeExceptionally(new DwsClientException(ExceptionCode.TIMEOUT,
                                    String.format(
                                            "Get action timeout before submit to dws, %s ms set in the config, actual cost %s ms",
                                            waitingTime, config.getReadTimeoutMilliseconds())));
                }
            }
            // 区分不同的tableSchema,用于后续批量sql拼接
            List list = getsByTable.computeIfAbsent(get.getRecord().getTableSchema(), (s) -> new ArrayList<>());
            list.add(get);
        }
        for (Map.Entry> entry : getsByTable.entrySet()) {
            GetAction getAction = new GetAction(entry.getValue(), config);
            while (!pool.submit(getAction)) {
                LogUtil.withLogSwitch(config, () -> log.warn("try submit."));
            }
        }
    }

    /**
     * ===============添加数据API===============
     */
    @Override
    public void collector(Record record) throws DwsClientException {
        // 获取该表对应的收集器
        getTableActionCollector(record.getTableSchema()).collector(record);

    }

    public void appendGet(Get get) {
        try {
            if (!queue.offer(get, OFFER_QUEUE_TIME_OUT, TimeUnit.MILLISECONDS)) {
                get.getFuture().completeExceptionally(new TimeoutException());
            }
        } catch (InterruptedException e) {
            get.getFuture().completeExceptionally(e);
        }
    }

    @Override
    public ExecutionPool getPool() {
        return pool;
    }

    @Override
    public DwsConfig getConfig() {
        return config;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy