Skip to content

Commit b0e4902

Browse files
committed
Add multiple instances support, improve event handling
1 parent 17597b1 commit b0e4902

File tree

5 files changed

+108
-34
lines changed

5 files changed

+108
-34
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>org.example</groupId>
88
<artifactId>ForestRedisAPI</artifactId>
9-
<version>1.0.6</version>
9+
<version>1.0.7</version>
1010

1111
<properties>
1212
<maven.compiler.source>11</maven.compiler.source>

src/main/java/cz/foresttech/forestredis/shared/IForestRedisPlugin.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public interface IForestRedisPlugin {
2626
/**
2727
* Calls the corresponding events when message was received
2828
*
29-
* @param channel Channel which received the message
29+
* @param channel Channel which received the message
3030
* @param messageTransferObject {@link MessageTransferObject} which was received
3131
*/
3232
void onMessageReceived(String channel, MessageTransferObject messageTransferObject);
@@ -36,7 +36,7 @@ public interface IForestRedisPlugin {
3636
/**
3737
* Returns logger object
3838
*
39-
* @return Logger instance of the current implementation
39+
* @return Logger instance of the current implementation
4040
*/
4141
Logger logger();
4242

@@ -45,7 +45,7 @@ public interface IForestRedisPlugin {
4545
/**
4646
* Returns the {@link IConfigurationAdapter} implementation
4747
*
48-
* @return Implementation of {@link IConfigurationAdapter}
48+
* @return Implementation of {@link IConfigurationAdapter}
4949
*/
5050
default IConfigurationAdapter getConfigAdapter() {
5151
return null;
@@ -86,18 +86,30 @@ default void load() {
8686
configAdapter.getBoolean("redis.ssl", false)
8787
);
8888

89-
// Initialize RedisManager object
90-
RedisManager.init(this, serverIdentifier, redisConfiguration);
9189

9290
// Setup the RedisManager
9391
List<String> channels = configAdapter.getStringList("channels");
94-
if (channels.isEmpty()) {
95-
RedisManager.getAPI().setup();
92+
93+
// Initialize RedisManager object
94+
if (RedisManager.getAPI() == null) {
95+
RedisManager.init(this, serverIdentifier, redisConfiguration);
96+
if (channels.isEmpty()) {
97+
RedisManager.getAPI().setup();
98+
return;
99+
}
100+
101+
String[] channelsArray = channels.toArray(new String[0]);
102+
RedisManager.getAPI().setup(channelsArray);
96103
return;
97104
}
98105

99-
String[] channelsArray = channels.toArray(new String[0]);
100-
RedisManager.getAPI().setup(channelsArray);
106+
// Reload the RedisManager if already initialized
107+
RedisManager.getAPI().reload(serverIdentifier, redisConfiguration, true);
108+
if (!channels.isEmpty()) {
109+
String[] channelsArray = channels.toArray(new String[0]);
110+
RedisManager.getAPI().subscribe(channelsArray);
111+
}
112+
101113
}
102114

103115
/*----------------------------------------------------------------------------------------------------------*/

src/main/java/cz/foresttech/forestredis/shared/RedisManager.java

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
import cz.foresttech.forestredis.shared.models.RedisConfiguration;
55
import redis.clients.jedis.*;
66

7-
import java.util.ArrayList;
8-
import java.util.Arrays;
9-
import java.util.List;
7+
import java.util.*;
108

119
/**
1210
* Class for maintaining and handling connection to Redis server.
@@ -17,7 +15,7 @@
1715
public class RedisManager {
1816

1917
/**
20-
* Singleton instance
18+
* Main instance
2119
*/
2220
private static RedisManager api;
2321

@@ -29,17 +27,17 @@ public class RedisManager {
2927
/**
3028
* Configuration object to store credentials
3129
*/
32-
private final RedisConfiguration redisConfiguration;
30+
private RedisConfiguration redisConfiguration;
3331

3432
/**
3533
* Current server's identifier. Shall be unique across your network.
3634
*/
37-
private final String serverIdentifier;
35+
private String serverIdentifier;
3836

3937
/**
40-
* List of subscribed channels
38+
* Set of subscribed channels
4139
*/
42-
private final List<String> channels;
40+
private final HashSet<String> channels;
4341

4442
/**
4543
* List of current subscriptions
@@ -66,7 +64,7 @@ public class RedisManager {
6664
* @param serverIdentifier Identifier of the server (e.g. 'Bungee01'). Shall be unique to prevent bugs
6765
* @param redisConfiguration {@link RedisConfiguration} object with Redis server credentials
6866
*/
69-
private RedisManager(IForestRedisPlugin plugin, String serverIdentifier, RedisConfiguration redisConfiguration) {
67+
public RedisManager(IForestRedisPlugin plugin, String serverIdentifier, RedisConfiguration redisConfiguration) {
7068
this.plugin = plugin;
7169
this.closing = false;
7270

@@ -75,7 +73,37 @@ private RedisManager(IForestRedisPlugin plugin, String serverIdentifier, RedisCo
7573

7674
this.subscriptions = new ArrayList<>();
7775

78-
this.channels = new ArrayList<>();
76+
this.channels = new HashSet<>();
77+
}
78+
79+
/*----------------------------------------------------------------------------------------------------------*/
80+
81+
/**
82+
* Reloads the manager while keeping already subscribed channels if set.
83+
*
84+
* @param serverIdentifier New server identifier (if null, already using server id will be used)
85+
* @param redisConfiguration New RedisConfiguration (if null, already using configuration will be used)
86+
* @param keepChannels Keep already subscribed channels
87+
*/
88+
public void reload(String serverIdentifier, RedisConfiguration redisConfiguration, boolean keepChannels) {
89+
this.close();
90+
this.closing = false;
91+
92+
if (serverIdentifier != null) {
93+
this.serverIdentifier = serverIdentifier;
94+
}
95+
if (redisConfiguration != null) {
96+
this.redisConfiguration = redisConfiguration;
97+
}
98+
99+
if (keepChannels) {
100+
String[] channels = this.channels.toArray(String[]::new);
101+
this.channels.clear();
102+
this.setup(channels);
103+
return;
104+
}
105+
106+
this.setup();
79107
}
80108

81109
/*----------------------------------------------------------------------------------------------------------*/
@@ -108,7 +136,7 @@ public boolean setup(String... channels) {
108136

109137
// If channels were provided, add them to the list and subscribe to them
110138
if (channels != null && channels.length > 0) {
111-
this.channels.addAll(List.of(channels));
139+
this.channels.addAll(Set.of(channels));
112140

113141
Subscription subscription = new Subscription(this.channels.toArray(new String[0]));
114142
this.plugin.runAsync(subscription);
@@ -137,14 +165,14 @@ public void unsubscribe(String... channels) {
137165
try {
138166
for (Subscription sub : this.subscriptions) {
139167
sub.unsubscribe(channels);
140-
this.plugin.logger().info("Successfully unsubscribed channels: " + Arrays.toString(channels) + "!");
141168
}
169+
this.plugin.logger().info("Successfully unsubscribed channels: " + Arrays.toString(channels) + "!");
142170
} catch (Exception ex) {
143171
this.plugin.logger().warning("An error occurred while unsubscribing channels: " + Arrays.toString(channels) + "!");
144172
return;
145173
}
146174

147-
this.channels.removeAll(List.of(channels));
175+
this.channels.removeAll(Set.of(channels));
148176
}
149177

150178
/*----------------------------------------------------------------------------------------------------------*/
@@ -165,7 +193,7 @@ public boolean subscribe(String... channels) {
165193
return false;
166194
}
167195

168-
List<String> actualChannelsToAdd = new ArrayList<>();
196+
Set<String> actualChannelsToAdd = new HashSet<>();
169197

170198
for (String channel : channels) {
171199
if (this.channels.contains(channel) && channel != null) {
@@ -271,6 +299,8 @@ public void close() {
271299
}
272300
}
273301

302+
this.subscriptions.clear();
303+
274304
if (this.jedisPool == null) {
275305
return;
276306
}
@@ -308,7 +338,7 @@ public boolean isSubscribed(String channel) {
308338
*
309339
* @return List of all subscribed channels (case-sensitive)
310340
*/
311-
public List<String> getSubscribedChannels() {
341+
public Set<String> getSubscribedChannels() {
312342
return channels;
313343
}
314344

@@ -386,7 +416,7 @@ public void onMessage(String channel, String message) {
386416
/*----------------------------------------------------------------------------------------------------------*/
387417

388418
/**
389-
* Initialization method for creating {@link RedisManager} singleton instance. This won't start any
419+
* Initialization method for creating {@link RedisManager} main instance. This won't start any
390420
* connection or subscription.
391421
*
392422
* @param plugin Origin plugin which tries to obtain the instance
@@ -400,10 +430,10 @@ public static void init(IForestRedisPlugin plugin, String serverIdentifier, Redi
400430
/*----------------------------------------------------------------------------------------------------------*/
401431

402432
/**
403-
* Gets the singleton instance of {@link RedisManager} object. This is the only
433+
* Gets the main instance of {@link RedisManager} object. This is the only
404434
* recommended approach to access the API methods.
405435
*
406-
* @return Singleton instance of {@link RedisManager}
436+
* @return Main instance of {@link RedisManager}
407437
*/
408438
public static RedisManager getAPI() {
409439
return api;

src/main/java/cz/foresttech/forestredis/spigot/ForestRedisSpigot.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@ public void runAsync(Runnable task) {
4242

4343
@Override
4444
public void onMessageReceived(String channel, MessageTransferObject messageTransferObject) {
45-
Bukkit.getPluginManager().callEvent(new AsyncRedisMessageReceivedEvent(channel, messageTransferObject));
46-
Bukkit.getScheduler().runTask(this, () -> Bukkit.getPluginManager().callEvent(new RedisMessageReceivedEvent(channel, messageTransferObject)));
45+
AsyncRedisMessageReceivedEvent asyncRedisMessageReceivedEvent = new AsyncRedisMessageReceivedEvent(channel, messageTransferObject);
46+
Bukkit.getPluginManager().callEvent(asyncRedisMessageReceivedEvent);
47+
48+
if (asyncRedisMessageReceivedEvent.isCancelled()) {
49+
Bukkit.getScheduler().runTask(this, () -> Bukkit.getPluginManager().callEvent(new RedisMessageReceivedEvent(asyncRedisMessageReceivedEvent.getChannel(), asyncRedisMessageReceivedEvent.getMessageTransferObject())));
50+
}
4751
}
4852

4953
@Override
@@ -61,7 +65,7 @@ public IConfigurationAdapter getConfigAdapter() {
6165
/**
6266
* Obtains the instance of the plugin
6367
*
64-
* @return Instance of {@link ForestRedisSpigot}
68+
* @return Instance of {@link ForestRedisSpigot}
6569
*/
6670
public static ForestRedisSpigot getInstance() {
6771
return instance;

src/main/java/cz/foresttech/forestredis/spigot/events/AsyncRedisMessageReceivedEvent.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,29 @@
33
import cz.foresttech.forestredis.shared.events.IRedisMessageReceivedEvent;
44
import cz.foresttech.forestredis.shared.models.MessageTransferObject;
55
import cz.foresttech.forestredis.shared.RedisManager;
6+
import org.bukkit.event.Cancellable;
67
import org.bukkit.event.Event;
78
import org.bukkit.event.HandlerList;
89

910
/**
1011
* Asynchronous Spigot Event class used when message was received from subscribed channel.
12+
* <p>
13+
* Data can be changed, so sync Spigot Event will be triggered with updated data
1114
*/
12-
public class AsyncRedisMessageReceivedEvent extends Event implements IRedisMessageReceivedEvent {
15+
public class AsyncRedisMessageReceivedEvent extends Event implements IRedisMessageReceivedEvent, Cancellable {
1316
private static final HandlerList HANDLERS = new HandlerList();
1417

18+
private boolean cancelled;
19+
1520
/**
1621
* Name of the channel the message came from
1722
*/
18-
private final String channel;
23+
private String channel;
1924

2025
/**
2126
* MessageTransferObject containing message's data
2227
*/
23-
private final MessageTransferObject messageTransferObject;
28+
private MessageTransferObject messageTransferObject;
2429

2530
/**
2631
* Constructs the instance of the Event
@@ -30,10 +35,23 @@ public class AsyncRedisMessageReceivedEvent extends Event implements IRedisMessa
3035
*/
3136
public AsyncRedisMessageReceivedEvent(String channel, MessageTransferObject messageTransferObject) {
3237
super(true);
38+
this.cancelled = false;
39+
this.channel = channel;
40+
this.messageTransferObject = messageTransferObject;
41+
}
42+
43+
public void setChannel(String channel) {
3344
this.channel = channel;
45+
}
46+
47+
public void setMessageTransferObject(MessageTransferObject messageTransferObject) {
3448
this.messageTransferObject = messageTransferObject;
3549
}
3650

51+
public MessageTransferObject getMessageTransferObject() {
52+
return messageTransferObject;
53+
}
54+
3755
@Override
3856
public String getSenderIdentifier() {
3957
return this.messageTransferObject.getSenderIdentifier();
@@ -72,4 +90,14 @@ public HandlerList getHandlers() {
7290
public static HandlerList getHandlerList() {
7391
return HANDLERS;
7492
}
93+
94+
@Override
95+
public boolean isCancelled() {
96+
return cancelled;
97+
}
98+
99+
@Override
100+
public void setCancelled(boolean cancelled) {
101+
this.cancelled = cancelled;
102+
}
75103
}

0 commit comments

Comments
 (0)