From 4da45ee03dee045904cfe4316653548255dc00b0 Mon Sep 17 00:00:00 2001 From: yfh0918 Date: Wed, 5 Sep 2018 12:36:46 +0800 Subject: [PATCH] Enhance FileRefreshableDataSource and FileWritableDataSource (#125) - Add method to check if the resource is modified in `AutoRefreshDataSource` - Implement FileWritableDataSource --- .../datasource/AutoRefreshDataSource.java | 16 +++++-- .../datasource/FileRefreshableDataSource.java | 42 ++++++++++++------- .../datasource/FileWritableDataSource.java | 26 +++++++++++- 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AutoRefreshDataSource.java b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AutoRefreshDataSource.java index ff85462703..cca5fa6e5c 100755 --- a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AutoRefreshDataSource.java +++ b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/AutoRefreshDataSource.java @@ -25,8 +25,10 @@ /** * A {@link ReadableDataSource} automatically fetches the backend data. * - * @param source data type - * @param target data type + * @param + * source data type + * @param + * target data type * @author Carpenter Lee */ public abstract class AutoRefreshDataSource extends AbstractDataSource { @@ -50,13 +52,15 @@ public AutoRefreshDataSource(Converter configParser, final long recommendR private void startTimerService() { service = Executors.newScheduledThreadPool(1, - new NamedThreadFactory("sentinel-datasource-auto-refresh-task", true)); + new NamedThreadFactory("sentinel-datasource-auto-refresh-task", true)); service.scheduleAtFixedRate(new Runnable() { @Override public void run() { try { + if (!refresh()) { + return; + } T newValue = loadConfig(); - getProperty().updateValue(newValue); } catch (Throwable e) { RecordLog.info("loadConfig exception", e); @@ -72,4 +76,8 @@ public void close() throws Exception { service = null; } } + + protected boolean refresh() { + return true; + } } diff --git a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileRefreshableDataSource.java b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileRefreshableDataSource.java index ac141f8e13..5f8249d6f4 100755 --- a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileRefreshableDataSource.java +++ b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileRefreshableDataSource.java @@ -25,11 +25,12 @@ /** *

- * A {@link ReadableDataSource} based on file. This class will automatically fetches the backend file every refresh period. + * A {@link ReadableDataSource} based on file. This class will automatically + * fetches the backend file every refresh period. *

*

- * Limitations: Default read buffer size is 1 MB. If file size is greater than buffer size, exceeding bytes will - * be ignored. Default charset is UTF-8. + * Limitations: Default read buffer size is 1 MB. If file size is greater than + * buffer size, exceeding bytes will be ignored. Default charset is UTF-8. *

* * @author Carpenter Lee @@ -45,35 +46,37 @@ public class FileRefreshableDataSource extends AutoRefreshDataSource configParser) throws FileNotFoundException { this(file, configParser, DEFAULT_REFRESH_MS, DEFAULT_BUF_SIZE, DEFAULT_CHAR_SET); } - public FileRefreshableDataSource(String fileName, Converter configParser) - throws FileNotFoundException { + public FileRefreshableDataSource(String fileName, Converter configParser) throws FileNotFoundException { this(new File(fileName), configParser, DEFAULT_REFRESH_MS, DEFAULT_BUF_SIZE, DEFAULT_CHAR_SET); } public FileRefreshableDataSource(File file, Converter configParser, int bufSize) - throws FileNotFoundException { + throws FileNotFoundException { this(file, configParser, DEFAULT_REFRESH_MS, bufSize, DEFAULT_CHAR_SET); } public FileRefreshableDataSource(File file, Converter configParser, Charset charset) - throws FileNotFoundException { + throws FileNotFoundException { this(file, configParser, DEFAULT_REFRESH_MS, DEFAULT_BUF_SIZE, charset); } - public FileRefreshableDataSource(File file, Converter configParser, long recommendRefreshMs, - int bufSize, Charset charset) throws FileNotFoundException { + public FileRefreshableDataSource(File file, Converter configParser, long recommendRefreshMs, int bufSize, + Charset charset) throws FileNotFoundException { super(configParser, recommendRefreshMs); if (bufSize <= 0 || bufSize > MAX_SIZE) { throw new IllegalArgumentException("bufSize must between (0, " + MAX_SIZE + "], but " + bufSize + " get"); @@ -87,6 +90,7 @@ public FileRefreshableDataSource(File file, Converter configParser, l this.buf = new byte[bufSize]; this.file = file; this.charset = charset; + this.lastModified = file.lastModified(); firstLoad(); } @@ -107,7 +111,7 @@ public String readSource() throws Exception { FileChannel channel = inputStream.getChannel(); if (channel.size() > buf.length) { throw new IllegalStateException(file.getAbsolutePath() + " file size=" + channel.size() - + ", is bigger than bufSize=" + buf.length + ". Can't read"); + + ", is bigger than bufSize=" + buf.length + ". Can't read"); } int len = inputStream.read(buf); return new String(buf, 0, len, charset); @@ -121,6 +125,16 @@ public String readSource() throws Exception { } } + @Override + protected boolean refresh() { + long curLastModified = new File(file.getAbsolutePath()).lastModified(); + if (curLastModified != this.lastModified) { + this.lastModified = curLastModified; + return true; + } + return false; + } + @Override public void close() throws Exception { super.close(); diff --git a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileWritableDataSource.java b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileWritableDataSource.java index 76e41d054d..f6c41bbdf3 100644 --- a/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileWritableDataSource.java +++ b/sentinel-extension/sentinel-datasource-extension/src/main/java/com/alibaba/csp/sentinel/datasource/FileWritableDataSource.java @@ -16,11 +16,13 @@ package com.alibaba.csp.sentinel.datasource; import java.io.File; +import java.io.FileOutputStream; /** * A {@link WritableDataSource} based on file. * - * @param data type + * @param + * data type * @author Eric Zhao * @since 0.2.0 */ @@ -46,7 +48,27 @@ public FileWritableDataSource(File file, Converter configEncoder) { @Override public void write(T value) throws Exception { - throw new UnsupportedOperationException("Not implemented"); + if (configEncoder == null) { + throw new NullPointerException("configEncoder is null Can't write"); + } + synchronized (file) { + String convertResult = configEncoder.convert(value); + FileOutputStream outputStream = null; + try { + outputStream = new FileOutputStream(file); + byte[] bytesArray = convertResult.getBytes(); + outputStream.write(bytesArray); + outputStream.flush(); + } finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (Exception ignore) { + // nothing + } + } + } + } } @Override