Java 带 Mappedbus 的 IPC - 在 EOF 上重置文件
Java IPC with Mappedbus - reset file on EOF
我在两个 JVM 之间使用 Mappedbus 进行 IPC(oracle jdk 1.8,linux arm);
我希望看到 IPC 工作 "forever",但由于内存映射(或共享内存)文件是有限的,因此在作者获得 EOFException 之前或之后。
所以我尝试重置写入器(和 reader),但是关闭并重新打开写入器后,reader 无法读取新记录。
所以,问题是,如何使以下测试用例正常工作,即在 writer 和 reader 工作的情况下永远继续下去?
// intentionally low, for this test case
final long FILE_SIZE = 2000L;
private final String fileName = "/dev/shm/ipc-message";
@Test
public void hello() throws IOException {
MappedBusReader reader;
MappedBusWriter writer;
writer = new MappedBusWriter(fileName, FILE_SIZE, 128, false);
writer.open();
reader = new MappedBusReader(fileName, FILE_SIZE, 128);
reader.open();
int writeCounter = 0;
int readCounter = 0;
while (true) {
IpcMessage message = new IpcMessage();
message.source = 1;
message.value = 1;
message.destination = 2;
message.body = new byte [32];
try {
writer.write(message);
} catch (EOFException ex) {
System.out.println("write EXCEPTION");
writer.close();
writer = new MappedBusWriter(fileName, FILE_SIZE, 128, false);
writer.open();
}
System.out.println("write: " + writeCounter++);
try {
if (reader.next()) {
boolean recovered = reader.hasRecovered();
int type = reader.readType();
System.out.println("read: " + readCounter++);
reader.readMessage(message);
}
} catch (EOFException ex) {
System.out.println("read EXCEPTION");
reader.close();
reader = new MappedBusReader(fileName, FILE_SIZE, 128);
reader.open();
}
}
}
IpcMessage 是:
public class IpcMessage implements MappedBusMessage, Serializable {
public static final int TYPE = 0;
public int messageType;
public int value;
public int source;
public int destination;
@Override
public void write(MemoryMappedFile mem, long pos) {
mem.putInt(pos, messageType);
mem.putInt(pos + 4, value);
mem.putInt(pos + 8, source);
mem.putInt(pos + 12, destination);
}
@Override
public void read(MemoryMappedFile mem, long pos) {
messageType = mem.getInt(pos);
value = mem.getInt(pos + 4);
source = mem.getInt(pos + 8);
destination = mem.getInt(pos + 12);
}
@Override
public int type() {
return TYPE;
}
}
我从这个测试用例中得到的输出是:
write: 0
read: 0
write: 1
read: 1
write: 2
read: 2
...
write: 8
read: 8
write: 9
read: 9
write: 10
read: 10
write: 11
read: 11
write: 12
read: 12
write: 13
read: 13
write EXCEPTION
write: 14
write: 15
write: 16
write: 17
write: 18
write: 19
write: 20
write: 21
write: 22
write: 23
我从 Mappedbus 的开发者那里通过电子邮件收到了对我的问题的回答,我觉得它很有趣所以我把它复制在这里:
This question was briefly answered here:
https://github.com/caplogic/Mappedbus/issues/1
In short, mappedbus is meant for scenarios where you need to store all
messages. If you don't need to do this, it might not be the right
solution.
If you do need to store them, just make the file large enough to be
able to contain all messages during in the life cycle of the system
(for example for one day). And then have a time where you stop all
components, rename the file and start them again.
我在两个 JVM 之间使用 Mappedbus 进行 IPC(oracle jdk 1.8,linux arm); 我希望看到 IPC 工作 "forever",但由于内存映射(或共享内存)文件是有限的,因此在作者获得 EOFException 之前或之后。
所以我尝试重置写入器(和 reader),但是关闭并重新打开写入器后,reader 无法读取新记录。
所以,问题是,如何使以下测试用例正常工作,即在 writer 和 reader 工作的情况下永远继续下去?
// intentionally low, for this test case
final long FILE_SIZE = 2000L;
private final String fileName = "/dev/shm/ipc-message";
@Test
public void hello() throws IOException {
MappedBusReader reader;
MappedBusWriter writer;
writer = new MappedBusWriter(fileName, FILE_SIZE, 128, false);
writer.open();
reader = new MappedBusReader(fileName, FILE_SIZE, 128);
reader.open();
int writeCounter = 0;
int readCounter = 0;
while (true) {
IpcMessage message = new IpcMessage();
message.source = 1;
message.value = 1;
message.destination = 2;
message.body = new byte [32];
try {
writer.write(message);
} catch (EOFException ex) {
System.out.println("write EXCEPTION");
writer.close();
writer = new MappedBusWriter(fileName, FILE_SIZE, 128, false);
writer.open();
}
System.out.println("write: " + writeCounter++);
try {
if (reader.next()) {
boolean recovered = reader.hasRecovered();
int type = reader.readType();
System.out.println("read: " + readCounter++);
reader.readMessage(message);
}
} catch (EOFException ex) {
System.out.println("read EXCEPTION");
reader.close();
reader = new MappedBusReader(fileName, FILE_SIZE, 128);
reader.open();
}
}
}
IpcMessage 是:
public class IpcMessage implements MappedBusMessage, Serializable {
public static final int TYPE = 0;
public int messageType;
public int value;
public int source;
public int destination;
@Override
public void write(MemoryMappedFile mem, long pos) {
mem.putInt(pos, messageType);
mem.putInt(pos + 4, value);
mem.putInt(pos + 8, source);
mem.putInt(pos + 12, destination);
}
@Override
public void read(MemoryMappedFile mem, long pos) {
messageType = mem.getInt(pos);
value = mem.getInt(pos + 4);
source = mem.getInt(pos + 8);
destination = mem.getInt(pos + 12);
}
@Override
public int type() {
return TYPE;
}
}
我从这个测试用例中得到的输出是:
write: 0
read: 0
write: 1
read: 1
write: 2
read: 2
...
write: 8
read: 8
write: 9
read: 9
write: 10
read: 10
write: 11
read: 11
write: 12
read: 12
write: 13
read: 13
write EXCEPTION
write: 14
write: 15
write: 16
write: 17
write: 18
write: 19
write: 20
write: 21
write: 22
write: 23
我从 Mappedbus 的开发者那里通过电子邮件收到了对我的问题的回答,我觉得它很有趣所以我把它复制在这里:
This question was briefly answered here: https://github.com/caplogic/Mappedbus/issues/1
In short, mappedbus is meant for scenarios where you need to store all messages. If you don't need to do this, it might not be the right solution.
If you do need to store them, just make the file large enough to be able to contain all messages during in the life cycle of the system (for example for one day). And then have a time where you stop all components, rename the file and start them again.