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

com.alibaba.schedulerx.worker.ha.AtLeastOnceDeliveryActor Maven / Gradle / Ivy

There is a newer version: 1.12.2
Show newest version
package com.alibaba.schedulerx.worker.ha;

import java.util.List;

import com.alibaba.schedulerx.common.util.ReflectionUtil;
import com.alibaba.schedulerx.protocol.Worker.ContainerBatchReportTaskStatuesRequest;
import com.alibaba.schedulerx.protocol.Worker.ContainerBatchReportTaskStatuesResponse;
import com.alibaba.schedulerx.protocol.Worker.MasterDestroyContainerPoolRequest;
import com.alibaba.schedulerx.protocol.Worker.MasterDestroyContainerPoolResponse;
import com.alibaba.schedulerx.protocol.Worker.WorkerBatchReportTaskStatuesRequest;
import com.alibaba.schedulerx.protocol.Worker.WorkerBatchReportTaskStatuesResponse;
import com.alibaba.schedulerx.protocol.Worker.WorkerReportJobInstanceStatusRequest;
import com.alibaba.schedulerx.protocol.Worker.WorkerReportJobInstanceStatusResponse;
import com.alibaba.schedulerx.worker.discovery.ServerDiscoveryFactory;
import com.alibaba.schedulerx.worker.log.LogFactory;
import com.alibaba.schedulerx.worker.log.Logger;
import com.alibaba.schedulerx.worker.util.ActorPathUtil;

import akka.actor.ActorSelection;
import akka.japi.Function;
import akka.persistence.AtLeastOnceDelivery.AtLeastOnceDeliverySnapshot;
import akka.persistence.AtLeastOnceDelivery.UnconfirmedDelivery;
import akka.persistence.AtLeastOnceDelivery.UnconfirmedWarning;
import akka.persistence.SnapshotOffer;
import akka.persistence.UntypedPersistentActorWithAtLeastOnceDelivery;

/**
 *
 * @author xiaomeng.hxm
 */
public class AtLeastOnceDeliveryActor extends UntypedPersistentActorWithAtLeastOnceDelivery {
    private int id = 0;
    private static final Logger LOGGER = LogFactory.getLogger(AtLeastOnceDeliveryActor.class);

    public AtLeastOnceDeliveryActor(int id) {
        this.id = id;
    }

    @Override
    public String persistenceId() {
        return "persistence-id-" + id;
    }

    @Override
    public void onReceiveCommand(Object obj) {
        try {
            if (obj instanceof WorkerReportJobInstanceStatusRequest) {
                handleReportInstanceStatusEvent((WorkerReportJobInstanceStatusRequest)obj);
            } else if (obj instanceof WorkerBatchReportTaskStatuesRequest) {
                handleBatchReportTaskStatues((WorkerBatchReportTaskStatuesRequest) obj);
            } else if (obj instanceof ContainerBatchReportTaskStatuesRequest) {
                handleContainerBatchStatus((ContainerBatchReportTaskStatuesRequest) obj);
            } else if (obj instanceof MasterDestroyContainerPoolRequest) {
                handleDestroyContainerPool((MasterDestroyContainerPoolRequest) obj);
            } else if (obj instanceof WorkerReportJobInstanceStatusResponse) {
                WorkerReportJobInstanceStatusResponse response = (WorkerReportJobInstanceStatusResponse)obj;
                if (response.getSuccess()) {
                    confirmDelivery(response.getDeliveryId());
                } else {
                    LOGGER.error("WorkerReportJobInstanceStatus not success, reason:{}", response.getMessage());
                }
            } else if (obj instanceof WorkerBatchReportTaskStatuesResponse) {
                WorkerBatchReportTaskStatuesResponse response = (WorkerBatchReportTaskStatuesResponse) obj;
                if (response.getSuccess()) {
                    confirmDelivery(response.getDeliveryId());
                } else {
                    LOGGER.error("WorkerBatchReportTaskStatues not success, reason:{}", response.getMessage());
                }
            } else if (obj instanceof ContainerBatchReportTaskStatuesResponse) {
                ContainerBatchReportTaskStatuesResponse response = (ContainerBatchReportTaskStatuesResponse) obj;
                if (response.getSuccess()) {
                    confirmDelivery(response.getDeliveryId());
                } else {
                    LOGGER.error("ContainerBatchReportTaskStatues not success, reason:{}", response.getMessage());
                }
            } else if (obj instanceof MasterDestroyContainerPoolResponse) {
                MasterDestroyContainerPoolResponse response = (MasterDestroyContainerPoolResponse) obj;
                if (response.getSuccess()) {
                    confirmDelivery(response.getDeliveryId());
                } else {
                    LOGGER.error("MasterDestroyContainerPool not success, reason:{}", response.getMessage());
                }
            } else if (obj instanceof UnconfirmedWarning) {
                try {
                    List list = ((UnconfirmedWarning)obj).getUnconfirmedDeliveries();
                    for (UnconfirmedDelivery unconfirmedDelivery : list) {
                        Object unConfirmedMsg =  unconfirmedDelivery.getMessage();
                        long deliveryId = (long) ReflectionUtil.invokeMethod(unConfirmedMsg, "getDeliveryId");
                        confirmDelivery(deliveryId);
                        //akka框架每次重试地址不变,如果server切主,需要业务重新选主再重试一次
                        unConfirmRetry(unConfirmedMsg);
                    }
                } catch (Exception e) {
                    LOGGER.error("", e);
                }
            } else if (obj instanceof SnapshotOffer) {
                AtLeastOnceDeliverySnapshot snapshot = (AtLeastOnceDeliverySnapshot)(((SnapshotOffer)obj).snapshot());
                setDeliverySnapshot(snapshot);
            } 
        } catch (Throwable e) {
            LOGGER.error("", e);
        }

    }

