I came across the following snippet of code:
AmqpConnection connection;
AmqpClient client = AmqpClient.create(someOptions);
client.connect(ar -> {
if (ar.failed()) {
System.out.println("Connection failed.");
} else {
System.out.println("Connection succeeded");
connection = ar.result();
}
});
// Wait for connection to succeed before moving on...
connection.doSomething() //etc...
I would like to use it but there needs to be a blocking mechanism so connection is not null. I do not want to move connection.doSomething() inside the lambda. What is the proper way to block in that scenario? A while loop with a timer? A Future/Callable? Something else?
Future is one great way, however does connect
return one?
You said you prefer not to, but another option would be to add it all to the lambda itself - if you're waiting anyway, why not do it together?
I think the way you have it set now is not a good one, as lambdas are not supposed to affect variables outside their body (I believe you'll receive a compile error on this).
There are some more ways using java.util.concurrent
, but I think these 2 are the best.
EDIT
Following discussion in the comments, and clarification that the connection is thread safe, you can split to ConnectionUtil
that creates the connection (once-only), and ConnectionUsage
as a usage example:
public class ConnectionUtil {
private static AmqpConnection connection;
private static Lock lock = new ReentrantLock();
public static AmqpConnection getConnection() {
if (connection == null) {
lock.lock();
if (connection == null) {
AmqpClient client = AmqpClient.create(someOptions);
client.connect(ar -> {
if (ar.failed()) {
System.out.println("Connection failed.");
} else {
System.out.println("Connection succeeded");
connection = ar.result();
}
});
}
lock.unlock();
}
return connection;
}
public static <T> T doWithConnection(Function<AmqpConnection, T> function) {
return function.apply(getConnection());
}
}
For usage, you have 2 options - if it is okay to pass the AmqpConnection
around, you can call getConnection
, and if not have your lambda ready and pass it to doWithConnection
:
public class ConnectionUsage {
public static void main(String[] args) {
// you can get the connection and do stuff
AmqpConnection connection = ConnectionUtil.getConnection();
// you can call the util and let him do stuff
Function<AmqpConnection, Void> func = amqpConnection -> {
// do stuff
return null;
};
ConnectionUtil.doWithConnection(func);
}
}