Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Commit

Permalink
changed notification of item state change listeners to asynchronous c…
Browse files Browse the repository at this point in the history
…alls and made it robust in case exceptions are thrown by the listener (#1704)

Signed-off-by: Kai Kreuzer <kai@openhab.org>
  • Loading branch information
kaikreuzer authored and maggu2810 committed Jun 20, 2016
1 parent 52b5a00 commit 1257c94
Showing 1 changed file with 25 additions and 8 deletions.
Expand Up @@ -17,7 +17,9 @@
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;

import org.eclipse.smarthome.core.common.ThreadPoolManager;
import org.eclipse.smarthome.core.events.EventPublisher;
import org.eclipse.smarthome.core.items.events.ItemEventFactory;
import org.eclipse.smarthome.core.types.Command;
Expand All @@ -26,6 +28,8 @@
import org.eclipse.smarthome.core.types.StateDescription;
import org.eclipse.smarthome.core.types.StateDescriptionProvider;
import org.eclipse.smarthome.core.types.UnDefType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
Expand All @@ -43,6 +47,10 @@
*/
abstract public class GenericItem implements ActiveItem {

private final Logger logger = LoggerFactory.getLogger(GenericItem.class);

private static final String ITEM_THREADPOOLNAME = "items";

protected EventPublisher eventPublisher;

protected Set<StateChangeListener> listeners = new CopyOnWriteArraySet<StateChangeListener>(
Expand Down Expand Up @@ -208,17 +216,26 @@ public void send(RefreshType command) {
internalSend(command);
}

protected void notifyListeners(State oldState, State newState) {
protected void notifyListeners(final State oldState, final State newState) {
// if nothing has changed, we send update notifications
Set<StateChangeListener> clonedListeners = null;
clonedListeners = new CopyOnWriteArraySet<StateChangeListener>(listeners);
for (StateChangeListener listener : clonedListeners) {
listener.stateUpdated(this, newState);
}
if (newState != null && !newState.equals(oldState)) {
for (StateChangeListener listener : clonedListeners) {
listener.stateChanged(this, oldState, newState);
}
ExecutorService pool = ThreadPoolManager.getPool(ITEM_THREADPOOLNAME);
for (final StateChangeListener listener : clonedListeners) {
pool.execute(new Runnable() {
@Override
public void run() {
try {
listener.stateUpdated(GenericItem.this, newState);
if (newState != null && !newState.equals(oldState)) {
listener.stateChanged(GenericItem.this, oldState, newState);
}
} catch (Exception e) {
logger.warn("failed notifying listener '{}' about state update of item {}: {}",
new Object[] { listener.toString(), GenericItem.this.getName(), e.getMessage() }, e);
}
}
});
}
}

Expand Down

0 comments on commit 1257c94

Please sign in to comment.