Allow to get an Iterator over all of the EventExecutor an EventExecutorGroup contains. Beside this allow to get basic stats for the EventExecutor like pendingTasks and executorCount

This commit is contained in:
Norman Maurer 2013-04-09 07:15:49 +02:00 committed by Trustin Lee
parent 067a2af700
commit 0efebd5a82
7 changed files with 113 additions and 3 deletions

View File

@ -15,6 +15,8 @@
*/ */
package io.netty.util.concurrent; package io.netty.util.concurrent;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.AbstractExecutorService; import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.RunnableFuture; import java.util.concurrent.RunnableFuture;
@ -30,6 +32,11 @@ public abstract class AbstractEventExecutor extends AbstractExecutorService impl
return this; return this;
} }
@Override
public Iterator<EventExecutor> iterator() {
return new EventExecutorIterator();
}
@Override @Override
public <V> Promise<V> newPromise() { public <V> Promise<V> newPromise() {
return new DefaultPromise<V>(this); return new DefaultPromise<V>(this);
@ -91,4 +98,26 @@ public abstract class AbstractEventExecutor extends AbstractExecutorService impl
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
private final class EventExecutorIterator implements Iterator<EventExecutor> {
private boolean nextCalled;
@Override
public boolean hasNext() {
return !nextCalled;
}
@Override
public EventExecutor next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
nextCalled = true;
return AbstractEventExecutor.this;
}
@Override
public void remove() {
throw new UnsupportedOperationException("read-only");
}
}
} }

View File

@ -15,8 +15,8 @@
*/ */
package io.netty.util.concurrent; package io.netty.util.concurrent;
import java.util.Iterator;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -26,13 +26,20 @@ import java.util.concurrent.TimeUnit;
* to shut them down in a global fashion. * to shut them down in a global fashion.
* *
*/ */
public interface EventExecutorGroup extends ScheduledExecutorService { public interface EventExecutorGroup extends ScheduledExecutorService, Iterable<EventExecutor> {
/** /**
* Returns one of the {@link EventExecutor}s that belong to this group. * Returns one of the {@link EventExecutor}s that belong to this group.
*/ */
EventExecutor next(); EventExecutor next();
/**
* Returns a read-only {@link Iterator} over all {@link EventExecutor}, which are handled by this
* {@link EventExecutorGroup} at the time of invoke this method.
*/
@Override
Iterator<EventExecutor> iterator();
@Override @Override
Future<?> submit(Runnable task); Future<?> submit(Runnable task);

View File

@ -16,6 +16,7 @@
package io.netty.util.concurrent; package io.netty.util.concurrent;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
@ -75,6 +76,19 @@ public abstract class MultithreadEventExecutorGroup extends AbstractEventExecuto
return children[Math.abs(childIndex.getAndIncrement() % children.length)]; return children[Math.abs(childIndex.getAndIncrement() % children.length)];
} }
@Override
public Iterator<EventExecutor> iterator() {
return children().iterator();
}
/**
* Return the number of {@link EventExecutor} this implementation uses. This number is the maps
* 1:1 to the threads it use.
*/
public final int executorCount() {
return children.length;
}
/** /**
* Return a safe-copy of all of the children of this group. * Return a safe-copy of all of the children of this group.
*/ */

View File

@ -260,6 +260,13 @@ public abstract class SingleThreadEventExecutor extends AbstractEventExecutor {
return !taskQueue.isEmpty(); return !taskQueue.isEmpty();
} }
/**
* Return the number of tasks that are pending for processing.
*/
public final int pendingTasks() {
return taskQueue.size();
}
/** /**
* Add a task to the task queue, or throws a {@link RejectedExecutionException} if this instance was shutdown * Add a task to the task queue, or throws a {@link RejectedExecutionException} if this instance was shutdown
* before. * before.

View File

@ -0,0 +1,45 @@
/*
* Copyright 2013 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.util.internal;
import java.util.Iterator;
public final class ReadOnlyIterator<T> implements Iterator<T> {
private final Iterator<? extends T> iterator;
public ReadOnlyIterator(Iterator<? extends T> iterator) {
if (iterator == null) {
throw new NullPointerException("iterator");
}
this.iterator = iterator;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public T next() {
return iterator.next();
}
@Override
public void remove() {
throw new UnsupportedOperationException("read-only");
}
}

View File

@ -18,7 +18,7 @@ package io.netty.channel;
import io.netty.util.concurrent.EventExecutorGroup; import io.netty.util.concurrent.EventExecutorGroup;
/** /**
* Special {@link io.netty.util.concurrent.EventExecutorGroup} which allows to register {@link Channel}'s that get * Special {@link EventExecutorGroup} which allows to register {@link Channel}'s that get
* processed for later selection during the event loop. * processed for later selection during the event loop.
* *
*/ */

View File

@ -17,9 +17,12 @@ package io.netty.channel;
import io.netty.util.concurrent.AbstractEventExecutorGroup; import io.netty.util.concurrent.AbstractEventExecutorGroup;
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.internal.PlatformDependent; import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.ReadOnlyIterator;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator;
import java.util.Queue; import java.util.Queue;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
@ -105,6 +108,11 @@ public class ThreadPerChannelEventLoopGroup extends AbstractEventExecutorGroup i
return new ThreadPerChannelEventLoop(this); return new ThreadPerChannelEventLoop(this);
} }
@Override
public Iterator<EventExecutor> iterator() {
return new ReadOnlyIterator<EventExecutor>(activeChildren.iterator());
}
@Override @Override
public EventLoop next() { public EventLoop next() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();