mirror of
https://github.com/SpigotMC/BungeeCord.git
synced 2024-11-27 20:59:12 +01:00
#1130: Add scheduler unit tests and make more robust.
This commit is contained in:
parent
28496e0471
commit
cf722de1d2
@ -96,8 +96,9 @@ public class Plugin
|
|||||||
{
|
{
|
||||||
if ( service == null )
|
if ( service == null )
|
||||||
{
|
{
|
||||||
service = Executors.newCachedThreadPool( new ThreadFactoryBuilder().setNameFormat( getDescription().getName() + " Pool Thread #%1$d" )
|
String name = ( getDescription() == null ) ? "unknown" : getDescription().getName();
|
||||||
.setThreadFactory( new GroupedThreadFactory( this ) ).build() );
|
service = Executors.newCachedThreadPool( new ThreadFactoryBuilder().setNameFormat( name + " Pool Thread #%1$d" )
|
||||||
|
.setThreadFactory( new GroupedThreadFactory( this, name ) ).build() );
|
||||||
}
|
}
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,9 @@ public class GroupedThreadFactory implements ThreadFactory
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupedThreadFactory(Plugin plugin)
|
public GroupedThreadFactory(Plugin plugin, String name)
|
||||||
{
|
{
|
||||||
this.group = new BungeeGroup( plugin.getDescription().getName() );
|
this.group = new BungeeGroup( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,6 +19,7 @@ import net.md_5.bungee.api.scheduler.TaskScheduler;
|
|||||||
public class BungeeScheduler implements TaskScheduler
|
public class BungeeScheduler implements TaskScheduler
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private final Object lock = new Object();
|
||||||
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() );
|
||||||
@ -36,10 +37,20 @@ public class BungeeScheduler implements TaskScheduler
|
|||||||
@Override
|
@Override
|
||||||
public void cancel(int id)
|
public void cancel(int id)
|
||||||
{
|
{
|
||||||
BungeeTask task = tasks.remove( id );
|
BungeeTask task = tasks.get( id );
|
||||||
|
Preconditions.checkArgument( task != null, "No task with id %s", id );
|
||||||
|
|
||||||
task.cancel();
|
task.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cancel0(BungeeTask task)
|
||||||
|
{
|
||||||
|
synchronized ( lock )
|
||||||
|
{
|
||||||
|
tasks.remove( task.getId() );
|
||||||
tasksByPlugin.values().remove( task );
|
tasksByPlugin.values().remove( task );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel(ScheduledTask task)
|
public void cancel(ScheduledTask task)
|
||||||
@ -80,8 +91,13 @@ public class BungeeScheduler implements TaskScheduler
|
|||||||
Preconditions.checkNotNull( owner, "owner" );
|
Preconditions.checkNotNull( owner, "owner" );
|
||||||
Preconditions.checkNotNull( task, "task" );
|
Preconditions.checkNotNull( task, "task" );
|
||||||
BungeeTask prepared = new BungeeTask( this, taskCounter.getAndIncrement(), owner, task, delay, period, unit );
|
BungeeTask prepared = new BungeeTask( this, taskCounter.getAndIncrement(), owner, task, delay, period, unit );
|
||||||
|
|
||||||
|
synchronized ( lock )
|
||||||
|
{
|
||||||
tasks.put( prepared.getId(), prepared );
|
tasks.put( prepared.getId(), prepared );
|
||||||
tasksByPlugin.put( owner, prepared );
|
tasksByPlugin.put( owner, prepared );
|
||||||
|
}
|
||||||
|
|
||||||
owner.getExecutorService().execute( prepared );
|
owner.getExecutorService().execute( prepared );
|
||||||
return prepared;
|
return prepared;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ public class BungeeTask implements Runnable, ScheduledTask
|
|||||||
|
|
||||||
if ( wasRunning )
|
if ( wasRunning )
|
||||||
{
|
{
|
||||||
sched.cancel( this.getId() );
|
sched.cancel0( this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
package net.md_5.bungee.api.plugin;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class DummyPlugin extends Plugin
|
||||||
|
{
|
||||||
|
|
||||||
|
public static final DummyPlugin INSTANCE = new DummyPlugin();
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package net.md_5.bungee.scheduler;
|
||||||
|
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import net.md_5.bungee.api.plugin.DummyPlugin;
|
||||||
|
import net.md_5.bungee.api.scheduler.ScheduledTask;
|
||||||
|
import net.md_5.bungee.api.scheduler.TaskScheduler;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class SchedulerTest
|
||||||
|
{
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRun() throws InterruptedException
|
||||||
|
{
|
||||||
|
TaskScheduler scheduler = new BungeeScheduler();
|
||||||
|
|
||||||
|
final CountDownLatch latch = new CountDownLatch( 1 );
|
||||||
|
|
||||||
|
scheduler.runAsync( DummyPlugin.INSTANCE, new Runnable()
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
latch.await( 5, TimeUnit.SECONDS );
|
||||||
|
|
||||||
|
Assert.assertEquals( 0, latch.getCount() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCancel() throws InterruptedException
|
||||||
|
{
|
||||||
|
TaskScheduler scheduler = new BungeeScheduler();
|
||||||
|
AtomicBoolean b = new AtomicBoolean();
|
||||||
|
|
||||||
|
ScheduledTask task = setup( scheduler, b );
|
||||||
|
scheduler.cancel( task.getId() );
|
||||||
|
Thread.sleep( 250 );
|
||||||
|
Assert.assertFalse( b.get() );
|
||||||
|
|
||||||
|
task = setup( scheduler, b );
|
||||||
|
scheduler.cancel( task );
|
||||||
|
Thread.sleep( 250 );
|
||||||
|
Assert.assertFalse( b.get() );
|
||||||
|
|
||||||
|
task = setup( scheduler, b );
|
||||||
|
scheduler.cancel( task.getOwner() );
|
||||||
|
Thread.sleep( 250 );
|
||||||
|
Assert.assertFalse( b.get() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScheduleAndRepeat() throws InterruptedException
|
||||||
|
{
|
||||||
|
TaskScheduler scheduler = new BungeeScheduler();
|
||||||
|
AtomicBoolean b = new AtomicBoolean();
|
||||||
|
|
||||||
|
setup( scheduler, b );
|
||||||
|
Thread.sleep( 250 );
|
||||||
|
Assert.assertTrue( b.get() );
|
||||||
|
|
||||||
|
b.set( false );
|
||||||
|
Thread.sleep( 250 );
|
||||||
|
Assert.assertTrue( b.get() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScheduledTask setup(TaskScheduler scheduler, final AtomicBoolean hasRun)
|
||||||
|
{
|
||||||
|
return scheduler.schedule( DummyPlugin.INSTANCE, new Runnable()
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
hasRun.set( true );
|
||||||
|
}
|
||||||
|
}, 100, 100, TimeUnit.MILLISECONDS );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user