How kind of @lazertester to test the new scheduler!
This commit is contained in:
parent
600a1b4ff5
commit
c54553d0f9
@ -1,6 +1,5 @@
|
|||||||
package net.md_5.bungee.api.scheduler;
|
package net.md_5.bungee.api.scheduler;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,11 +30,7 @@ public interface ScheduledTask
|
|||||||
Runnable getTask();
|
Runnable getTask();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the delay in the specified unit before this task will next be
|
* Cancel this task to suppress subsequent executions.
|
||||||
* executed.
|
|
||||||
*
|
|
||||||
* @param unit the unit to get the delay in
|
|
||||||
* @return the time before the next execution of this task
|
|
||||||
*/
|
*/
|
||||||
long getDelay(TimeUnit unit);
|
void cancel();
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ import java.util.MissingResourceException;
|
|||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
@ -50,7 +49,6 @@ import net.md_5.bungee.api.config.ServerInfo;
|
|||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
import net.md_5.bungee.api.plugin.PluginManager;
|
import net.md_5.bungee.api.plugin.PluginManager;
|
||||||
import net.md_5.bungee.api.scheduler.TaskScheduler;
|
|
||||||
import net.md_5.bungee.api.tab.CustomTabList;
|
import net.md_5.bungee.api.tab.CustomTabList;
|
||||||
import net.md_5.bungee.command.*;
|
import net.md_5.bungee.command.*;
|
||||||
import net.md_5.bungee.config.YamlConfig;
|
import net.md_5.bungee.config.YamlConfig;
|
||||||
@ -60,7 +58,6 @@ import net.md_5.bungee.protocol.packet.DefinedPacket;
|
|||||||
import net.md_5.bungee.protocol.packet.Packet3Chat;
|
import net.md_5.bungee.protocol.packet.Packet3Chat;
|
||||||
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
||||||
import net.md_5.bungee.protocol.Vanilla;
|
import net.md_5.bungee.protocol.Vanilla;
|
||||||
import net.md_5.bungee.scheduler.BungeeThreadPool;
|
|
||||||
import net.md_5.bungee.tab.Custom;
|
import net.md_5.bungee.tab.Custom;
|
||||||
import net.md_5.bungee.util.CaseInsensitiveMap;
|
import net.md_5.bungee.util.CaseInsensitiveMap;
|
||||||
import org.fusesource.jansi.AnsiConsole;
|
import org.fusesource.jansi.AnsiConsole;
|
||||||
@ -83,10 +80,6 @@ public class BungeeCord extends ProxyServer
|
|||||||
* Localization bundle.
|
* Localization bundle.
|
||||||
*/
|
*/
|
||||||
public final ResourceBundle bundle = ResourceBundle.getBundle( "messages_en" );
|
public final ResourceBundle bundle = ResourceBundle.getBundle( "messages_en" );
|
||||||
/**
|
|
||||||
* Thread pools.
|
|
||||||
*/
|
|
||||||
public final ScheduledThreadPoolExecutor executors = new BungeeThreadPool( new ThreadFactoryBuilder().setNameFormat( "Bungee Pool Thread #%1$d" ).build() );
|
|
||||||
public final MultithreadEventLoopGroup eventLoops = new NioEventLoopGroup( 0, new ThreadFactoryBuilder().setNameFormat( "Netty IO Thread #%1$d" ).build() );
|
public final MultithreadEventLoopGroup eventLoops = new NioEventLoopGroup( 0, new ThreadFactoryBuilder().setNameFormat( "Netty IO Thread #%1$d" ).build() );
|
||||||
/**
|
/**
|
||||||
* locations.yml save thread.
|
* locations.yml save thread.
|
||||||
@ -117,7 +110,7 @@ public class BungeeCord extends ProxyServer
|
|||||||
@Getter
|
@Getter
|
||||||
private final File pluginsFolder = new File( "plugins" );
|
private final File pluginsFolder = new File( "plugins" );
|
||||||
@Getter
|
@Getter
|
||||||
private final TaskScheduler scheduler = new BungeeScheduler();
|
private final BungeeScheduler scheduler = new BungeeScheduler();
|
||||||
@Getter
|
@Getter
|
||||||
private ConsoleReader consoleReader;
|
private ConsoleReader consoleReader;
|
||||||
@Getter
|
@Getter
|
||||||
@ -288,8 +281,6 @@ public class BungeeCord extends ProxyServer
|
|||||||
{
|
{
|
||||||
BungeeCord.this.isRunning = false;
|
BungeeCord.this.isRunning = false;
|
||||||
|
|
||||||
executors.shutdown();
|
|
||||||
|
|
||||||
stopListeners();
|
stopListeners();
|
||||||
getLogger().info( "Closing pending connections" );
|
getLogger().info( "Closing pending connections" );
|
||||||
|
|
||||||
@ -329,6 +320,7 @@ public class BungeeCord extends ProxyServer
|
|||||||
getScheduler().cancel( plugin );
|
getScheduler().cancel( plugin );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scheduler.shutdown();
|
||||||
getLogger().info( "Thankyou and goodbye" );
|
getLogger().info( "Thankyou and goodbye" );
|
||||||
System.exit( 0 );
|
System.exit( 0 );
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,16 @@ import com.google.common.base.Preconditions;
|
|||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.HashMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.Multimaps;
|
import com.google.common.collect.Multimaps;
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import gnu.trove.TCollections;
|
import gnu.trove.TCollections;
|
||||||
import gnu.trove.map.TIntObjectMap;
|
import gnu.trove.map.TIntObjectMap;
|
||||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import net.md_5.bungee.BungeeCord;
|
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
import net.md_5.bungee.api.scheduler.ScheduledTask;
|
import net.md_5.bungee.api.scheduler.ScheduledTask;
|
||||||
import net.md_5.bungee.api.scheduler.TaskScheduler;
|
import net.md_5.bungee.api.scheduler.TaskScheduler;
|
||||||
@ -19,16 +21,21 @@ import net.md_5.bungee.api.scheduler.TaskScheduler;
|
|||||||
public class BungeeScheduler implements TaskScheduler
|
public class BungeeScheduler implements TaskScheduler
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private final ExecutorService s = Executors.newCachedThreadPool( new ThreadFactoryBuilder().setNameFormat( "Bungee Pool Thread #%1$d" ).build() );
|
||||||
private final AtomicInteger taskCounter = new AtomicInteger();
|
private final AtomicInteger taskCounter = new AtomicInteger();
|
||||||
private final TIntObjectMap<BungeeTask> tasks = TCollections.synchronizedMap( new TIntObjectHashMap<BungeeTask>() );
|
private final TIntObjectMap<BungeeTask> tasks = TCollections.synchronizedMap( new TIntObjectHashMap<BungeeTask>() );
|
||||||
private final Multimap<Plugin, BungeeTask> tasksByPlugin = Multimaps.synchronizedMultimap( HashMultimap.<Plugin, BungeeTask>create() );
|
private final Multimap<Plugin, BungeeTask> tasksByPlugin = Multimaps.synchronizedMultimap( HashMultimap.<Plugin, BungeeTask>create() );
|
||||||
|
|
||||||
|
public void shutdown()
|
||||||
|
{
|
||||||
|
s.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel(int id)
|
public void cancel(int id)
|
||||||
{
|
{
|
||||||
BungeeTask task = tasks.remove( id );
|
BungeeTask task = tasks.remove( id );
|
||||||
tasksByPlugin.values().remove( task );
|
tasksByPlugin.values().remove( task );
|
||||||
task.getFuture().cancel( false );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -61,21 +68,17 @@ public class BungeeScheduler implements TaskScheduler
|
|||||||
@Override
|
@Override
|
||||||
public ScheduledTask schedule(Plugin owner, Runnable task, long delay, TimeUnit unit)
|
public ScheduledTask schedule(Plugin owner, Runnable task, long delay, TimeUnit unit)
|
||||||
{
|
{
|
||||||
return prepare( owner, task ).setFuture( BungeeCord.getInstance().executors.schedule( task, delay, unit ) );
|
return schedule( owner, task, delay, 0, unit );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ScheduledTask schedule(Plugin owner, Runnable task, long delay, long period, TimeUnit unit)
|
public ScheduledTask schedule(Plugin owner, Runnable task, long delay, long period, TimeUnit unit)
|
||||||
{
|
|
||||||
return prepare( owner, task ).setFuture( BungeeCord.getInstance().executors.scheduleWithFixedDelay( task, delay, period, unit ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
private BungeeTask prepare(Plugin owner, Runnable task)
|
|
||||||
{
|
{
|
||||||
Preconditions.checkNotNull( owner, "owner" );
|
Preconditions.checkNotNull( owner, "owner" );
|
||||||
Preconditions.checkNotNull( task, "task" );
|
Preconditions.checkNotNull( task, "task" );
|
||||||
BungeeTask prepared = new BungeeTask( taskCounter.getAndIncrement(), owner, task );
|
BungeeTask prepared = new BungeeTask( this, taskCounter.getAndIncrement(), owner, task, delay, period, unit );
|
||||||
tasks.put( prepared.getId(), prepared );
|
tasks.put( prepared.getId(), prepared );
|
||||||
|
s.execute( prepared );
|
||||||
return prepared;
|
return prepared;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,75 @@
|
|||||||
package net.md_5.bungee.scheduler;
|
package net.md_5.bungee.scheduler;
|
||||||
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import lombok.AccessLevel;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.logging.Level;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Setter;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
import net.md_5.bungee.api.scheduler.ScheduledTask;
|
import net.md_5.bungee.api.scheduler.ScheduledTask;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class BungeeTask implements ScheduledTask
|
public class BungeeTask implements Runnable, ScheduledTask
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private final BungeeScheduler sched;
|
||||||
private final int id;
|
private final int id;
|
||||||
private final Plugin owner;
|
private final Plugin owner;
|
||||||
private final Runnable task;
|
private final Runnable task;
|
||||||
@Setter(AccessLevel.NONE)
|
//
|
||||||
private ScheduledFuture<?> future;
|
private final long delay;
|
||||||
|
private final long period;
|
||||||
|
private final AtomicBoolean running = new AtomicBoolean( true );
|
||||||
|
|
||||||
|
public BungeeTask(BungeeScheduler sched, int id, Plugin owner, Runnable task, long delay, long period, TimeUnit unit)
|
||||||
|
{
|
||||||
|
this.sched = sched;
|
||||||
|
this.id = id;
|
||||||
|
this.owner = owner;
|
||||||
|
this.task = task;
|
||||||
|
this.delay = unit.toMillis( delay );
|
||||||
|
this.period = unit.toMillis( period );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getDelay(TimeUnit unit)
|
public void cancel()
|
||||||
{
|
{
|
||||||
return future.getDelay( unit );
|
running.set( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
BungeeTask setFuture(ScheduledFuture<?> future)
|
@Override
|
||||||
|
public void run()
|
||||||
{
|
{
|
||||||
this.future = future;
|
if ( delay > 0 )
|
||||||
return this;
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep( delay );
|
||||||
|
} catch ( InterruptedException ex )
|
||||||
|
{
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( running.get() )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
task.run();
|
||||||
|
} catch ( Throwable t )
|
||||||
|
{
|
||||||
|
ProxyServer.getInstance().getLogger().log( Level.SEVERE, String.format( "Task %s encountered an exception", this ), t );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep( period );
|
||||||
|
} catch ( InterruptedException ex )
|
||||||
|
{
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sched.cancel( this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
package net.md_5.bungee.scheduler;
|
|
||||||
|
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
|
|
||||||
public class BungeeThreadPool extends ScheduledThreadPoolExecutor
|
|
||||||
{
|
|
||||||
|
|
||||||
public BungeeThreadPool(ThreadFactory threadFactory)
|
|
||||||
{
|
|
||||||
super( Integer.MAX_VALUE, threadFactory );
|
|
||||||
setKeepAliveTime( 5, TimeUnit.MINUTES );
|
|
||||||
allowCoreThreadTimeOut( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void afterExecute(Runnable r, Throwable t)
|
|
||||||
{
|
|
||||||
super.afterExecute( r, t );
|
|
||||||
if ( t != null )
|
|
||||||
{
|
|
||||||
ProxyServer.getInstance().getLogger().log( Level.SEVERE, "Task caused exception whilst running", t );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user