From 426df6cf0154f559c105ffe8c0b8696af6bd90fb Mon Sep 17 00:00:00 2001 From: ingvord Date: Fri, 25 Oct 2019 16:29:04 +0200 Subject: [PATCH] Close #18 & #19 --- .../hzg/wpn/idl/EventDevStateAwaitor.java | 133 ------------------ src/main/java/hzg/wpn/idl/IDLDeviceProxy.java | 12 +- .../java/hzg/wpn/idl/PollDevStateAwaitor.java | 62 +++++--- .../hzg/wpn/idl/TangoDevStateAwaitor.java | 33 +++-- .../java/hzg/wpn/idl/IDLDeviceProxyTest.java | 8 +- 5 files changed, 73 insertions(+), 175 deletions(-) delete mode 100644 src/main/java/hzg/wpn/idl/EventDevStateAwaitor.java diff --git a/src/main/java/hzg/wpn/idl/EventDevStateAwaitor.java b/src/main/java/hzg/wpn/idl/EventDevStateAwaitor.java deleted file mode 100644 index b89ad62..0000000 --- a/src/main/java/hzg/wpn/idl/EventDevStateAwaitor.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * The main contributor to this project is Institute of Materials Research, - * Helmholtz-Zentrum Geesthacht, - * Germany. - * - * This project is a contribution of the Helmholtz Association Centres and - * Technische Universitaet Muenchen to the ESS Design Update Phase. - * - * The project's funding reference is FKZ05E11CG1. - * - * Copyright (c) 2012. Institute of Materials Research, - * Helmholtz-Zentrum Geesthacht, - * Germany. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -package hzg.wpn.idl; - -import com.google.common.base.Preconditions; -import fr.esrf.Tango.DevState; -import org.tango.client.ez.proxy.*; - -/** - * @author Igor Khokhriakov - * @since 05.06.12 - */ -public class EventDevStateAwaitor extends TangoDevStateAwaitor { - - private final Object internalLock = new Object(); - private volatile Throwable error = null; - private volatile TangoEventListener listener; - - public EventDevStateAwaitor(TangoProxy proxy, TangoProxyExceptionHandler handler) { - super(proxy, handler); - } - - @Override - public void waitUntil(DevState targetState, long timeout) { - Preconditions.checkArgument(timeout > 0L, "timeout can not be less or equal to 0"); - try { - DevState crtState = getProxy().readAttribute(STATE); - setCrtDevState(crtState); - - subscribeToStateChange(); - synchronized (internalLock) { - while (!targetStateReached(targetState)) { - internalLock.wait(timeout); - } - } - listener = null; - } catch (TangoProxyException devFailed) { - throw getHandler().handle(devFailed); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw getHandler().handle(error != null ? error : e); - } catch (NoSuchAttributeException e) { - throw getHandler().handle(e); - } - } - - - @Override - public void waitUntil(DevState targetState) { - waitUntil(targetState, Long.MAX_VALUE); - } - - @Override - public void waitUntilNot(DevState targetState, long timeout) { - Preconditions.checkArgument(timeout > 0L, "timeout can not be less or equal to 0"); - try { - DevState crtState = getProxy().readAttribute(STATE); - setCrtDevState(crtState); - - subscribeToStateChange(); - synchronized (internalLock) { - while (targetStateReached(targetState)) { - internalLock.wait(timeout); - } - } - listener = null; - } catch (TangoProxyException devFailed) { - throw getHandler().handle(devFailed); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw getHandler().handle(error != null ? error : e); - } catch (NoSuchAttributeException e) { - throw getHandler().handle(e); - } - } - - @Override - public void waitUntilNot(DevState targetState) { - waitUntilNot(targetState, Long.MAX_VALUE); - } - - private void subscribeToStateChange() throws TangoProxyException, NoSuchAttributeException { - final Thread mainThread = Thread.currentThread(); - getProxy().subscribeToEvent(STATE, TangoEvent.CHANGE); - getProxy().addEventListener(STATE, TangoEvent.CHANGE, listener = new TangoEventListener() { - @Override - public void onEvent(EventData eventData) { - DevState crtState = eventData.getValue(); - if (crtState == null) return; - synchronized (internalLock) { - setCrtDevState(crtState); - internalLock.notifyAll(); - } - } - - @Override - public void onError(Exception e) { - error = e; - //does not work in IDL -// getLog().error(e.getMessage(),e); - mainThread.interrupt(); - } - }); - } - -} diff --git a/src/main/java/hzg/wpn/idl/IDLDeviceProxy.java b/src/main/java/hzg/wpn/idl/IDLDeviceProxy.java index c95bf02..e97562f 100644 --- a/src/main/java/hzg/wpn/idl/IDLDeviceProxy.java +++ b/src/main/java/hzg/wpn/idl/IDLDeviceProxy.java @@ -140,9 +140,11 @@ public IDLDeviceProxy(String name) { */ public IDLDeviceProxy(String name, boolean useEventsForWaitUntil) { logger.debug("Creating proxy for device[{},useEventsForWaitUntil={}]", name, useEventsForWaitUntil); + if (useEventsForWaitUntil) + throw handler.handle(new UnsupportedOperationException("useEventsForWaitUntil=true is no longer supported use false")); try { this.proxy = TangoProxies.newDeviceProxyWrapper(name); - this.awaitor = useEventsForWaitUntil ? new EventDevStateAwaitor(this.proxy, handler) : new PollDevStateAwaitor(this.proxy, handler); + this.awaitor = new PollDevStateAwaitor(this.proxy, handler); } catch (TangoProxyException devFailed) { throw handler.handle(devFailed); } @@ -236,11 +238,11 @@ public void waitUntil(String state) { * @param state desired state in String format, i.e. "ON","RUNNING" etc (case insensitive) * @throws RuntimeException */ - public void waitUntil(String state, long delay) { + public void waitUntil(String state, long timeout) { logger.trace("Waiting until {}/{}", proxy.getName(), state); try { DevState targetDevState = devStates.get(state.toUpperCase()); - awaitor.waitUntil(targetDevState, delay); + awaitor.waitUntil(targetDevState, timeout, PollDevStateAwaitor.SLEEP_GRANULARITY); logger.trace("Done waiting."); } catch (Exception e) { if (e.getCause() instanceof ReadAttributeException) { @@ -281,11 +283,11 @@ public void waitUntilNot(String state) { } } - public void waitUntilNot(String state, long delay) { + public void waitUntilNot(String state, long timeout) { logger.trace("Waiting until not {}/{}", proxy.getName(), state); try { DevState targetDevState = devStates.get(state.toUpperCase()); - awaitor.waitUntilNot(targetDevState, delay); + awaitor.waitUntilNot(targetDevState, timeout, PollDevStateAwaitor.SLEEP_GRANULARITY); logger.trace("Done waiting."); } catch (Exception e) { if (e.getCause() instanceof ReadAttributeException) { diff --git a/src/main/java/hzg/wpn/idl/PollDevStateAwaitor.java b/src/main/java/hzg/wpn/idl/PollDevStateAwaitor.java index 2cdb866..0d1fb21 100644 --- a/src/main/java/hzg/wpn/idl/PollDevStateAwaitor.java +++ b/src/main/java/hzg/wpn/idl/PollDevStateAwaitor.java @@ -36,66 +36,83 @@ import org.tango.client.ez.proxy.TangoProxy; import org.tango.client.ez.proxy.TangoProxyException; +import java.util.concurrent.TimeoutException; + /** * @author Igor Khokhriakov * @since 06.06.12 */ public class PollDevStateAwaitor extends TangoDevStateAwaitor { public static final long SLEEP_GRANULARITY = 10L; + public static final long DEFAULT_TIMEOUT = 30_000L; + + public PollDevStateAwaitor(TangoProxy proxy, TangoProxyExceptionHandler handler) { + super(proxy); + } @Override - public void waitUntil(DevState targetState, long delay) { + public void waitUntil(DevState targetState, long timeout, long delay) throws Exception { + Preconditions.checkArgument(timeout > 0L, "timeout can not be less or equal to 0"); Preconditions.checkArgument(delay > 0L, "delay can not be less or equal to 0"); - while (true) { + long start = System.currentTimeMillis(); + long tooLate = start + timeout; + + + while (!Thread.currentThread().isInterrupted()) { try { pollCrtState(); //do not wait if state are the same if (targetStateReached(targetState)) { return; + } else if (tooLate < System.currentTimeMillis()) { + throw new TimeoutException(String.format("Timeout has exceed! %s did not reach state %s within %d ms", getProxy().getName(), targetState, timeout)); } else { Thread.sleep(delay); } - } catch (TangoProxyException devFailed) { - throw getHandler().handle(devFailed); } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw getHandler().handle(e); - } catch (NoSuchAttributeException e) { - throw getHandler().handle(e); + throw e; } } } @Override - public void waitUntil(DevState targetState) { - waitUntil(targetState, SLEEP_GRANULARITY); + public void waitUntil(DevState targetState, long delay) throws Exception { + waitUntil(targetState, DEFAULT_TIMEOUT, delay); + } + + @Override + public void waitUntil(DevState targetState) throws Exception { + waitUntil(targetState, DEFAULT_TIMEOUT, SLEEP_GRANULARITY); } - public void waitUntilNot(DevState targetState, long delay) { - Preconditions.checkArgument(delay > 0L, "dealy can not be less or equal to 0"); - while (true) { + public void waitUntilNot(DevState targetState, long timeout, long delay) throws Exception { + Preconditions.checkArgument(timeout > 0L, "timeout can not be less or equal to 0"); + Preconditions.checkArgument(delay > 0L, "delay can not be less or equal to 0"); + long start = System.currentTimeMillis(); + long tooLate = start + timeout; + + while (!Thread.currentThread().isInterrupted()) { try { pollCrtState(); //wait if states are the same - if (targetStateReached(targetState)) { + if (tooLate < System.currentTimeMillis()) { + throw new TimeoutException(String.format("Timeout has exceed! %s did not change state %s within %d ms", getProxy().getName(), targetState, timeout)); + } else if (targetStateReached(targetState)) { Thread.sleep(delay); } else { return; } - } catch (TangoProxyException devFailed) { - throw getHandler().handle(devFailed); } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw getHandler().handle(e); - } catch (NoSuchAttributeException e) { - throw getHandler().handle(e); + throw e; } } } @Override - public void waitUntilNot(DevState targetState) { - waitUntilNot(targetState, SLEEP_GRANULARITY); + public void waitUntilNot(DevState targetState, long timeout) throws Exception { + waitUntilNot(targetState, timeout, SLEEP_GRANULARITY); } private void pollCrtState() throws TangoProxyException, NoSuchAttributeException { @@ -103,7 +120,8 @@ private void pollCrtState() throws TangoProxyException, NoSuchAttributeException setCrtDevState(crtState); } - public PollDevStateAwaitor(TangoProxy proxy, TangoProxyExceptionHandler handler) { - super(proxy, handler); + @Override + public void waitUntilNot(DevState targetState) throws Exception { + waitUntilNot(targetState, DEFAULT_TIMEOUT, SLEEP_GRANULARITY); } } diff --git a/src/main/java/hzg/wpn/idl/TangoDevStateAwaitor.java b/src/main/java/hzg/wpn/idl/TangoDevStateAwaitor.java index 170eace..f263aad 100644 --- a/src/main/java/hzg/wpn/idl/TangoDevStateAwaitor.java +++ b/src/main/java/hzg/wpn/idl/TangoDevStateAwaitor.java @@ -42,12 +42,10 @@ public abstract class TangoDevStateAwaitor { public static final String STATE = "State"; private final TangoProxy proxy; - private final TangoProxyExceptionHandler handler; private final AtomicReference crtDevState = new AtomicReference(); - protected TangoDevStateAwaitor(TangoProxy proxy, TangoProxyExceptionHandler handler) { + protected TangoDevStateAwaitor(TangoProxy proxy) { this.proxy = proxy; - this.handler = handler; } /** @@ -56,7 +54,7 @@ protected TangoDevStateAwaitor(TangoProxy proxy, TangoProxyExceptionHandler hand * @param targetState wait until the state * @throws RuntimeException */ - public abstract void waitUntil(DevState targetState); + public abstract void waitUntil(DevState targetState) throws Exception; /** * Blocks current thread until the device is in targetState @@ -64,7 +62,7 @@ protected TangoDevStateAwaitor(TangoProxy proxy, TangoProxyExceptionHandler hand * @param targetState current device state * @throws RuntimeException */ - public abstract void waitUntilNot(DevState targetState); + public abstract void waitUntilNot(DevState targetState) throws Exception; /** * Blocks current thread until device state changes to targetState @@ -72,7 +70,15 @@ protected TangoDevStateAwaitor(TangoProxy proxy, TangoProxyExceptionHandler hand * @param targetState wait until the state * @throws RuntimeException */ - public abstract void waitUntil(DevState targetState, long delay); + public abstract void waitUntil(DevState targetState, long timeout, long delay) throws Exception; + + /** + * Blocks current thread until device state changes to targetState + * + * @param targetState wait until the state + * @throws RuntimeException + */ + public abstract void waitUntil(DevState targetState, long delay) throws Exception; /** * Blocks current thread until the device is in targetState @@ -80,7 +86,16 @@ protected TangoDevStateAwaitor(TangoProxy proxy, TangoProxyExceptionHandler hand * @param targetState current device state * @throws RuntimeException */ - public abstract void waitUntilNot(DevState targetState, long delay); + public abstract void waitUntilNot(DevState targetState, long timeout, long delay) throws Exception; + + + /** + * Blocks current thread until the device is in targetState + * + * @param targetState current device state + * @throws RuntimeException + */ + public abstract void waitUntilNot(DevState targetState, long delay) throws Exception; protected boolean targetStateReached(DevState targetState) { @@ -94,8 +109,4 @@ protected void setCrtDevState(DevState state) { protected TangoProxy getProxy() { return proxy; } - - protected TangoProxyExceptionHandler getHandler() { - return handler; - } } diff --git a/src/test/java/hzg/wpn/idl/IDLDeviceProxyTest.java b/src/test/java/hzg/wpn/idl/IDLDeviceProxyTest.java index f547fb8..4a5a6b2 100644 --- a/src/test/java/hzg/wpn/idl/IDLDeviceProxyTest.java +++ b/src/test/java/hzg/wpn/idl/IDLDeviceProxyTest.java @@ -312,10 +312,10 @@ public void testExecuteCommand_State() throws Exception { //@Test public void testAwaitUntil() throws Exception { - IDLDeviceProxy instance = new IDLDeviceProxy(TEST_TANGO); + IDLDeviceProxy instance = new IDLDeviceProxy("tango://localhost:10000/sys/tg_test/1"); long nanosStart = System.nanoTime(); - instance.waitUntil("running"); + instance.waitUntil("running", 3000); long nanosEnd = System.nanoTime(); long awaited = nanosEnd - nanosStart; assertTrue(awaited > 409343233); @@ -324,11 +324,11 @@ public void testAwaitUntil() throws Exception { //@Test public void testAwaitUntilNot() throws Exception { - IDLDeviceProxy instance = new IDLDeviceProxy(TEST_TANGO); + IDLDeviceProxy instance = new IDLDeviceProxy("tango://localhost:10000/sys/tg_test/1"); long nanosStart = System.nanoTime(); //device is started in fault state - instance.waitUntilNot("fault"); + instance.waitUntilNot("fault", 3000); long nanosEnd = System.nanoTime(); long awaited = nanosEnd - nanosStart; assertTrue(awaited > 409343233);