Make all event script invocations thread safe
Simple solution for avoiding concurrent access of the same evaluated script, but I would be surprised if performance is not affected for the worse. The same Invocable is used for all instances of an event, so more active instances means higher contention of the single Invocable. Hopefully the number of instances required for it to be noticeably slow is high enough that this is not an issue.
This commit is contained in:
@@ -23,6 +23,7 @@ package scripting.event;
|
||||
|
||||
import net.server.channel.Channel;
|
||||
import scripting.AbstractScriptManager;
|
||||
import scripting.SynchronizedInvocable;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptEngine;
|
||||
@@ -39,7 +40,7 @@ import java.util.logging.Logger;
|
||||
* @author Matze
|
||||
*/
|
||||
public class EventScriptManager extends AbstractScriptManager {
|
||||
private static final String INJECTED_VARIABLE = "em";
|
||||
private static final String INJECTED_VARIABLE_NAME = "em";
|
||||
private static EventEntry fallback;
|
||||
private final Map<String, EventEntry> events = new ConcurrentHashMap<>();
|
||||
private boolean active = false;
|
||||
@@ -57,11 +58,7 @@ public class EventScriptManager extends AbstractScriptManager {
|
||||
public EventScriptManager(final Channel channel, String[] scripts) {
|
||||
for (String script : scripts) {
|
||||
if (!script.isEmpty()) {
|
||||
ScriptEngine engine = getInvocableScriptEngine("event/" + script + ".js");
|
||||
Invocable iv = (Invocable) engine;
|
||||
EventManager eventManager = new EventManager(channel, iv, script);
|
||||
engine.put(INJECTED_VARIABLE, eventManager);
|
||||
events.put(script, new EventEntry(iv, eventManager));
|
||||
events.put(script, initializeEventEntry(script, channel));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,17 +97,21 @@ public class EventScriptManager extends AbstractScriptManager {
|
||||
return;
|
||||
}
|
||||
|
||||
Channel cserv = eventEntries.iterator().next().getValue().em.getChannelServer();
|
||||
Channel channel = eventEntries.iterator().next().getValue().em.getChannelServer();
|
||||
for (Entry<String, EventEntry> entry : eventEntries) {
|
||||
String script = entry.getKey();
|
||||
ScriptEngine engine = getInvocableScriptEngine("event/" + script + ".js");
|
||||
Invocable iv = (Invocable) engine;
|
||||
EventManager eventManager = new EventManager(cserv, iv, script);
|
||||
engine.put(INJECTED_VARIABLE, eventManager);
|
||||
events.put(script, new EventEntry(iv, eventManager));
|
||||
events.put(script, initializeEventEntry(script, channel));
|
||||
}
|
||||
}
|
||||
|
||||
private EventEntry initializeEventEntry(String script, Channel channel) {
|
||||
ScriptEngine engine = getInvocableScriptEngine("event/" + script + ".js");
|
||||
Invocable iv = SynchronizedInvocable.of((Invocable) engine);
|
||||
EventManager eventManager = new EventManager(channel, iv, script);
|
||||
engine.put(INJECTED_VARIABLE_NAME, eventManager);
|
||||
return new EventEntry(iv, eventManager);
|
||||
}
|
||||
|
||||
// Is never being called
|
||||
public void reload() {
|
||||
cancel();
|
||||
|
||||
Reference in New Issue
Block a user