我在用openstack4j进行与openstack的互连的时候,想用spring编写成一个服务的api,从自己的服务器接口直接获取openstack的信息。但是在编写的时候,发现了一个问题。就是openstack4j创建的client只能用一次,再深入调查,发现只能在初始化client的线程用一次,其他线程会报如下错误:
org.openstack4j.api.exceptions.OS4JException: Unable to retrieve current session. Please verify thread has a current session available.
然后就百度了下问题,主要原因是4j里的session是用的ThreadLocal类型,因此线程间不通用。简书这位博主解释的挺到位,那我这里就不多做解释了,直接贴链接:https://www.jianshu.com/p/fd9abf27ae71。
但是文章中没给解决办法,只说了问题的原理。随后我在openstack4j的官网找到了解决办法,就是用client的Token为每个线程新生成client,但token是唯一的,那么这个client其实也是同一个,链接如下:http://www.openstack4j.com/learn/threads/。
实现代码如下:
v3的情况下:
// Grab the token from the client in the thread that did the authentication
Token token = os.getToken();
// Spawn off a thread giving it the access
myThreadExecutor.submit(new MyRunnableOrCallable(token));
// Example of the Runnable or other object invoked in a new thread
public class MyRunnable implements Runnable {
private OSClientV3 clientV3;
public MyRunnable(Access access) {
clientV3 = OSFactory.clientFromToken(token);
}
public void run() {
// can now use the client :)
}
}
V2的情况下:
// Grab the access from the client in the thread that did the authentication
Access access = os.getAccess();
// Spawn off a thread giving it the access
myThreadExecutor.submit(new MyRunnableOrCallable(access));
// Example of the Runnable or other object invoked in a new thread
public class MyRunnable implements Runnable {
private OSClient clientV2;
public MyRunnable(Access access) {
clientV2 = OSFactory.clientFromAccess(access);
}
public void run() {
// can now use the client :)
}
}