Skip to content

Commit 286bbc4

Browse files
committed
feat(backend): move command execution logic into separate impl class
1 parent 4065647 commit 286bbc4

File tree

5 files changed

+125
-50
lines changed

5 files changed

+125
-50
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.brotherjing.core.executor;
2+
3+
import java.util.HashMap;
4+
import java.util.List;
5+
import java.util.Map;
6+
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.stereotype.Component;
9+
10+
import com.brotherjing.proto.BaseProto;
11+
12+
@Component
13+
public class CommandExecutorRegistry {
14+
15+
private List<ICommandExecutor> executorList;
16+
17+
private Map<BaseProto.DocType, ICommandExecutor> executorMap;
18+
19+
@Autowired
20+
public CommandExecutorRegistry(List<ICommandExecutor> executorList) {
21+
this.executorList = executorList;
22+
this.executorMap = new HashMap<>();
23+
for (ICommandExecutor executor : executorList) {
24+
executorMap.put(executor.getSupportedType(), executor);
25+
}
26+
}
27+
28+
public ICommandExecutor getCommandExecutor(BaseProto.DocType docType) {
29+
return executorMap.get(docType);
30+
}
31+
32+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.brotherjing.core.executor;
2+
3+
import com.brotherjing.core.dto.SnapshotDto;
4+
import com.brotherjing.proto.BaseProto;
5+
6+
public interface ICommandExecutor {
7+
8+
BaseProto.DocType getSupportedType();
9+
10+
void applySingle(SnapshotDto dto, BaseProto.Command command);
11+
12+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.brotherjing.core.executor.impl;
2+
3+
import java.util.Collections;
4+
import java.util.List;
5+
6+
import lombok.extern.slf4j.Slf4j;
7+
8+
import org.springframework.stereotype.Component;
9+
10+
import com.brotherjing.core.dto.SnapshotDto;
11+
import com.brotherjing.core.executor.ICommandExecutor;
12+
import com.brotherjing.proto.BaseProto;
13+
import com.brotherjing.proto.TextProto;
14+
import com.google.protobuf.InvalidProtocolBufferException;
15+
16+
@Slf4j
17+
@Component
18+
public class TextCommandExecutor implements ICommandExecutor {
19+
20+
@Override
21+
public BaseProto.DocType getSupportedType() {
22+
return BaseProto.DocType.PLAIN_TEXT;
23+
}
24+
25+
@Override
26+
public void applySingle(SnapshotDto dto, BaseProto.Command command) {
27+
log.info("command type is {}", command.getOp().getTypeUrl());
28+
try {
29+
if (command.getOp().is(TextProto.Operation.class)) {
30+
TextProto.Operation op = command.getOp().unpack(TextProto.Operation.class);
31+
applyTextOp(dto, op);
32+
}
33+
} catch (InvalidProtocolBufferException e) {
34+
e.printStackTrace();
35+
}
36+
}
37+
38+
private void applyTextOp(SnapshotDto dto, TextProto.Operation op) {
39+
List<TextProto.Operation> operations;
40+
if (op.hasMultiple()) {
41+
operations = op.getMultiple().getOpsList();
42+
} else {
43+
operations = Collections.singletonList(op);
44+
}
45+
String data = dto.getData();
46+
int index = 0;
47+
for (TextProto.Operation operation : operations) {
48+
switch (operation.getType()) {
49+
case RETAIN:
50+
index += operation.getRetain();
51+
break;
52+
case INSERT:
53+
data = data.substring(0, index)
54+
.concat(operation.getInsert())
55+
.concat(data.substring(index));
56+
index += operation.getInsert().length();
57+
break;
58+
case DELETE:
59+
int right = Math.min(data.length(), index + operation.getDelete().getDelete());
60+
data = data.substring(0, index).concat(data.substring(right));
61+
break;
62+
default:
63+
break;
64+
}
65+
}
66+
dto.setData(data);
67+
}
68+
}

scalable-ot-core/src/main/java/com/brotherjing/core/service/impl/DocServiceImpl.java

Lines changed: 12 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,23 @@
1515
import com.brotherjing.core.dao.DocDao;
1616
import com.brotherjing.core.dto.CommandDto;
1717
import com.brotherjing.core.dto.SnapshotDto;
18+
import com.brotherjing.core.executor.CommandExecutorRegistry;
19+
import com.brotherjing.core.executor.ICommandExecutor;
1820
import com.brotherjing.core.service.DocService;
1921
import com.brotherjing.core.util.Converter;
2022
import com.brotherjing.core.util.IDUtils;
2123
import com.brotherjing.core.util.ShortUUID;
2224
import com.brotherjing.proto.BaseProto;
23-
import com.brotherjing.proto.TextProto;
2425
import com.google.common.annotations.VisibleForTesting;
2526
import com.google.common.collect.Lists;
26-
import com.google.protobuf.InvalidProtocolBufferException;
2727

2828
@Slf4j
2929
@Service
3030
public class DocServiceImpl implements DocService {
3131

32+
@Autowired
33+
private CommandExecutorRegistry registry;
34+
3235
@Autowired
3336
private DocDao docDao;
3437

@@ -119,60 +122,20 @@ public BaseProto.Snapshot apply(String docId, List<BaseProto.Command> commands)
119122
}
120123

121124
private void apply(SnapshotDto dto, List<BaseProto.Command> commands) {
122-
if (commands == null) {
125+
if (commands == null || commands.isEmpty()) {
126+
return;
127+
}
128+
ICommandExecutor executor = registry.getCommandExecutor(commands.get(0).getType());
129+
if (executor == null) {
130+
log.error("Cannot find executor for this command type: {}", commands.get(0).getType().name());
123131
return;
124132
}
125133
for (BaseProto.Command command : commands) {
126-
applySingle(dto, command);
134+
executor.applySingle(dto, command);
127135
dto.setVersion(dto.getVersion() + 1);
128136
}
129137
}
130138

131-
private void applySingle(SnapshotDto dto, BaseProto.Command command) {
132-
if (BaseProto.DocType.PLAIN_TEXT.equals(command.getType())) {
133-
log.info("command type is {}", command.getOp().getTypeUrl());
134-
try {
135-
if (command.getOp().is(TextProto.Operation.class)) {
136-
TextProto.Operation op = command.getOp().unpack(TextProto.Operation.class);
137-
applyTextOp(dto, op);
138-
}
139-
} catch (InvalidProtocolBufferException e) {
140-
e.printStackTrace();
141-
}
142-
}
143-
}
144-
145-
private void applyTextOp(SnapshotDto dto, TextProto.Operation op) {
146-
List<TextProto.Operation> operations;
147-
if (op.hasMultiple()) {
148-
operations = op.getMultiple().getOpsList();
149-
} else {
150-
operations = Collections.singletonList(op);
151-
}
152-
String data = dto.getData();
153-
int index = 0;
154-
for (TextProto.Operation operation : operations) {
155-
switch (operation.getType()) {
156-
case RETAIN:
157-
index += operation.getRetain();
158-
break;
159-
case INSERT:
160-
data = data.substring(0, index)
161-
.concat(operation.getInsert())
162-
.concat(data.substring(index));
163-
index += operation.getInsert().length();
164-
break;
165-
case DELETE:
166-
int right = Math.min(data.length(), index + operation.getDelete().getDelete());
167-
data = data.substring(0, index).concat(data.substring(right));
168-
break;
169-
default:
170-
break;
171-
}
172-
}
173-
dto.setData(data);
174-
}
175-
176139
/**
177140
* Try take snapshot at certain intervals
178141
*

scripts/mongo-start.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#!/usr/bin/env bash
22

3-
docker run -d -p 27017-27019:27017-27019 --name mongodb mongo
3+
docker run -d -p 27017-27019:27017-27019 --name mongodb --rm mongo

0 commit comments

Comments
 (0)