Skip to content

Commit 9d4b6cb

Browse files
carryxyhbeiwei30
authored andcommitted
Optimize retry for FailbackRegistry. (#2763)
* Abstract retry task * Task for retry. * Fix sth. * Finish Optimize. fix ci failed. * Optimize retry for FailbackRegistry. The retry operation splits into specific operations, such as subscriptions and registrations. This approach allows for very precise retry control. * Optimize retry for FailbackRegistry. The retry operation splits into specific operations, such as subscriptions and registrations. This approach allows for very precise retry control. * Optimize logger warn's msg. * Optimize FailedNotifiedTask's run method. Optimize addXXXTask, directly return if we already have a retry task. * Optimize notify logic, just notify when the urls is not empty. * Optimize notify logic, just notify when the urls is not empty. * Optimize timer that use daemon thread.
1 parent ce4defa commit 9d4b6cb

File tree

11 files changed

+567
-247
lines changed

11 files changed

+567
-247
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dubbo.registry.retry;
19+
20+
import org.apache.dubbo.common.Constants;
21+
import org.apache.dubbo.common.URL;
22+
import org.apache.dubbo.common.logger.Logger;
23+
import org.apache.dubbo.common.logger.LoggerFactory;
24+
import org.apache.dubbo.common.timer.Timeout;
25+
import org.apache.dubbo.common.timer.Timer;
26+
import org.apache.dubbo.common.timer.TimerTask;
27+
import org.apache.dubbo.common.utils.StringUtils;
28+
import org.apache.dubbo.registry.support.FailbackRegistry;
29+
30+
import java.util.concurrent.TimeUnit;
31+
32+
/**
33+
* AbstractRetryTask
34+
*/
35+
public abstract class AbstractRetryTask implements TimerTask {
36+
37+
protected final Logger logger = LoggerFactory.getLogger(getClass());
38+
39+
/**
40+
* url for retry task
41+
*/
42+
protected final URL url;
43+
44+
/**
45+
* registry for this task
46+
*/
47+
protected final FailbackRegistry registry;
48+
49+
/**
50+
* retry period
51+
*/
52+
protected final long retryPeriod;
53+
54+
/**
55+
* task name for this task
56+
*/
57+
protected final String taskName;
58+
59+
private volatile boolean cancel;
60+
61+
AbstractRetryTask(URL url, FailbackRegistry registry, String taskName) {
62+
if (url == null || StringUtils.isBlank(taskName)) {
63+
throw new IllegalArgumentException();
64+
}
65+
this.url = url;
66+
this.registry = registry;
67+
this.taskName = taskName;
68+
cancel = false;
69+
this.retryPeriod = url.getParameter(Constants.REGISTRY_RETRY_PERIOD_KEY, Constants.DEFAULT_REGISTRY_RETRY_PERIOD);
70+
}
71+
72+
public void cancel() {
73+
cancel = true;
74+
}
75+
76+
public boolean isCancel() {
77+
return cancel;
78+
}
79+
80+
protected void reput(Timeout timeout, long tick) {
81+
if (timeout == null) {
82+
throw new IllegalArgumentException();
83+
}
84+
85+
Timer timer = timeout.timer();
86+
if (timer.isStop() || timeout.isCancelled() || isCancel()) {
87+
return;
88+
}
89+
90+
timer.newTimeout(timeout.task(), tick, TimeUnit.MILLISECONDS);
91+
}
92+
93+
@Override
94+
public void run(Timeout timeout) throws Exception {
95+
if (timeout.isCancelled() || timeout.timer().isStop() || isCancel()) {
96+
// other thread cancel this timeout or stop the timer.
97+
return;
98+
}
99+
if (logger.isInfoEnabled()) {
100+
logger.info(taskName + " : " + url);
101+
}
102+
try {
103+
doRetry(url, registry, timeout);
104+
} catch (Throwable t) { // Ignore all the exceptions and wait for the next retry
105+
logger.warn("Failed to execute task " + taskName + ", url: " + url + ", waiting for again, cause:" + t.getMessage(), t);
106+
// reput this task when catch exception.
107+
reput(timeout, retryPeriod);
108+
}
109+
}
110+
111+
protected abstract void doRetry(URL url, FailbackRegistry registry, Timeout timeout);
112+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dubbo.registry.retry;
19+
20+
import org.apache.dubbo.common.URL;
21+
import org.apache.dubbo.common.timer.Timeout;
22+
import org.apache.dubbo.common.utils.CollectionUtils;
23+
import org.apache.dubbo.registry.NotifyListener;
24+
import org.apache.dubbo.registry.support.FailbackRegistry;
25+
26+
import java.util.List;
27+
import java.util.concurrent.CopyOnWriteArrayList;
28+
29+
/**
30+
* FailedNotifiedTask
31+
*/
32+
public final class FailedNotifiedTask extends AbstractRetryTask {
33+
34+
private static final String NAME = "retry subscribe";
35+
36+
private final NotifyListener listener;
37+
38+
private final List<URL> urls = new CopyOnWriteArrayList<>();
39+
40+
public FailedNotifiedTask(URL url, NotifyListener listener) {
41+
super(url, null, NAME);
42+
if (listener == null) {
43+
throw new IllegalArgumentException();
44+
}
45+
this.listener = listener;
46+
}
47+
48+
public void addUrlToRetry(List<URL> urls) {
49+
if (CollectionUtils.isEmpty(urls)) {
50+
return;
51+
}
52+
this.urls.addAll(urls);
53+
}
54+
55+
public void removeRetryUrl(List<URL> urls) {
56+
this.urls.removeAll(urls);
57+
}
58+
59+
@Override
60+
protected void doRetry(URL url, FailbackRegistry registry, Timeout timeout) {
61+
if (CollectionUtils.isNotEmpty(urls)) {
62+
listener.notify(urls);
63+
urls.clear();
64+
}
65+
reput(timeout, retryPeriod);
66+
}
67+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dubbo.registry.retry;
19+
20+
import org.apache.dubbo.common.URL;
21+
import org.apache.dubbo.common.timer.Timeout;
22+
import org.apache.dubbo.registry.support.FailbackRegistry;
23+
24+
/**
25+
* FailedRegisteredTask
26+
*/
27+
public final class FailedRegisteredTask extends AbstractRetryTask {
28+
29+
private static final String NAME = "retry register";
30+
31+
public FailedRegisteredTask(URL url, FailbackRegistry registry) {
32+
super(url, registry, NAME);
33+
}
34+
35+
@Override
36+
protected void doRetry(URL url, FailbackRegistry registry, Timeout timeout) {
37+
registry.doRegister(url);
38+
registry.removeFailedRegisteredTask(url);
39+
}
40+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dubbo.registry.retry;
19+
20+
import org.apache.dubbo.common.URL;
21+
import org.apache.dubbo.common.timer.Timeout;
22+
import org.apache.dubbo.registry.NotifyListener;
23+
import org.apache.dubbo.registry.support.FailbackRegistry;
24+
25+
/**
26+
* FailedSubscribedTask
27+
*/
28+
public final class FailedSubscribedTask extends AbstractRetryTask {
29+
30+
private static final String NAME = "retry subscribe";
31+
32+
private final NotifyListener listener;
33+
34+
public FailedSubscribedTask(URL url, FailbackRegistry registry, NotifyListener listener) {
35+
super(url, registry, NAME);
36+
if (listener == null) {
37+
throw new IllegalArgumentException();
38+
}
39+
this.listener = listener;
40+
}
41+
42+
@Override
43+
protected void doRetry(URL url, FailbackRegistry registry, Timeout timeout) {
44+
registry.doSubscribe(url, listener);
45+
registry.removeFailedSubscribedTask(url, listener);
46+
}
47+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dubbo.registry.retry;
19+
20+
import org.apache.dubbo.common.URL;
21+
import org.apache.dubbo.common.timer.Timeout;
22+
import org.apache.dubbo.registry.support.FailbackRegistry;
23+
24+
/**
25+
* FailedUnregisteredTask
26+
*/
27+
public final class FailedUnregisteredTask extends AbstractRetryTask {
28+
29+
private static final String NAME = "retry unregister";
30+
31+
public FailedUnregisteredTask(URL url, FailbackRegistry registry) {
32+
super(url, registry, NAME);
33+
}
34+
35+
@Override
36+
protected void doRetry(URL url, FailbackRegistry registry, Timeout timeout) {
37+
registry.doUnregister(url);
38+
registry.removeFailedUnregisteredTask(url);
39+
}
40+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dubbo.registry.retry;
19+
20+
import org.apache.dubbo.common.URL;
21+
import org.apache.dubbo.common.timer.Timeout;
22+
import org.apache.dubbo.registry.NotifyListener;
23+
import org.apache.dubbo.registry.support.FailbackRegistry;
24+
25+
/**
26+
* FailedUnsubscribedTask
27+
*/
28+
public final class FailedUnsubscribedTask extends AbstractRetryTask {
29+
30+
private static final String NAME = "retry unsubscribe";
31+
32+
private final NotifyListener listener;
33+
34+
public FailedUnsubscribedTask(URL url, FailbackRegistry registry, NotifyListener listener) {
35+
super(url, registry, NAME);
36+
if (listener == null) {
37+
throw new IllegalArgumentException();
38+
}
39+
this.listener = listener;
40+
}
41+
42+
@Override
43+
protected void doRetry(URL url, FailbackRegistry registry, Timeout timeout) {
44+
registry.unsubscribe(url, listener);
45+
registry.removeFailedUnsubscribedTask(url, listener);
46+
}
47+
}

0 commit comments

Comments
 (0)