我在用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 :)
}
}