The phoebus PV API was designed for what we need in CS-Studio, for displays etc.
In a display, you don’t freeze until all PVs are connected.
Instead, you create the PVs, show their initial value as disconnected, then show the received values as the PVs connect and value updates arrive over time.
So the use case of waiting for a connection is rare, but would he handled as done in these examples:
https://github.com/ControlSystemStudio/phoebus/blob/master/core/pv/src/test/java/org/phoebus/pv/ReactivePVTest.java
In there you’ll find a few ways to create the PV, subscribe, and then wait for the first update or wait for 3 updates etc.
Similarly, when you write in a GUI you don’t freeze until the value has been written, and a read doesn’t block, either.
The basic PV.write(value) is just send-and-forget, and PV.read() returns the most recently received update, as mentioned in the info for the methods in
https://github.com/ControlSystemStudio/phoebus/blob/master/core/pv/src/main/java/org/phoebus/pv/PV.java:
/** Read current value
*
* <p>Should return the most recent value
* that listeners have received.
*
* @return Most recent value of the PV. <code>null</code> if no known value.
*/
public VType read()
/** Write value, no confirmation
* @param new_value Value to write to the PV
* @exception Exception on error
* @see #asyncWrite(Object)
*/
public void write(final Object new_value) throws Exception
If you do want to wait for a write to complete, or perform an active read that goes out and fetches a value, blocking until it receives the callback, look into the “async” variants:
/** Issue a read request
*
* <p>{@link CompletableFuture} allows waiting for
* and obtaining the result, or its <code>get()</code>
* calls will provide an error.
*
* <p>As a side effect, registered listeners will
* also receive the value obtained by this call.
*
* @return {@link CompletableFuture} for obtaining the result or Exception
* @exception Exception on error
*/
public CompletableFuture<VType> asyncRead() throws Exception
/** Write value with confirmation
*
* <p>{@link CompletableFuture} can be used to await completion
* of the write.
* The <code>get()</code> will not return a useful value (null),
* but they will throw an error if the write failed.
*
* @param new_value Value to write to the PV
* @return {@link CompletableFuture} for awaiting completion or exception
* @exception Exception on error
* @see #write(Object)
*/
public CompletableFuture<?> asyncWrite(final Object new_value) throws Exception
From:
Tech-talk <tech-talk-bounces at aps.anl.gov> on behalf of Wang, Lin via Tech-talk <tech-talk at aps.anl.gov>
Date: Monday, May 27, 2024 at 3:42 AM
To: tech-talk at aps.anl.gov <tech-talk at aps.anl.gov>
Subject: [EXTERNAL] pv.read() after pv.write() returns old value instead of new value using org.phoebus.pv.PV
Dear all,
I have two questions when using pv.read() and pv.write() as shown in the following code snippet,
import
org.epics.vtype.VType;
import
org.phoebus.pv.PV;
import
org.phoebus.pv.PVPool;
public
void
pvWrite()
throws
IOException,
Exception
PV
pv
=
PVPool.getPV("calcExample");
Thread.sleep(2000);
// Delay for PV connection
VType
oldValue
=
pv.read();
Thread.sleep(2000);
// Delay for PV writing
VType
newValue
=
pv.read();
System.out.println("Old
value: "
+
oldValue);
System.out.println("New
value: "
+
newValue);
1. pv.read() after pv.write() always returns the old value instead of the new value without a delay, what is the proper way other than sleep() to get the updated value after pv.write()?
2. Another delay is also needed after PVPool.getPV() to wait for PV connection, is there any elegent way like pendIO stuff to wait other than sleep()?
Thanks,
Lin