我正在使用Chronicle 4.5.27。
下面是使用StoreFileListner的Writer和Reader的简单实现。在Reader中,我获得了多个onAcquired和onReleased事件。
为什么会这样?我期待只收到一个Acquire(当获取文件时读取)和一个Release(读取完成后)。
在下面的Reader日志中,可以看到多个onAcquired和onReleased事件。
请注意此行为是随机的。另请注意,使用Jvm.pause故意减慢Writer的速度,以便模拟可能无法连续获得数据的真实系统。
import net.openhft.chronicle.queue.RollCycles;
import net.openhft.chronicle.queue.impl.StoreFileListener;
import net.openhft.chronicle.queue.impl.single.SingleChronicleQueue;
import net.openhft.chronicle.queue.impl.single.SingleChronicleQueueBuilder;
import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class ChronicleFactory {
public SingleChronicleQueue createChronicle(String instance, String persistenceDir, RollCycles rollCycles) {
SingleChronicleQueue chronicle = null;
try {
chronicle = SingleChronicleQueueBuilder.binary(persistenceDir).rollCycle(rollCycles).storeFileListener(new StoreFileListener() {
@Override
public void onReleased(int i, File file) {
String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
System.out.println(currentTime + ": " + Thread.currentThread().getName() + " onReleased called for file: " + file.getAbsolutePath() + " for cycle: " + i);
}
@Override
public void onAcquired(int cycle, File file) {
String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
System.out.println(currentTime + ": " + Thread.currentThread().getName() + " onAcquired called for file: " + file.getAbsolutePath() + " for cycle: " + cycle);
}
}).build();
} catch (Exception e) {
e.printStackTrace();
}
return chronicle;
}
}
import net.openhft.chronicle.core.Jvm;
import net.openhft.chronicle.queue.ExcerptAppender;
import net.openhft.chronicle.queue.RollCycles;
import net.openhft.chronicle.queue.impl.single.SingleChronicleQueue;
import org.apache.commons.lang3.RandomStringUtils;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicLong;
public class MarketDataWriter {
private static AtomicLong dataSeq = new AtomicLong();
private static long longSequence = 0;
private static int intSequence = 0;
public static void main(String args[]) {
String path = "C:\\Logs\\ChronicleData\\marketdata";
writeMarketData(path);
}
private static void writeMarketData(String path) {
ChronicleFactory chronicleFactory = new ChronicleFactory();
SingleChronicleQueue chronicle = chronicleFactory.createChronicle("MD", path, RollCycles.MINUTELY);
ExcerptAppender appender = chronicle.acquireAppender();
while (true) {
Jvm.pause(100); //NOTE: Slowing down writer to understand file rolling
appender.writeBytes(b -> {
b.writeLong(getLongSequence());
b.writeInt(getIntSequence());
});
}
}
private static long getLongSequence() {
return longSequence++;
}
private static int getIntSequence() {
return intSequence++;
}
}
import net.openhft.chronicle.queue.ExcerptTailer;
import net.openhft.chronicle.queue.RollCycles;
import net.openhft.chronicle.queue.impl.single.SingleChronicleQueue;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SimpleMarketDataReader {
private static final ExecutorService executor = Executors.newCachedThreadPool();
public static void main(String args[]) {
String pathForMarketData = "C:\\Logs\\ChronicleData\\marketdata";
readMarketData(pathForMarketData);
}
public static void readMarketData(String pathForMarketDataFile) {
ChronicleFactory chronicleFactory = new ChronicleFactory();
SingleChronicleQueue chronicle = chronicleFactory.createChronicle("Reader", pathForMarketDataFile, RollCycles.MINUTELY);
//Create another thread to read same file
SimpleMarketDataReaderNewChronicle simpleMarketDataReaderNewChronicle = new SimpleMarketDataReaderNewChronicle();
executor.submit(simpleMarketDataReaderNewChronicle);
ExcerptTailer tailer = chronicle.createTailer();
try {
while (true) {
tailer.readBytes(b -> {
b.readLong();
b.readInt();
//System.out.println("Long Sequence in SimpleMarketDataReader: " + b.readLong());
//System.out.println("User data is: " + userData);
//System.out.println("Int Sequence is: " + b.readInt());
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
作家输出:
2018 -01-03 09:36:00.079:main onAcquired调用文件:C:\ Logs \ ChronicleData \ marketdata \ 20180103-0936.cq4for cycle:25249536
2018 -01-03 09:37:00.098:main onReleased调用文件:C:\ Logs \ ChronicleData \ marketdata \ 20180103-0936.cq4for cycle:25249536
读者输出:
2018 -01-03 09:36:00.065:main onAcquired调用文件:C:\ Logs \ ChronicleData \ marketdata \ 20180103-0936.cq4for cycle:25249536
2018 -01-03 09:36:00.075:main onReleased调用文件:C:\ Logs \ ChronicleData \ marketdata \ 20180103-0936.cq4for cycle:25249536
2018 -01-03 09:36:00.078:main onAcquired调用文件:C:\ Logs \ ChronicleData \ marketdata \ 20180103-0936.cq4for cycle:25249536
2018 -01-03 09:36:00.082:main onReleased调用文件:C:\ Logs \ ChronicleData \ marketdata \ 20180103-0936.cq4for cycle:25249536
2018 -01-03 09:36:00.086:main onAcquired调用文件:C:\ Logs \ ChronicleData \ marketdata \ 20180103-0936.cq4for cycle:25249536
2018 -01-03 09:37:00.103:main onReleased调用文件:C:\ Logs \ ChronicleData \ marketdata \ 20180103-0936.cq4for cycle:25249536