    @Override
    public void onReceiveRecover(Object obj) throws Throwable {
        // noting to do
    }

    private void handleReportInstanceStatusEvent(final WorkerReportJobInstanceStatusRequest request) {
        ActorSelection serverSelection = ServerDiscoveryFactory.getDiscovery(request.getGroupId()).getInstanceStatusRouter();
        deliver(serverSelection, new Function() {
            public Object apply(Long deliveryId) {
                return request.toBuilder().setDeliveryId(deliveryId).build();
            }
        });
        LOGGER.info("report jobInstance={}, status={} to server={}", request.getJobInstanceId(), request.getStatus(), serverSelection);
    }

    private void handleBatchReportTaskStatues(final WorkerBatchReportTaskStatuesRequest request) {
        ActorSelection serverSelection = ServerDiscoveryFactory.getDiscovery(request.getGroupId()).getTaskStatusRouter();
        deliver(serverSelection, new Function() {
            public Object apply(Long deliveryId) {
                return request.toBuilder().setDeliveryId(deliveryId).build();
            }
        });
        LOGGER.debug("batch report task statues jobInstanceId={} to server={}", request.getJobInstanceId(),
            serverSelection);
    }

    private void handleContainerBatchStatus(final ContainerBatchReportTaskStatuesRequest request) {
        ActorSelection taskMasterSelection = getContext().actorSelection(request.getTaskMasterAkkaPath());
        deliver(taskMasterSelection, new Function() {
            public Object apply(Long deliveryId) {
                return request.toBuilder().setDeliveryId(deliveryId).build();
            }
        });
    }

    private void handleDestroyContainerPool(final MasterDestroyContainerPoolRequest request) {
        ActorSelection selection = getContext().actorSelection(
            ActorPathUtil.getContainerRouterPath(request.getWorkerIdAddr()));
        deliver(selection, new Function() {
            public Object apply(Long deliveryId) {
                return request.toBuilder().setDeliveryId(deliveryId).build();
            }
        });
    }

    private void unConfirmRetry(Object msg) {
        if (msg instanceof ContainerBatchReportTaskStatuesRequest) {
            ContainerBatchReportTaskStatuesRequest request = (ContainerBatchReportTaskStatuesRequest) msg;
            if (!request.hasAlreadyUnConfirmRetry() || !request.getAlreadyUnConfirmRetry()) {
                // never retry for unconfirm, we retry once, otherwise just let it go
                request = request.toBuilder().setAlreadyUnConfirmRetry(true).build();
                getSelf().tell(request, null);
                LOGGER.info("jobInstanceId={}, ContainerBatchReportTaskStatuesRequest unconfirm retry", request.getJobInstanceId());
            }
        } else if (msg instanceof MasterDestroyContainerPoolRequest) {
            MasterDestroyContainerPoolRequest request = (MasterDestroyContainerPoolRequest) msg;
            if (!request.hasAlreadyUnConfirmRetry() || !request.getAlreadyUnConfirmRetry()) {
                // never retry for unconfirm, we retry once, otherwise just let it go
                request = request.toBuilder().setAlreadyUnConfirmRetry(true).build();
                getSelf().tell(request, null);
                LOGGER.info("MasterDestroyContainerPoolRequest unconfirm retry, jobInstanceId={}, workerIdAddr={}",
                        request.getJobInstanceId(), request.getWorkerIdAddr());
            }
        } else if (msg instanceof WorkerBatchReportTaskStatuesRequest) {
            WorkerBatchReportTaskStatuesRequest request = (WorkerBatchReportTaskStatuesRequest) msg;
            if (!request.hasAlreadyUnConfirmRetry() || !request.getAlreadyUnConfirmRetry()) {
                // never retry for unconfirm, we retry once, otherwise just let it go
                request = request.toBuilder().setAlreadyUnConfirmRetry(true).build();
                getSelf().tell(request, null);
                LOGGER.info("jobInstanceId={}, WorkerBatchReportTaskStatuesRequest unconfirm retry", request.getJobInstanceId());
            }
        } else if (msg instanceof WorkerReportJobInstanceStatusRequest) {
            WorkerReportJobInstanceStatusRequest request = (WorkerReportJobInstanceStatusRequest) msg;
            if (!request.hasAlreadyUnConfirmRetry() || !request.getAlreadyUnConfirmRetry()) {
                // never retry for unconfirm, we retry once, otherwise just let it go
                request = request.toBuilder().setAlreadyUnConfirmRetry(true).build();
                getSelf().tell(request, null);
                LOGGER.info("jobInstanceId={}, WorkerReportJobInstanceStatusRequest unconfirm retry", request.getJobInstanceId());
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy