Skip to content

Commit

Permalink
refactor(all): code optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
chuntaojun committed Apr 16, 2020
1 parent 1aca7bc commit 0b3b5e8
Show file tree
Hide file tree
Showing 74 changed files with 1,985 additions and 1,471 deletions.
5 changes: 5 additions & 0 deletions common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
<artifactId>nacos-api</artifactId>
</dependency>

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>

<!-- Test -->
<dependency>
<groupId>junit</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("PMD.ThreadPoolCreationRule")
public class ExecutorFactory {
public final class ExecutorFactory {

private static final ThreadPoolManager THREAD_POOL_MANAGER = ThreadPoolManager.getInstance();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@
* limitations under the License.
*/

package com.alibaba.nacos.core.file;
package com.alibaba.nacos.common.file;

import com.alibaba.nacos.core.notify.Event;
import java.io.Serializable;
import java.nio.file.WatchEvent;

/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class FileChangeEvent implements Event {
public class FileChangeEvent implements Serializable {

private static final long serialVersionUID = -4255584033113954765L;

private String paths;

private WatchEvent<?> event;
private Object context;

public static FileChangeEventBuilder builder() {
return new FileChangeEventBuilder();
Expand All @@ -42,31 +42,23 @@ public void setPaths(String paths) {
this.paths = paths;
}

public WatchEvent<?> getEvent() {
return event;
public Object getContext() {
return context;
}

public void setEvent(WatchEvent<?> event) {
this.event = event;
public void setContext(Object context) {
this.context = context;
}

@Override
public String toString() {
return "FileChangeEvent{" +
"paths='" + paths + '\'' +
", event-kind=" + event.kind() + '\'' +
", even-context=" + event.context() + '\'' +
'}';
}

@Override
public Class<? extends Event> eventType() {
return FileChangeEvent.class;
return "FileChangeEvent{" + "paths='" + paths + '\'' + ", context=" + context
+ '}';
}

public static final class FileChangeEventBuilder {
private String paths;
private WatchEvent<?> event;
private Object context;

private FileChangeEventBuilder() {
}
Expand All @@ -76,15 +68,15 @@ public FileChangeEventBuilder paths(String paths) {
return this;
}

public FileChangeEventBuilder event(WatchEvent<?> event) {
this.event = event;
public FileChangeEventBuilder context(Object context) {
this.context = context;
return this;
}

public FileChangeEvent build() {
FileChangeEvent fileChangeEvent = new FileChangeEvent();
fileChangeEvent.setPaths(paths);
fileChangeEvent.setEvent(event);
fileChangeEvent.setContext(context);
return fileChangeEvent;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,39 @@
* limitations under the License.
*/

package com.alibaba.nacos.core.file;
package com.alibaba.nacos.common.file;

import java.nio.file.WatchEvent;
import java.util.concurrent.Executor;

/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public interface FileWatcher {
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class FileWatcher {

/**
* Triggered when a file change occurs
*
* @param event {@link FileChangeEvent}
*/
void onChange(FileChangeEvent event);
public abstract void onChange(FileChangeEvent event);

/**
* WatchEvent context information
*
* @param context {@link WatchEvent#context()}
* @return is this watcher interest context
*/
boolean interest(String context);
public abstract boolean interest(String context);

/**
* If the FileWatcher has its own thread pool, use this thread
* pool to execute, otherwise use the WatchFileManager thread
*
* @return {@link Executor}
*/
default Executor executor() {
public Executor executor() {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/*
* 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.common.file;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.common.executor.ExecutorFactory;
import com.alibaba.nacos.common.executor.NameThreadFactory;

import java.io.File;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;

/**
* Unified file change monitoring management center, which uses {@link WatchService} internally.
* One file directory corresponds to one {@link WatchService}. It can only monitor up to 32 file
* directories. When a file change occurs, a {@link FileChangeEvent} will be issued
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class WatchFileCenter {

private static final int MAX_WATCH_FILE_JOB = Integer
.getInteger("nacos.watch-file.max-dirs", 16);
private static final Map<String, WatchJob> MANAGER = new HashMap<>(
MAX_WATCH_FILE_JOB);
private static final FileSystem FILE_SYSTEM = FileSystems.getDefault();
private static final ExecutorService WATCH_FILE_EXECUTOR = ExecutorFactory
.newFixExecutorService(WatchFileCenter.class.getCanonicalName(),
MAX_WATCH_FILE_JOB << 1,
new NameThreadFactory("com.alibaba.nacos.common.file.watch"));
private static int NOW_WATCH_JOB_CNT = 0;

public synchronized static boolean registerWatcher(final String paths,
FileWatcher watcher) throws NacosException {
NOW_WATCH_JOB_CNT++;
if (NOW_WATCH_JOB_CNT > MAX_WATCH_FILE_JOB) {
return false;
}
WatchJob job = MANAGER.get(paths);
if (job == null) {
job = new WatchJob(paths);
WATCH_FILE_EXECUTOR.execute(job);
}
job.addSubscribe(watcher);
return true;
}

public synchronized static boolean deregisterWatcher(final String path) {
WatchJob job = MANAGER.get(path);
if (job != null) {
job.shutdown();
MANAGER.remove(path);
return true;
}
return false;
}

private static class WatchJob implements Runnable {

private final String paths;

private WatchService watchService;

private volatile boolean watch = true;

private Set<FileWatcher> watchers = new CopyOnWriteArraySet<>();

public WatchJob(String paths) throws NacosException {
this.paths = paths;

if (!Paths.get(paths).toFile().isDirectory()) {
throw new IllegalArgumentException("Must be a file directory : " + paths);
}

try {
WatchService service = FILE_SYSTEM.newWatchService();
Paths.get(paths).register(service, StandardWatchEventKinds.OVERFLOW,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE);
this.watchService = service;
}
catch (Throwable ex) {
throw new NacosException(NacosException.SERVER_ERROR, ex);
}
}

void addSubscribe(final FileWatcher watcher) {
watchers.add(watcher);
}

void shutdown() {
watch = false;
}

@Override
public void run() {
while (watch) {
try {
WatchKey watchKey = watchService.take();
final List<WatchEvent<?>> events = watchKey.pollEvents();
watchKey.reset();
if (WATCH_FILE_EXECUTOR.isShutdown()) {
return;
}
WATCH_FILE_EXECUTOR.execute(new Runnable() {
@Override
public void run() {
for (WatchEvent<?> event : events) {
WatchEvent.Kind<?> kind = event.kind();

// Since the OS's event cache may be overflow, a backstop is needed
if (StandardWatchEventKinds.OVERFLOW.equals(kind)) {
eventOverflow();
}
else {
eventProcess(event.context());
}
}
}
});
}
catch (InterruptedException ignore) {
Thread.interrupted();
}
}
}

private void eventProcess(Object context) {
final FileChangeEvent fileChangeEvent = FileChangeEvent.builder().paths(paths)
.context(context).build();
String str = String.valueOf(context);
for (final FileWatcher watcher : watchers) {
if (watcher.interest(str)) {
Runnable job = new Runnable() {
@Override
public void run() {
watcher.onChange(fileChangeEvent);
}
};
Executor executor = watcher.executor();
if (executor == null) {
job.run();
}
else {
executor.execute(job);
}
}
}
}

private void eventOverflow() {
File dir = Paths.get(paths).toFile();
for (File file : Objects.requireNonNull(dir.listFiles())) {
if (file.isDirectory()) {
continue;
}
eventProcess(file.getName());
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public class HttpClientManager {
private static final RequestConfig DEFAULT_CONFIG = RequestConfig.custom()
.setConnectTimeout(TIMEOUT).setSocketTimeout(TIMEOUT << 1).build();

public static NSyncHttpClient newHttpClient(String namespace) {
public static NSyncHttpClient newSyncHttpClient(String namespace) {
synchronized (SYNC_MONITOR) {

NSyncHttpClient nSyncHttpClient = HTTP_SYNC_CLIENT_MAP.get(namespace);
Expand Down Expand Up @@ -120,7 +120,7 @@ public static NAsyncHttpClient newAsyncHttpClient(String namespace) {
}
}

public static NSyncHttpClient newHttpClient(String namespace,
public static NSyncHttpClient newSyncHttpClient(String namespace,
RequestConfig requestConfig) {
synchronized (SYNC_MONITOR) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@

package com.alibaba.nacos.common.http.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.GsonUtils;

/**
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public final class RequestHandler {

public static String parse(Object object) {
return JSON.toJSONString(object);
return GsonUtils.toJson(object);
}

}
Loading

0 comments on commit 0b3b5e8

Please sign in to comment.