Skip to content

Commit b879c8e

Browse files
authored
feat: move smart configs into their own files (#1808)
### Motivation We want to redo the service / task property handling at some point. This is a pain in the ass if the smart config stays inside the task properties. Furthermore it simply does not make sense to keep it there anymore as smart is mostly used on single tasks and not on all of them, just creating clutter and overhead. ### Modification Moved each smart config into a separate file in the modules/CloudNet-Smart directory, if the config was enabled. Disabled configs are **not migrated**. Old configs are removed from the task props. ### Result Smart configs are not part of the task props anymore and the property rework can be done.
1 parent 6f807c8 commit b879c8e

File tree

12 files changed

+437
-154
lines changed

12 files changed

+437
-154
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2019-present CloudNetService team & contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package eu.cloudnetservice.modules.smart;
18+
19+
import java.util.Map;
20+
import lombok.NonNull;
21+
import org.jetbrains.annotations.Nullable;
22+
import org.jetbrains.annotations.UnmodifiableView;
23+
24+
/**
25+
* Represents the management interface for smart service task configurations.
26+
*
27+
* @since 4.0
28+
*/
29+
public interface SmartServiceManagement {
30+
31+
/**
32+
* Gets an unmodifiable view of all smart service task configurations mapped by their target task name.
33+
*
34+
* @return an unmodifiable view of all smart service task configurations.
35+
*/
36+
@NonNull
37+
@UnmodifiableView
38+
Map<String, SmartServiceTaskConfig> configurations();
39+
40+
/**
41+
* Gets the smart service task entry with the given task name as {@link SmartServiceTaskConfig#targetTask()}.
42+
*
43+
* @param taskName the targetTask name of the smart service task configuration to get.
44+
* @return the smart service task configuration or null if not present.
45+
* @throws NullPointerException if the given task name is null.
46+
*/
47+
@Nullable SmartServiceTaskConfig smartServiceTaskConfig(@NonNull String taskName);
48+
49+
/**
50+
* Adds or updates the given smart service task configuration. If there is already a configuration for the same task
51+
* name, the old one is replaced.
52+
* <p>
53+
* The configuration is synced to all other nodes in the cluster.
54+
*
55+
* @param config the smart service task configuration to add.
56+
* @throws NullPointerException if the given configuration is null.
57+
*/
58+
void addSmartServiceTaskConfig(@NonNull SmartServiceTaskConfig config);
59+
60+
/**
61+
* Removes the smart service task configuration based on the given task name.
62+
* <p>
63+
* The configuration is removed from all other nodes in the cluster.
64+
*
65+
* @param taskName the targetTask name of the smart service task configuration to remove.
66+
* @throws NullPointerException if the given task name is null.
67+
*/
68+
void removeSmartServiceTaskConfig(@NonNull String taskName);
69+
}

modules/smart/api/src/main/java/eu/cloudnetservice/modules/smart/SmartServiceTaskConfig.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616

1717
package eu.cloudnetservice.modules.smart;
1818

19+
import java.util.Objects;
1920
import lombok.NonNull;
2021

2122
public record SmartServiceTaskConfig(
23+
@NonNull String targetTask,
2224
boolean enabled,
2325
int priority,
2426
int maxServices,
@@ -39,6 +41,8 @@ public record SmartServiceTaskConfig(
3941

4042
public static @NonNull Builder builder(@NonNull SmartServiceTaskConfig config) {
4143
return builder()
44+
.targetTask(config.targetTask())
45+
4246
.enabled(config.enabled())
4347
.priority(config.priority())
4448

@@ -72,6 +76,8 @@ public enum TemplateInstaller {
7276

7377
public static class Builder {
7478

79+
private String targetTask;
80+
7581
private boolean enabled = false;
7682
private int priority = 10;
7783

@@ -89,6 +95,11 @@ public static class Builder {
8995
private int forAnewInstanceDelayTimeInSeconds = 300;
9096
private int percentOfPlayersForANewServiceByInstance = 100;
9197

98+
public @NonNull Builder targetTask(@NonNull String targetTask) {
99+
this.targetTask = targetTask;
100+
return this;
101+
}
102+
92103
public @NonNull Builder enabled(boolean enabled) {
93104
this.enabled = enabled;
94105
return this;
@@ -150,7 +161,10 @@ public static class Builder {
150161
}
151162

152163
public @NonNull SmartServiceTaskConfig build() {
164+
Objects.requireNonNull(this.targetTask, "targetTask must be set");
165+
153166
return new SmartServiceTaskConfig(
167+
this.targetTask,
154168
this.enabled,
155169
this.priority,
156170
this.maxServices,

modules/smart/impl/build.gradle.kts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,28 @@ plugins {
2525

2626
dependencies {
2727
compileOnly(libs.guava)
28-
compileOnlyApi(projects.node.nodeApi)
28+
compileOnlyApi(projects.node.nodeImpl)
29+
compileOnlyApi(projects.utils.utilsBase)
2930
compileOnlyApi(projects.modules.bridge.bridgeApi)
31+
32+
annotationProcessor(libs.aerogelAuto)
33+
3034
api(projects.modules.smart.smartApi)
3135
}
3236

3337
tasks.shadowJar.configure {
3438
archiveFileName = Files.smart
3539
}
3640

41+
tasks.withType<JavaCompile>().configureEach {
42+
options.compilerArgs.add("-AaerogelAutoFileName=autoconfigure/smart.aero")
43+
}
44+
3745
moduleJson {
3846
name = "CloudNet-Smart"
3947
author = "CloudNetService"
4048
main = "eu.cloudnetservice.modules.smart.impl.CloudNetSmartModule"
4149
description = "CloudNet extension, which implement smart network handling and automatic services providing"
42-
runtimeModule = true
4350
// depend on internal modules
4451
dependencies.add(ModuleConfiguration.Dependency("CloudNet-Bridge").apply {
4552
needsRepoResolve = false

modules/smart/impl/src/main/java/eu/cloudnetservice/modules/smart/impl/CloudNetSmartModule.java

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,46 @@
1717
package eu.cloudnetservice.modules.smart.impl;
1818

1919
import eu.cloudnetservice.driver.event.EventManager;
20+
import eu.cloudnetservice.driver.inject.InjectionLayer;
2021
import eu.cloudnetservice.driver.module.ModuleLifeCycle;
2122
import eu.cloudnetservice.driver.module.ModuleTask;
2223
import eu.cloudnetservice.driver.module.driver.DriverModule;
2324
import eu.cloudnetservice.driver.provider.ServiceTaskProvider;
2425
import eu.cloudnetservice.driver.service.ServiceTask;
2526
import eu.cloudnetservice.modules.smart.SmartServiceTaskConfig;
2627
import eu.cloudnetservice.modules.smart.impl.listener.CloudNetLocalServiceListener;
27-
import eu.cloudnetservice.modules.smart.impl.listener.CloudNetLocalServiceTaskListener;
2828
import eu.cloudnetservice.modules.smart.impl.listener.CloudNetTickListener;
29+
import eu.cloudnetservice.modules.smart.impl.listener.SmartConfigMessageListener;
2930
import eu.cloudnetservice.node.command.CommandProvider;
31+
import jakarta.inject.Inject;
32+
import jakarta.inject.Named;
3033
import jakarta.inject.Singleton;
3134
import lombok.NonNull;
32-
import org.jetbrains.annotations.Nullable;
3335

3436
@Singleton
3537
public class CloudNetSmartModule extends DriverModule {
3638

39+
@Inject
40+
public CloudNetSmartModule(@NonNull @Named("module") InjectionLayer<?> layer) {
41+
layer.installAutoConfigureBindings(this.getClass().getClassLoader(), "smart");
42+
}
43+
3744
@ModuleTask(lifecycle = ModuleLifeCycle.STARTED, order = Byte.MAX_VALUE)
38-
public void rewriteOldSmartTaskEntries(@NonNull ServiceTaskProvider taskProvider) {
45+
public void rewriteOldSmartTaskEntries(
46+
@NonNull ServiceTaskProvider taskProvider,
47+
@NonNull NodeSmartServiceManagement management
48+
) {
3949
for (var task : taskProvider.serviceTasks()) {
4050
// check if the task had a smart config entry previously
4151
if (task.propertyHolder().contains("smartConfig")) {
52+
SmartServiceTaskConfig config = null;
53+
4254
// check if the task still uses the old format
4355
var smartEntry = task.propertyHolder().readDocument("smartConfig");
4456
if (smartEntry.contains("dynamicMemoryAllocationRange")) {
4557
// rewrite the old config
46-
var config = SmartServiceTaskConfig.builder()
58+
config = SmartServiceTaskConfig.builder()
59+
.targetTask(task.name())
4760
.enabled(smartEntry.getBoolean("enabled"))
4861
.priority(smartEntry.getInt("priority"))
4962

@@ -62,26 +75,21 @@ public void rewriteOldSmartTaskEntries(@NonNull ServiceTaskProvider taskProvider
6275
.percentOfPlayersForANewServiceByInstance(smartEntry.getInt("percentOfPlayersForANewServiceByInstance"))
6376

6477
.build();
78+
} else if (!smartEntry.containsNonNull("targetTask")) {
79+
var newEntry = smartEntry.mutableCopy().append("targetTask", task.name());
80+
config = newEntry.toInstanceOf(SmartServiceTaskConfig.class);
81+
}
6582

66-
// append the new smart entry and update the service
67-
var newTask = ServiceTask.builder(task)
68-
.modifyProperties(properties -> properties.append("smartConfig", config))
83+
if (config != null) {
84+
var updatedTask = ServiceTask.builder(task)
85+
.modifyProperties(properties -> properties.remove("smartConfig"))
6986
.build();
70-
taskProvider.addServiceTask(newTask);
71-
}
72-
}
73-
}
74-
}
87+
taskProvider.addServiceTask(updatedTask);
7588

76-
@ModuleTask(lifecycle = ModuleLifeCycle.STARTED, order = 64)
77-
public void addMissingSmartConfigurationEntries(@NonNull ServiceTaskProvider taskProvider) {
78-
for (var task : taskProvider.serviceTasks()) {
79-
// check if the service task needs a smart entry
80-
if (!task.propertyHolder().contains("smartConfig")) {
81-
var newTask = ServiceTask.builder(task)
82-
.modifyProperties(properties -> properties.append("smartConfig", SmartServiceTaskConfig.builder().build()))
83-
.build();
84-
taskProvider.addServiceTask(newTask);
89+
if (config.enabled()) {
90+
management.addSmartServiceTaskConfigSilently(config);
91+
}
92+
}
8593
}
8694
}
8795
}
@@ -90,14 +98,14 @@ public void addMissingSmartConfigurationEntries(@NonNull ServiceTaskProvider tas
9098
public void start(@NonNull EventManager eventManager, @NonNull CommandProvider commandProvider) {
9199
eventManager
92100
.registerListener(CloudNetTickListener.class)
93-
.registerListener(CloudNetLocalServiceListener.class)
94-
.registerListener(CloudNetLocalServiceTaskListener.class);
101+
.registerListener(SmartConfigMessageListener.class)
102+
.registerListener(CloudNetLocalServiceListener.class);
95103

96104
commandProvider.register(SmartCommand.class);
97105
}
98106

99-
public @Nullable SmartServiceTaskConfig smartConfig(@NonNull ServiceTask task) {
100-
// try to get the smart config entry
101-
return task.propertyHolder().readObject("smartConfig", SmartServiceTaskConfig.class);
107+
@ModuleTask(lifecycle = ModuleLifeCycle.RELOADING)
108+
public void reload(@NonNull NodeSmartServiceManagement management) {
109+
management.loadSmartConfigurations();
102110
}
103111
}

0 commit comments

Comments
 (0)