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

com.huaweicloud.dws.client.worker.WaitActionTaskExecutor 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.action.AbstractAction;
import com.huaweicloud.dws.client.exception.DwsClientException;
import com.huaweicloud.dws.client.exception.DwsClientRecordException;
import com.huaweicloud.dws.client.function.DwsClientExceptionFunction;
import lombok.extern.slf4j.Slf4j;

import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @ProjectName: dws-connector
 * @ClassName: BackgroundExecutor
 * @Description: 后台任务执行
 * @Date: 2023/1/9 19:39
 * @Version: 1.0
 */
@Slf4j
public class WaitActionTaskExecutor implements Runnable, Closeable {
    private final DwsConfig config;
    private final DwsClient client;
    private final AtomicBoolean started;
    private DwsClientException lastException;
    private final AtomicBoolean running = new AtomicBoolean(true);
    private final AtomicReference lastRecordException = new AtomicReference<>(null);
    protected final LinkedBlockingQueue> backgroundTasks;

    public WaitActionTaskExecutor(DwsConfig config, AtomicBoolean started, DwsClient client) {
        this.config = config;
        this.started = started;
        this.client = client;
        this.backgroundTasks = new LinkedBlockingQueue<>(config.getThreadSize() * 2);
    }


    @Override
    public void run() {
        while (started.get() && running.get()) {
            doRun();
            if (!backgroundTasks.isEmpty()) {
                continue;
            }
            try {
                Thread.sleep(10L);
            } catch (InterruptedException e) {

            }
        }
    }

    private void doRun() {
        try {
            waitAction();
        } catch (DwsClientRecordException recordException) {
            lastRecordException.accumulateAndGet(recordException, (last, n) -> {
                if (last == null) {
                    return n;
                }
                return last.merge(n);
            });
        } catch (DwsClientException e) {
            log.error("wait task flush error.", e);
            lastException = e;
        } catch (Throwable unknown) {
            log.error("wait task running error.", unknown);
        }
    }

    private synchronized void waitAction() throws DwsClientException {
        try {
            AbstractAction action = backgroundTasks.poll();
            if (action == null) {
                return;
            }
            DwsClientRecordException exception = DwsClientRecordException.fromAction(action);
            if (exception != null) {
                throw exception;
            }
        } catch (DwsClientException e) {
            DwsClientExceptionFunction function = config.getErrorFunction();
            if (function == null) {
                throw e;
            }
            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 synchronized void close() throws IOException {
        running.compareAndSet(true, false);
    }

    public synchronized void flush() {
        if (backgroundTasks.isEmpty()) {
            return;
        }
        while (!backgroundTasks.isEmpty()) {
            doRun();
        }
    }

    public void submitAction(AbstractAction action) {
        while (!backgroundTasks.offer(action)) {
            log.debug("try submit action.");
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy