Skip to content

Commit 86ef175

Browse files
committed
Optimization and informer system rework
1 parent 37df14f commit 86ef175

File tree

8 files changed

+209
-86
lines changed

8 files changed

+209
-86
lines changed

common/src/main/java/fr/epsilon/common/Epsilon.java

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,29 @@
77
import fr.epsilon.common.instance.EInstanceModule;
88
import fr.epsilon.common.queue.EQueueModule;
99
import fr.epsilon.common.template.ETemplate;
10+
import io.kubernetes.client.informer.ResourceEventHandler;
11+
import io.kubernetes.client.informer.SharedIndexInformer;
12+
import io.kubernetes.client.informer.SharedInformer;
1013
import io.kubernetes.client.informer.SharedInformerFactory;
14+
import io.kubernetes.client.informer.cache.Lister;
1115
import io.kubernetes.client.openapi.ApiClient;
16+
import io.kubernetes.client.openapi.ApiException;
17+
import io.kubernetes.client.openapi.models.V1ObjectMeta;
1218
import io.kubernetes.client.util.Config;
1319
import io.kubernetes.client.util.generic.GenericKubernetesApi;
20+
import io.kubernetes.client.util.generic.KubernetesApiResponse;
1421
import okhttp3.*;
1522

1623
import java.io.FileReader;
1724
import java.io.IOException;
25+
import java.nio.file.Files;
26+
import java.nio.file.Path;
27+
import java.nio.file.Paths;
1828
import java.util.concurrent.CompletableFuture;
29+
import java.util.concurrent.TimeUnit;
1930
import java.util.logging.Logger;
31+
import java.util.stream.Collectors;
32+
import java.util.stream.Stream;
2033

