Skip to content

Commit

Permalink
Merge pull request #975 from jifengnan/issue_974
Browse files Browse the repository at this point in the history
[ISSUE #974] ArrayIndexOutOfBoundsException may be thrown when invokes taskDispatcher.addTask
  • Loading branch information
Fury Zhu authored Apr 1, 2019
2 parents 9b7d613 + 180f3a7 commit b1790fa
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.naming.cluster.servers.Server;
import com.alibaba.nacos.naming.misc.GlobalConfig;
import com.alibaba.nacos.naming.misc.GlobalExecutor;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.NetUtils;
import com.alibaba.nacos.naming.misc.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -58,12 +55,8 @@ public void init() {
}
}

public int mapTask(String key) {
return Math.abs(key.hashCode()) % partitionConfig.getTaskDispatchThreadCount();
}

public void addTask(String key) {
taskSchedulerList.get(mapTask(key)).addTask(key);
taskSchedulerList.get(UtilsAndCommons.shakeUp(key, partitionConfig.getTaskDispatchThreadCount())).addTask(key);
}

public class TaskScheduler implements Runnable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,34 @@ public static Map<String, String> parseMetadata(String metadata) throws NacosExc
public static String assembleFullServiceName(String namespaceId, String serviceName) {
return namespaceId + UtilsAndCommons.NAMESPACE_SERVICE_CONNECTOR + serviceName;
}

/**
* 根据指定的字符串计算出一个0(含)到{@code upperLimit}(不含)之间的数字,本方法会试图让不同的字符串较均匀的分布在0到{@code upperLimit}之间。
* (Provide a number between 0(include) and {@code upperLimit}(exclude) for the given {@code string}, the number will be nearly uniform distribution.)
* <p>
* <p>
* 举个例子:假设有N个提供相同服务的服务器地址被存在一个数组中,为了实现负载均衡,可以根据调用者的名字决定使用哪个服务器。
* (e.g. Assume there's an array which contains some IP of the servers provide the same service, the caller name can be used to choose the server to achieve load balance.)
* <blockquote><pre>
* String[] serverIps = new String[10];
* int index = shakeUp("callerName", serverIps.length);
* String targetServerIp = serverIps[index];
* </pre></blockquote>
*
* @param string 字符串。如果为null会固定返回0 (a string. the number 0 will be returned if it's null)
* @param upperLimit 返回值的上限,必须为正整数(>0) (the upper limit of the returned number, must be a positive integer, which means > 0)
* @return 0(含)到upperLimit(不含)之间的一个数字 (a number between 0(include) and upperLimit(exclude))
* @throws IllegalArgumentException if the upper limit equals or less than 0
* @since 1.0.0
*/
public static int shakeUp(String string, int upperLimit) {
if (upperLimit < 1) {
throw new IllegalArgumentException("upper limit must be greater than 0");
}
if (string == null) {
return 0;
}
return (string.hashCode() & Integer.MAX_VALUE) % upperLimit;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.naming.consistency.ephemeral.distro;

import com.alibaba.nacos.naming.misc.GlobalConfig;
import org.junit.Before;
import org.junit.Test;
import org.springframework.test.util.ReflectionTestUtils;

/**
* @author jifengnan
*/
public class TaskDispatcherTest {

private TaskDispatcher taskDispatcher;

@Before
public void init() {
taskDispatcher = new TaskDispatcher();
GlobalConfig conf = new GlobalConfig();
ReflectionTestUtils.setField(conf, "taskDispatchThreadCount", 3);
ReflectionTestUtils.setField(taskDispatcher, "partitionConfig", conf);
taskDispatcher.init();
}

@Test
public void testAddTask() {
char[] chars = new char[]{2325, 9, 30, 12, 2};
taskDispatcher.addTask(new String(chars));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,16 @@ public void testControllerPathsDefaultValues() {

Assert.assertEquals("/nacos/v1/ns", DEFAULT_NACOS_NAMING_CONTEXT);
}

@Test(expected = IllegalArgumentException.class)
public void testShakeUpException() {
UtilsAndCommons.shakeUp(null, 0);
}

@Test
public void testShakeUp() {
Assert.assertEquals(0, UtilsAndCommons.shakeUp(null, 1));
char[] chars = new char[]{2325, 9, 30, 12, 2};
Assert.assertEquals(0, UtilsAndCommons.shakeUp(new String(chars), 1));
}
}

0 comments on commit b1790fa

Please sign in to comment.