| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.dubbo.registry.retry; |
| |
| import org.apache.dubbo.common.URL; |
| import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; |
| import org.apache.dubbo.common.logger.LoggerFactory; |
| import org.apache.dubbo.common.timer.Timeout; |
| import org.apache.dubbo.common.timer.Timer; |
| import org.apache.dubbo.common.timer.TimerTask; |
| import org.apache.dubbo.common.utils.StringUtils; |
| import org.apache.dubbo.registry.support.FailbackRegistry; |
| |
| import java.util.concurrent.TimeUnit; |
| |
| import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_EXECUTE_RETRYING_TASK; |
| import static org.apache.dubbo.registry.Constants.DEFAULT_REGISTRY_RETRY_PERIOD; |
| import static org.apache.dubbo.registry.Constants.DEFAULT_REGISTRY_RETRY_TIMES; |
| import static org.apache.dubbo.registry.Constants.REGISTRY_RETRY_PERIOD_KEY; |
| import static org.apache.dubbo.registry.Constants.REGISTRY_RETRY_TIMES_KEY; |
| |
| /** |
| * AbstractRetryTask |
| */ |
| public abstract class AbstractRetryTask implements TimerTask { |
| |
| protected final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(getClass()); |
| |
| /** |
| * url for retry task |
| */ |
| protected final URL url; |
| |
| /** |
| * registry for this task |
| */ |
| protected final FailbackRegistry registry; |
| |
| /** |
| * retry period |
| */ |
| private final long retryPeriod; |
| |
| /** |
| * define the most retry times |
| */ |
| private final int retryTimes; |
| |
| /** |
| * task name for this task |
| */ |
| private final String taskName; |
| |
| /** |
| * times of retry. |
| * retry task is execute in single thread so that the times is not need volatile. |
| */ |
| private int times = 1; |
| |
| private volatile boolean cancel; |
| |
| AbstractRetryTask(URL url, FailbackRegistry registry, String taskName) { |
| if (url == null || StringUtils.isBlank(taskName)) { |
| throw new IllegalArgumentException(); |
| } |
| this.url = url; |
| this.registry = registry; |
| this.taskName = taskName; |
| this.cancel = false; |
| this.retryPeriod = url.getParameter(REGISTRY_RETRY_PERIOD_KEY, DEFAULT_REGISTRY_RETRY_PERIOD); |
| this.retryTimes = url.getParameter(REGISTRY_RETRY_TIMES_KEY, DEFAULT_REGISTRY_RETRY_TIMES); |
| } |
| |
| public void cancel() { |
| cancel = true; |
| } |
| |
| public boolean isCancel() { |
| return cancel; |
| } |
| |
| protected void reput(Timeout timeout, long tick) { |
| if (timeout == null) { |
| throw new IllegalArgumentException(); |
| } |
| |
| Timer timer = timeout.timer(); |
| if (timer.isStop() || timeout.isCancelled() || isCancel()) { |
| return; |
| } |
| times++; |
| timer.newTimeout(timeout.task(), tick, TimeUnit.MILLISECONDS); |
| } |
| |
| @Override |
| public void run(Timeout timeout) throws Exception { |
| if (timeout.isCancelled() || timeout.timer().isStop() || isCancel()) { |
| // other thread cancel this timeout or stop the timer. |
| return; |
| } |
| if (times > retryTimes) { |
| // 1-13 - failed to execute the retrying task. |
| |
| logger.warn( |
| REGISTRY_EXECUTE_RETRYING_TASK, "registry center offline", "Check the registry server.", |
| "Final failed to execute task " + taskName + ", url: " + url + ", retry " + retryTimes + " times."); |
| |
| return; |
| } |
| if (logger.isInfoEnabled()) { |
| logger.info(taskName + " : " + url); |
| } |
| try { |
| doRetry(url, registry, timeout); |
| } catch (Throwable t) { // Ignore all the exceptions and wait for the next retry |
| |
| // 1-13 - failed to execute the retrying task. |
| |
| logger.warn(REGISTRY_EXECUTE_RETRYING_TASK, "registry center offline", "Check the registry server.", |
| "Failed to execute task " + taskName + ", url: " + url + ", waiting for again, cause:" + t.getMessage(), t); |
| |
| // reput this task when catch exception. |
| reput(timeout, retryPeriod); |
| } |
| } |
| |
| protected abstract void doRetry(URL url, FailbackRegistry registry, Timeout timeout); |
| } |