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;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
/**
|
||||
@ -31,11 +30,7 @@ public interface ScheduledTask
|
||||
Runnable getTask();
|
||||
|
||||
/**
|
||||
* Get the delay in the specified unit before this task will next be
|
||||
* executed.
|
||||
*
|
||||
* @param unit the unit to get the delay in
|
||||
* @return the time before the next execution of this task
|
||||
* Cancel this task to suppress subsequent executions.
|
||||
*/
|
||||
long getDelay(TimeUnit unit);
|
||||
void cancel();
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
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.plugin.Plugin;
|
||||
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.command.*;
|
||||
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.PacketFAPluginMessage;
|
||||
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.util.CaseInsensitiveMap;
|
||||
import org.fusesource.jansi.AnsiConsole;
|
||||
@ -83,10 +80,6 @@ public class BungeeCord extends ProxyServer
|
||||
* Localization bundle.
|
||||
*/
|
||||
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() );
|
||||
/**
|
||||
* locations.yml save thread.
|
||||
@ -117,7 +110,7 @@ public class BungeeCord extends ProxyServer
|
||||
@Getter
|
||||
private final File pluginsFolder = new File( "plugins" );
|
||||
@Getter
|
||||
private final TaskScheduler scheduler = new BungeeScheduler();
|
||||
private final BungeeScheduler scheduler = new BungeeScheduler();
|
||||
@Getter
|
||||
private ConsoleReader consoleReader;
|
||||
@Getter
|
||||
@ -288,8 +281,6 @@ public class BungeeCord extends ProxyServer
|
||||
{
|
||||
BungeeCord.this.isRunning = false;
|
||||
|
||||
executors.shutdown();
|
||||
|
||||
stopListeners();
|
||||
getLogger().info( "Closing pending connections" );
|
||||
|
||||
@ -329,6 +320,7 @@ public class BungeeCord extends ProxyServer
|
||||
getScheduler().cancel( plugin );
|
||||
}
|
||||
|
||||
scheduler.shutdown();
|
||||
getLogger().info( "Thankyou and goodbye" );
|
||||
System.exit( 0 );
|
||||
}
|
||||
|
@ -4,14 +4,16 @@ import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import gnu.trove.TCollections;
|
||||
import gnu.trove.map.TIntObjectMap;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
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.scheduler.ScheduledTask;
|
||||
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
|
||||
{
|
||||
|
||||
private final ExecutorService s = Executors.newCachedThreadPool( new ThreadFactoryBuilder().setNameFormat( "Bungee Pool Thread #%1$d" ).build() );
|
||||
private final AtomicInteger taskCounter = new AtomicInteger();
|
||||
private final TIntObjectMap<BungeeTask> tasks = TCollections.synchronizedMap( new TIntObjectHashMap<BungeeTask>() );
|
||||
private final Multimap<Plugin, BungeeTask> tasksByPlugin = Multimaps.synchronizedMultimap( HashMultimap.<Plugin, BungeeTask>create() );
|
||||
|
||||
public void shutdown()
|
||||
{
|
||||
s.shutdown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(int id)
|
||||
{
|
||||
BungeeTask task = tasks.remove( id );
|
||||
tasksByPlugin.values().remove( task );
|
||||
task.getFuture().cancel( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -61,21 +68,17 @@ public class BungeeScheduler implements TaskScheduler
|
||||
@Override
|
||||
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
|
||||
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( 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 );
|
||||
s.execute( prepared );
|
||||
return prepared;
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,75 @@
|
||||
package net.md_5.bungee.scheduler;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.AccessLevel;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
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.scheduler.ScheduledTask;
|
||||
|
||||
@Data
|
||||
public class BungeeTask implements ScheduledTask
|
||||
public class BungeeTask implements Runnable, ScheduledTask
|
||||
{
|
||||
|
||||
private final BungeeScheduler sched;
|
||||
private final int id;
|
||||
private final Plugin owner;
|
||||
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
|
||||
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;
|
||||
return this;
|
||||
if ( delay > 0 )
|
||||
{
|
||||
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