2134
public class Epsilon {
2235
private static Epsilon singleton;
@@ -26,17 +39,29 @@ public class Epsilon {
2639
private final EInstanceModule instanceModule;
2740
private final EQueueModule queueModule;
2841

42+
private String namespace;
43+
2944
private SharedInformerFactory informerFactory;
30-
private GenericKubernetesApi<EpsilonInstanceCRD, EpsilonInstanceCRDList> epsilonInstanceClient;
45+
private InstanceInformer instanceInformer;
3146

3247
private ETemplate template;
3348

3449
public Epsilon() {
50+
Path namespacePath = Paths.get("/var/run/secrets/kubernetes.io/serviceaccount/namespace");
51+
52+
try (Stream<String> lines = Files.lines(namespacePath)) {
53+
this.namespace = lines.collect(Collectors.joining(System.lineSeparator()));
54+
} catch (IOException e) {
55+
e.printStackTrace();
56+
}
57+
3558
try {
3659
ApiClient kubeClient = Config.defaultClient();
60+
GenericKubernetesApi<EpsilonInstanceCRD, EpsilonInstanceCRDList> epsilonInstanceClient =
61+
new GenericKubernetesApi<>(EpsilonInstanceCRD.class, EpsilonInstanceCRDList.class, "controller.epsilon" + ".fr", "v1", "epsiloninstances", kubeClient);
3762

3863
this.informerFactory = new SharedInformerFactory(kubeClient);
39-
this.epsilonInstanceClient = new GenericKubernetesApi<>(EpsilonInstanceCRD.class, EpsilonInstanceCRDList.class, "controller.epsilon.fr", "v1", "epsiloninstances", kubeClient);
64+
this.instanceInformer = new InstanceInformer(namespace, informerFactory, epsilonInstanceClient);
4065
} catch (IOException e) {
4166
e.printStackTrace();
4267
}
@@ -63,12 +88,10 @@ public static Epsilon get() {
6388
return singleton;
6489
}
6590

66-
public SharedInformerFactory getInformerFactory() {
67-
return informerFactory;
68-
}
91+
public InstanceInformer runInstanceInformer() {
92+
informerFactory.startAllRegisteredInformers();
6993

70-
public GenericKubernetesApi<EpsilonInstanceCRD, EpsilonInstanceCRDList> getEpsilonInstanceClient() {
71-
return epsilonInstanceClient;
94+
return instanceInformer;
7295
}
7396

7497
public String name() {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package fr.epsilon.common;
2+
3+
import fr.epsilon.common.crd.EpsilonInstanceCRD;
4+
import fr.epsilon.common.crd.EpsilonInstanceCRDList;
5+
import fr.epsilon.common.instance.EInstance;
6+
import io.kubernetes.client.informer.ResourceEventHandler;
7+
import io.kubernetes.client.informer.SharedIndexInformer;
8+
import io.kubernetes.client.informer.SharedInformerFactory;
9+
import io.kubernetes.client.informer.cache.Lister;
10+
import io.kubernetes.client.util.generic.GenericKubernetesApi;
11+
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
import java.util.concurrent.TimeUnit;
15+
import java.util.stream.Collectors;
16+
17+
public class InstanceInformer {
18+
private SharedIndexInformer<EpsilonInstanceCRD> instanceInformer;
19+
20+
private Lister<EpsilonInstanceCRD> instanceStore;
21+
22+
private List<InstanceInformerListener> listeners;
23+
24+
public InstanceInformer(String namespace, SharedInformerFactory informerFactory, GenericKubernetesApi<EpsilonInstanceCRD, EpsilonInstanceCRDList> epsilonInstanceClient) {
25+
this.instanceInformer = informerFactory.sharedIndexInformerFor(epsilonInstanceClient,
26+
EpsilonInstanceCRD.class, TimeUnit.MINUTES.toMillis(10), namespace);
27+
28+
this.instanceStore = new Lister<>(instanceInformer.getIndexer());
29+
30+
this.listeners = new ArrayList<>();
31+
32+
instanceInformer.addEventHandlerWithResyncPeriod(new ResourceEventHandler<EpsilonInstanceCRD>() {
33+
@Override
34+
public void onAdd(EpsilonInstanceCRD instance) {}
35+
36+
@Override
37+
public void onUpdate(EpsilonInstanceCRD oldInstance, EpsilonInstanceCRD newInstance) {
38+
if (newInstance.getStatus() != null) {
39+
for (InstanceInformerListener listener : listeners) {
40+
listener.onInstanceUpdate(newInstance.getInstance());
41+
}
42+
}
43+
}
44+
45+
@Override
46+
public void onDelete(EpsilonInstanceCRD instance, boolean deletedFinalStateUnknown) {
47+
for (InstanceInformerListener listener : listeners) {
48+
listener.onInstanceUpdate(instance.getInstance());
49+
}
50+
}
51+
}, TimeUnit.MINUTES.toMillis(5));
52+
}
53+
54+
public EInstance getInstance(String name) {
55+
return instanceStore.get(name).getInstance();
56+
}
57+
58+
public List<EInstance> getInstances() {
59+
return instanceStore.list().stream()
60+
.map(EpsilonInstanceCRD::getInstance)
61+
.collect(Collectors.toList());
62+
}
63+
64+
public void registerListener(InstanceInformerListener listener) {
65+
listeners.add(listener);
66+
}
67+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package fr.epsilon.common;
2+
3+
import fr.epsilon.common.crd.EpsilonInstanceCRD;
4+
import fr.epsilon.common.instance.EInstance;
5+
6+
public interface InstanceInformerListener {
7+
void onInstanceUpdate(EInstance instance);
8+
void onInstanceRemove(EInstance instance);
9+
}

common/src/main/java/fr/epsilon/common/crd/EpsilonInstanceCRD.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package fr.epsilon.common.crd;
22

33
import com.google.gson.annotations.SerializedName;
4+
import fr.epsilon.common.instance.EInstance;
5+
import fr.epsilon.common.instance.EState;
6+
import fr.epsilon.common.instance.EType;
47
import io.kubernetes.client.common.KubernetesObject;
58
import io.kubernetes.client.openapi.models.V1ObjectMeta;
69

@@ -47,4 +50,26 @@ public String getName() {
4750
public EpsilonInstanceCRDStatus getStatus() {
4851
return status;
4952
}
53+
54+
public EInstance getInstance() {
55+
if (getStatus() != null) {
56+
String template = getStatus().getTemplate();
57+
58+
String content = getStatus().getContent();
59+
60+
boolean hub = getStatus().isHub();
61+
62+
EType type = getStatus().getType();
63+
EState state = getStatus().getState();
64+
65+
int slots = getStatus().getSlots();
66+
int onlineCount = getStatus().getOnlineCount();
67+
68+
String ip = getStatus().getIp();
69+
70+
return new EInstance(getName(), template, content, hub, type, state, slots, onlineCount, ip);
71+
}
72+
73+
return null;
74+
}
5075
}

common/src/main/java/fr/epsilon/common/crd/EpsilonInstanceCRDStatus.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class EpsilonInstanceCRDStatus {
1919

2020
public static final String SERIALIZED_NAME_SLOTS = "slots";
2121

22-
public static final String SERIALIZED_NAME_CLOSE = "close";
22+
public static final String SERIALIZED_NAME_ONLINE = "online";
2323

2424
@SerializedName(SERIALIZED_NAME_IP)
2525
private String ip = null;
@@ -42,8 +42,8 @@ public class EpsilonInstanceCRDStatus {
4242
@SerializedName(SERIALIZED_NAME_SLOTS)
4343
private Integer slots = null;
4444

45-
@SerializedName(SERIALIZED_NAME_CLOSE)
46-
private Boolean close = null;
45+
@SerializedName(SERIALIZED_NAME_ONLINE)
46+
private Integer online = null;
4747

4848
public String getIp() {
4949
return ip;
@@ -73,7 +73,7 @@ public Integer getSlots() {
7373
return slots;
7474
}
7575

76-
public Boolean isClose() {
77-
return close;
76+
public Integer getOnlineCount() {
77+
return online;
7878
}
7979
}

common/src/main/java/fr/epsilon/common/instance/EInstance.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,31 @@
55
public class EInstance {
66
private String name;
77
private String template;
8+
9+
private String content;
10+
11+
private boolean hub;
12+
13+
private EType type;
814
private EState state;
15+
916
private int slots;
1017
private int online_count;
1118

19+
private String ip;
20+
21+
public EInstance(String name, String template, String content, boolean hub, EType type, EState state, int slots, int online_count, String ip) {
22+
this.name = name;
23+
this.template = template;
24+
this.content = content;
25+
this.hub = hub;
26+
this.type = type;
27+
this.state = state;
28+
this.slots = slots;
29+
this.online_count = online_count;
30+
this.ip = ip;
31+
}
32+
1233
public String getName() {
1334
return name;
1435
}
@@ -17,6 +38,18 @@ public String getTemplate() {
1738
return template;
1839
}
1940

41+
public String getContent() {
42+
return content;
43+
}
44+
45+
public boolean isHub() {
46+
return hub;
47+
}
48+
49+
public EType getType() {
50+
return type;
51+
}
52+
2053
public EState getState() {
2154
return state;
2255
}
@@ -29,6 +62,10 @@ public int getOnlineCount() {
2962
return online_count;
3063
}
3164

65+
public String getIp() {
66+
return ip;
67+
}
68+
3269
public boolean enableInGame() {
3370
return Epsilon.get().instanceModule().inGameInstance(name);
3471
}

proxy/src/main/java/fr/epsilon/exporter/EpsilonExporter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public void onEnable() {
2525
getProxy().getServers().clear();
2626

2727
this.register = new EpsilonRegister(this);
28-
register.runInformer();
28+
register.run();
2929

3030
EpsilonEventStream.init(this);
3131

0 commit comments

Comments
 (0)