mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-12 14:40:46 +00:00
#1431 - Refactor internals for RemoteTransactionEvent binary serialisation
This commit is contained in:
1 parent
4f1f3cadf9
commit
e1d4159453
21 files changed
+306
-553
No files matched your search
@@ -1,8 +1,9 @@
|
||||
package io.ebeaninternal.server.transaction;
|
||||
|
||||
import io.ebeaninternal.api.BinaryReadContext;
|
||||
import io.ebeaninternal.api.BinaryWritable;
|
||||
import io.ebeaninternal.api.BinaryWriteContext;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.server.cluster.binarymessage.BinaryMessage;
|
||||
import io.ebeaninternal.server.cluster.binarymessage.BinaryMessageList;
|
||||
import io.ebeaninternal.server.core.PersistRequest;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.id.IdBinder;
|
||||
@@ -27,7 +28,7 @@ import java.util.List;
|
||||
* size of data sent around the network.
|
||||
* </p>
|
||||
*/
|
||||
public class BeanPersistIds {
|
||||
public class BeanPersistIds implements BinaryWritable {
|
||||
|
||||
private final BeanDescriptor<?> beanDescriptor;
|
||||
|
||||
@@ -45,21 +46,20 @@ public class BeanPersistIds {
|
||||
this.descriptorId = desc.getDescriptorId();
|
||||
}
|
||||
|
||||
public static BeanPersistIds readBinaryMessage(SpiEbeanServer server, DataInput dataInput) throws IOException {
|
||||
public static BeanPersistIds readBinaryMessage(SpiEbeanServer server, BinaryReadContext input) throws IOException {
|
||||
|
||||
String descriptorId = dataInput.readUTF();
|
||||
BeanDescriptor<?> desc = server.getBeanDescriptorById(descriptorId);
|
||||
BeanDescriptor<?> desc = server.getBeanDescriptorById(input.readUTF());
|
||||
BeanPersistIds bp = new BeanPersistIds(desc);
|
||||
bp.read(dataInput);
|
||||
bp.read(input);
|
||||
return bp;
|
||||
}
|
||||
|
||||
private void read(DataInput dataInput) throws IOException {
|
||||
private void read(BinaryReadContext dataInput) throws IOException {
|
||||
|
||||
IdBinder idBinder = beanDescriptor.getIdBinder();
|
||||
|
||||
int iudType = dataInput.readInt();
|
||||
List<Object> idList = readIdList(dataInput, idBinder);
|
||||
List<Object> idList = readIdList(dataInput.in(), idBinder);
|
||||
switch (iudType) {
|
||||
case 0:
|
||||
insertIds = idList;
|
||||
@@ -76,20 +76,28 @@ public class BeanPersistIds {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the contents into a BinaryMessage form.
|
||||
* <p>
|
||||
* For a RemoteBeanPersist with a large number of id's note that this is
|
||||
* broken up into many BinaryMessages each with a maximum of 100 ids. This
|
||||
* enables the contents of a large RemoteTransactionEvent to be split up
|
||||
* across multiple Packets.
|
||||
* </p>
|
||||
*/
|
||||
void writeBinaryMessage(BinaryMessageList msgList) throws IOException {
|
||||
@Override
|
||||
public void writeBinary(BinaryWriteContext out) throws IOException {
|
||||
writeBinaryList(out, 0, insertIds);
|
||||
writeBinaryList(out, 1, updateIds);
|
||||
writeBinaryList(out, 2, deleteIds);
|
||||
}
|
||||
|
||||
writeIdList(beanDescriptor, 0, insertIds, msgList);
|
||||
writeIdList(beanDescriptor, 1, updateIds, msgList);
|
||||
writeIdList(beanDescriptor, 2, deleteIds, msgList);
|
||||
private void writeBinaryList(BinaryWriteContext out, int type, List<Object> ids) throws IOException {
|
||||
|
||||
if (ids != null) {
|
||||
IdBinder idBinder = beanDescriptor.getIdBinder();
|
||||
int count = ids.size();
|
||||
|
||||
DataOutputStream os = out.start(TYPE_BEANIUD);
|
||||
os.writeUTF(descriptorId);
|
||||
os.writeInt(type);
|
||||
os.writeInt(count);
|
||||
for (Object insertId : ids) {
|
||||
idBinder.writeData(os, insertId);
|
||||
}
|
||||
os.flush();
|
||||
}
|
||||
}
|
||||
|
||||
private List<Object> readIdList(DataInput dataInput, IdBinder idBinder) throws IOException {
|
||||
@@ -105,48 +113,6 @@ public class BeanPersistIds {
|
||||
return idList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a BinaryMessage containing the descriptorId, iudType and list of Id
|
||||
* values.
|
||||
* <p>
|
||||
* Note that a given BinaryMessage has a maximum of 100 Ids. This is due to
|
||||
* the limit of UDP packet sizes. We break up the RemoteBeanPersist into
|
||||
* potentially many smaller BinaryMessages which may be put into multiple
|
||||
* Packets.
|
||||
* </p>
|
||||
*/
|
||||
private void writeIdList(BeanDescriptor<?> desc, int iudType, List<Object> idList, BinaryMessageList msgList) throws IOException {
|
||||
|
||||
IdBinder idBinder = desc.getIdBinder();
|
||||
|
||||
int count = idList == null ? 0 : idList.size();
|
||||
if (count > 0) {
|
||||
int loop = 0;
|
||||
int i = 0;
|
||||
int eof = idList.size();
|
||||
do {
|
||||
++loop;
|
||||
int endOfLoop = Math.min(eof, loop * 100);
|
||||
|
||||
BinaryMessage m = new BinaryMessage(endOfLoop * 4 + 20);
|
||||
|
||||
DataOutputStream os = m.getOs();
|
||||
os.writeInt(BinaryMessage.TYPE_BEANIUD);
|
||||
os.writeUTF(descriptorId);
|
||||
os.writeInt(iudType);
|
||||
os.writeInt(count);
|
||||
|
||||
for (; i < endOfLoop; i++) {
|
||||
idBinder.writeData(os, idList.get(i));
|
||||
}
|
||||
|
||||
os.close();
|
||||
msgList.add(m);
|
||||
|
||||
} while (i < eof);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package io.ebeaninternal.server.transaction;
|
||||
|
||||
import io.ebeaninternal.server.cluster.binarymessage.BinaryMessage;
|
||||
import io.ebeaninternal.server.cluster.binarymessage.BinaryMessageList;
|
||||
import io.ebeaninternal.api.BinaryReadContext;
|
||||
import io.ebeaninternal.api.BinaryWritable;
|
||||
import io.ebeaninternal.api.BinaryWriteContext;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class RemoteTableMod {
|
||||
public class RemoteTableMod implements BinaryWritable {
|
||||
|
||||
private final long timestamp;
|
||||
|
||||
@@ -28,7 +28,7 @@ public class RemoteTableMod {
|
||||
return tables;
|
||||
}
|
||||
|
||||
public static RemoteTableMod readBinaryMessage(DataInput dataInput) throws IOException {
|
||||
public static RemoteTableMod readBinaryMessage(BinaryReadContext dataInput) throws IOException {
|
||||
|
||||
long timestamp = dataInput.readLong();
|
||||
int count = dataInput.readInt();
|
||||
@@ -40,16 +40,14 @@ public class RemoteTableMod {
|
||||
return new RemoteTableMod(timestamp, tables);
|
||||
}
|
||||
|
||||
public void writeBinary(BinaryMessageList msgList) throws IOException {
|
||||
BinaryMessage msg = new BinaryMessage(tables.size() * 20 + 30);
|
||||
DataOutputStream os = msg.getOs();
|
||||
os.writeInt(BinaryMessage.TYPE_TABLEMOD);
|
||||
@Override
|
||||
public void writeBinary(BinaryWriteContext out) throws IOException {
|
||||
DataOutputStream os = out.start(TYPE_TABLEMOD);
|
||||
os.writeLong(timestamp);
|
||||
os.writeInt(tables.size());
|
||||
for (String table : tables) {
|
||||
os.writeUTF(table);
|
||||
}
|
||||
os.close();
|
||||
msgList.add(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +1,20 @@
|
||||
package io.ebeaninternal.server.transaction;
|
||||
|
||||
import io.ebeaninternal.api.BinaryReadContext;
|
||||
import io.ebeaninternal.api.BinaryWritable;
|
||||
import io.ebeaninternal.api.BinaryWriteContext;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.TransactionEventTable;
|
||||
import io.ebeaninternal.api.TransactionEventTable.TableIUD;
|
||||
import io.ebeaninternal.server.cache.RemoteCacheEvent;
|
||||
import io.ebeaninternal.server.cluster.binarymessage.BinaryMessageList;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RemoteTransactionEvent implements Runnable {
|
||||
public class RemoteTransactionEvent implements Runnable, BinaryWritable {
|
||||
|
||||
private final List<BeanPersistIds> beanPersistList = new ArrayList<>();
|
||||
|
||||
@@ -25,10 +30,16 @@ public class RemoteTransactionEvent implements Runnable {
|
||||
|
||||
private transient SpiEbeanServer server;
|
||||
|
||||
/**
|
||||
* Create for sending to other servers in the cluster.
|
||||
*/
|
||||
public RemoteTransactionEvent(String serverName) {
|
||||
this.serverName = serverName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create from Reading and processing from remote server.
|
||||
*/
|
||||
public RemoteTransactionEvent(SpiEbeanServer server) {
|
||||
this.server = server;
|
||||
}
|
||||
@@ -53,30 +64,86 @@ public class RemoteTransactionEvent implements Runnable {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void writeBinaryMessage(BinaryMessageList msgList) throws IOException {
|
||||
/**
|
||||
* Read the binary message.
|
||||
*/
|
||||
public void readBinary(BinaryReadContext dataInput) throws IOException {
|
||||
|
||||
boolean more = dataInput.readBoolean();
|
||||
while (more) {
|
||||
int msgType = dataInput.readInt();
|
||||
readBinaryMessage(msgType, dataInput);
|
||||
more = dataInput.readBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
private void readBinaryMessage(int msgType, BinaryReadContext dataInput) throws IOException {
|
||||
|
||||
switch (msgType) {
|
||||
case BinaryWritable.TYPE_BEANIUD:
|
||||
addBeanPersistIds(BeanPersistIds.readBinaryMessage(server, dataInput));
|
||||
break;
|
||||
|
||||
case BinaryWritable.TYPE_TABLEIUD:
|
||||
addTableIUD(TransactionEventTable.TableIUD.readBinaryMessage(dataInput));
|
||||
break;
|
||||
|
||||
case BinaryWritable.TYPE_CACHE:
|
||||
addRemoteCacheEvent(RemoteCacheEvent.readBinaryMessage(dataInput));
|
||||
break;
|
||||
|
||||
case BinaryWritable.TYPE_TABLEMOD:
|
||||
addRemoteTableMod(RemoteTableMod.readBinaryMessage(dataInput));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Invalid Transaction msgType " + msgType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a binary message to byte array given an initial buffer size.
|
||||
*/
|
||||
public byte[] writeBinaryAsBytes(int bufferSize) throws IOException {
|
||||
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(bufferSize);
|
||||
DataOutputStream out = new DataOutputStream(buffer);
|
||||
BinaryWriteContext context = new BinaryWriteContext(out);
|
||||
|
||||
writeBinary(context);
|
||||
out.close();
|
||||
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBinary(BinaryWriteContext out) throws IOException {
|
||||
|
||||
DataOutputStream os = out.os();
|
||||
//os.writeInt(TRANSACTION_EVENT);
|
||||
os.writeUTF(serverName);
|
||||
|
||||
if (remoteTableMod != null) {
|
||||
remoteTableMod.writeBinary(msgList);
|
||||
remoteTableMod.writeBinary(out);
|
||||
}
|
||||
|
||||
if (tableList != null) {
|
||||
for (TableIUD aTableList : tableList) {
|
||||
aTableList.writeBinaryMessage(msgList);
|
||||
aTableList.writeBinary(out);
|
||||
}
|
||||
}
|
||||
|
||||
if (deleteByIdMap != null) {
|
||||
for (BeanPersistIds deleteIds : deleteByIdMap.values()) {
|
||||
deleteIds.writeBinaryMessage(msgList);
|
||||
deleteIds.writeBinary(out);
|
||||
}
|
||||
}
|
||||
|
||||
for (BeanPersistIds aBeanPersistList : beanPersistList) {
|
||||
aBeanPersistList.writeBinaryMessage(msgList);
|
||||
aBeanPersistList.writeBinary(out);
|
||||
}
|
||||
if (remoteCacheEvent != null) {
|
||||
remoteCacheEvent.writeBinaryMessage(msgList);
|
||||
remoteCacheEvent.writeBinary(out);
|
||||
}
|
||||
out.end();
|
||||
os.flush();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
|
||||
Reference in new issue
Block a user