短い: あるクライアントでロックを作成し、別のクライアントで解放したい。そのため、そのために失効を使用しようとしています。機能していません。詳細 (および私のコード) は以下のとおりです。どんな助けでも大歓迎です!
long: 1 つのスレッド (独自のクライアントを使用) が最初のロック (更新) を設定し、次に 2 番目のスレッド (クライアントが元のクライアントと同じである場合もそうでない場合もある) が 2 番目のロックを設定するシステムがあります。次に、いくつかの作業を行い、そのロックを解放してから、最初のロックを解放します。このコードは、2 つの異なるクライアントにロックを取得させることで、2 つのスレッドをシミュレートします。
ただし、2 番目のクライアントは最初のクライアントからのロックを取り消すことができません。「失効リスナー」がトリガーされることはありません。ウェブを精査しましたが、例が見つかりませんでした。このコードは、ローカル ホストのポート 2181 で Zookeeper サーバーが実行されていることを前提としています。
理想的には、ロックが設定されているかどうかをすぐに確認するために別の場所からも調べたいと思いますが、おそらく非常に短いタイムアウト (5 ミリ秒) での取得がそれを実現します。
また、ロックを解放した後にロックを取得することは良い考えですか? (システムを詰まらせないために?)
ありがとう
-ジル
追伸: apache curator user mailing list にも投稿されました
回答があればクロスポストします。
メーリング リストから 1 つの回答を得ました: Jordan Zimmerman 8:46 PM (13 時間前) 多くの問題があります。
- ドキュメントはこれについて明確ではありませんが、ロックが取得される前に makeRevocable() を呼び出す必要があります。ドキュメントを修正するには、Jira/PR を送信してください。
- テストでは、Revoker.attemptRevoke が間違ったパスを使用していました。これはロックのパスである必要があるため、「Revoker.attemptRevoke(client2, ipMutex.getLockPath());」</li>
- InterProcessMutex は、ロックを所有するスレッドを追跡します。したがって、lock.release(); リボーカーでは機能しません。代わりに InterProcessSemaphoreMutex を使用することをお勧めします。
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.framework.recipes.locks.RevocationListener;
import org.apache.curator.framework.recipes.locks.Revoker;
import org.apache.curator.retry.ExponentialBackoffRetry;
public class MultipleClientExample {
/*entry point
*/
public static void main(String[] args){
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
String zookeeperConnectionString = "127.0.0.1:2181";
CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy);
client.start();
try {
System.out.println("testing locks....");
InterProcessMutex ipMutex = new InterProcessMutex(client, "/mpx-updates/guid123/update");
boolean acquired = ipMutex.acquire(3, TimeUnit.SECONDS);
System.out.println("got the lock(update)?" + acquired);
RevocationListener<InterProcessMutex> rl = new MyRevocationListener();
ipMutex.makeRevocable(rl);
InterProcessMutex ipMutex2 = new InterProcessMutex(client, "/mpx-updates/guid123/swap");
boolean a2 = ipMutex2.acquire(3, TimeUnit.SECONDS);
System.out.println("got the lock(swap)?" + a2);
System.out.println("got the first lock in this process? " + ipMutex.isAcquiredInThisProcess());
// make a new client; see if it can get the lock!
CuratorFramework client2 = CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy);
client2.start();
InterProcessMutex ipMutex1Retry = new InterProcessMutex(client2, "/mpx-updates/guid123/update");
boolean a3 = ipMutex1Retry.acquire(3, TimeUnit.SECONDS);
System.out.println("got the lock(retry/update) ?" + a3);
System.out.println("got the first lock in this process? " + ipMutex1Retry.isAcquiredInThisProcess());
Revoker.attemptRevoke(client2, "/mpx-updates/guid123/update");
a3 = ipMutex1Retry.acquire(3, TimeUnit.SECONDS);
System.out.println("AGAIN: got the lock(retry/update) ?" + a3);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class MyRevocationListener implements RevocationListener<InterProcessMutex> {
/*
* (non-Javadoc)
*
* @see org.apache.curator.framework.recipes.locks.RevocationListener#revocationRequested(java.lang.Object)
*/
@Override
public void revocationRequested(InterProcessMutex lock) {
//this seems to never be called
Collection<String> participantNodes = null;
try {
System.out.println("revocation was requested....");
System.out.println("ick ick revocation requested....");
participantNodes = lock.getParticipantNodes();
lock.release();
System.out.println("revoked lock at path: " + participantNodes);
} catch (Exception e) {
System.out.println("problem revoking lock with path: " + participantNodes + "; it was not revoked");
}
}
}
}