Search in sources :

Example 1 with CampaignResponse

use of io.etcd.jetcd.election.CampaignResponse in project jetcd by coreos.

the class ElectionTest method testRetryCampaignWithDifferentValue.

@Test
public void testRetryCampaignWithDifferentValue() throws Exception {
    ByteSequence electionName = ByteSequence.from(randomString(), StandardCharsets.UTF_8);
    long leaseId = leaseClient.grant(10).get().getID();
    ByteSequence firstProposal = ByteSequence.from("proposal1", StandardCharsets.UTF_8);
    CampaignResponse campaignResponse1 = electionClient.campaign(electionName, leaseId, firstProposal).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
    ByteSequence secondProposal = ByteSequence.from("proposal2", StandardCharsets.UTF_8);
    CampaignResponse campaignResponse2 = electionClient.campaign(electionName, leaseId, secondProposal).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
    // check that for sure we are the leader
    LeaderResponse leaderResponse = electionClient.leader(electionName).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
    assertThat(leaderResponse.getKv().getKey()).isEqualTo(campaignResponse1.getLeader().getKey());
    assertThat(campaignResponse1.getLeader().getKey()).isEqualTo(campaignResponse2.getLeader().getKey());
    assertThat(campaignResponse1.getLeader().getRevision()).isEqualTo(campaignResponse2.getLeader().getRevision());
    // latest proposal should be persisted
    GetOption getOption = GetOption.newBuilder().isPrefix(true).build();
    List<KeyValue> keys = kvClient.get(electionName, getOption).get().getKvs();
    assertThat(keys.size()).isEqualTo(1);
    assertThat(keys.get(0).getValue()).isEqualTo(secondProposal);
    electionClient.resign(campaignResponse1.getLeader()).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
    leaseClient.revoke(leaseId).get();
}
Also used : KeyValue(io.etcd.jetcd.KeyValue) CampaignResponse(io.etcd.jetcd.election.CampaignResponse) GetOption(io.etcd.jetcd.options.GetOption) LeaderResponse(io.etcd.jetcd.election.LeaderResponse) ByteSequence(io.etcd.jetcd.ByteSequence) TestUtil.randomByteSequence(io.etcd.jetcd.impl.TestUtil.randomByteSequence) Test(org.junit.jupiter.api.Test)

Example 2 with CampaignResponse

use of io.etcd.jetcd.election.CampaignResponse in project jetcd by coreos.

the class ElectionTest method testIsolatedElection.

@Test
public void testIsolatedElection() throws Exception {
    ByteSequence electionName = ByteSequence.from(randomString(), StandardCharsets.UTF_8);
    // register lease
    long leaseId = leaseClient.grant(10).get().getID();
    // start new campaign
    ByteSequence firstProposal = ByteSequence.from("proposal1", StandardCharsets.UTF_8);
    CampaignResponse campaignResponse = electionClient.campaign(electionName, leaseId, firstProposal).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
    assertThat(campaignResponse.getLeader()).isNotNull();
    assertThat(campaignResponse.getLeader().getLease()).isEqualTo(leaseId);
    assertThat(campaignResponse.getLeader().getName()).isEqualTo(electionName);
    // election is backed by standard key in etcd. let us examine it
    GetOption getOption = GetOption.newBuilder().isPrefix(true).build();
    List<KeyValue> keys = kvClient.get(electionName, getOption).get().getKvs();
    assertThat(keys.size()).isEqualTo(1);
    assertThat(keys.get(0).getKey().toString()).isEqualTo(campaignResponse.getLeader().getKey().toString());
    assertThat(keys.get(0).getValue()).isEqualTo(firstProposal);
    // check that we really are the leader (just to test API)
    LeaderResponse leaderResponse = electionClient.leader(electionName).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
    assertThat(leaderResponse.getKv().getKey()).isEqualTo(campaignResponse.getLeader().getKey());
    assertThat(leaderResponse.getKv().getValue()).isEqualTo(firstProposal);
    assertThat(leaderResponse.getKv().getLease()).isEqualTo(leaseId);
    assertThat(leaderResponse.getKv().getCreateRevision()).isEqualTo(campaignResponse.getLeader().getRevision());
    // as a leader change your proposal
    ByteSequence secondProposal = ByteSequence.from("proposal2", StandardCharsets.UTF_8);
    electionClient.proclaim(campaignResponse.getLeader(), secondProposal).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
    keys = kvClient.get(electionName, getOption).get().getKvs();
    assertThat(keys.size()).isEqualTo(1);
    assertThat(keys.get(0).getValue()).isEqualTo(secondProposal);
    // finally resign
    electionClient.resign(campaignResponse.getLeader()).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
    keys = kvClient.get(electionName, getOption).get().getKvs();
    assertThat(keys).isEmpty();
    leaseClient.revoke(leaseId).get();
}
Also used : KeyValue(io.etcd.jetcd.KeyValue) CampaignResponse(io.etcd.jetcd.election.CampaignResponse) GetOption(io.etcd.jetcd.options.GetOption) LeaderResponse(io.etcd.jetcd.election.LeaderResponse) ByteSequence(io.etcd.jetcd.ByteSequence) TestUtil.randomByteSequence(io.etcd.jetcd.impl.TestUtil.randomByteSequence) Test(org.junit.jupiter.api.Test)

Example 3 with CampaignResponse

use of io.etcd.jetcd.election.CampaignResponse in project jetcd by coreos.

the class ElectionImpl method campaign.

@Override
public CompletableFuture<CampaignResponse> campaign(ByteSequence electionName, long leaseId, ByteSequence proposal) {
    checkNotNull(electionName, "election name should not be null");
    checkNotNull(proposal, "proposal should not be null");
    CampaignRequest request = CampaignRequest.newBuilder().setName(Util.prefixNamespace(electionName, namespace)).setValue(ByteString.copyFrom(proposal.getBytes())).setLease(leaseId).build();
    return completable(stub.campaign(request), CampaignResponse::new, this::convertException);
}
Also used : CampaignResponse(io.etcd.jetcd.election.CampaignResponse) CampaignRequest(io.etcd.jetcd.api.CampaignRequest)

Example 4 with CampaignResponse

use of io.etcd.jetcd.election.CampaignResponse in project jetcd by coreos.

the class ElectionTest method testObserveElections.

@Test
public void testObserveElections() throws Exception {
    int electionCount = 3;
    final AtomicInteger electionsSeen = new AtomicInteger(0);
    ByteSequence electionName = ByteSequence.from(randomString(), StandardCharsets.UTF_8);
    electionClient.observe(electionName, new Election.Listener() {

        @Override
        public void onNext(LeaderResponse response) {
            electionsSeen.incrementAndGet();
        }

        @Override
        public void onError(Throwable error) {
        }

        @Override
        public void onCompleted() {
        }
    });
    long leaseId = leaseClient.grant(10).get().getID();
    for (int i = 0; i < electionCount; ++i) {
        ByteSequence proposal = ByteSequence.from(randomString(), StandardCharsets.UTF_8);
        CampaignResponse campaignResponse = electionClient.campaign(electionName, leaseId, proposal).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
        Thread.sleep(100);
        electionClient.resign(campaignResponse.getLeader()).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
    }
    TestUtil.waitForCondition(() -> electionsSeen.get() == electionCount, OPERATION_TIMEOUT * 1000, "Observer did not receive expected notifications, got: " + electionsSeen.get());
    leaseClient.revoke(leaseId).get();
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CampaignResponse(io.etcd.jetcd.election.CampaignResponse) LeaderResponse(io.etcd.jetcd.election.LeaderResponse) Election(io.etcd.jetcd.Election) ByteSequence(io.etcd.jetcd.ByteSequence) TestUtil.randomByteSequence(io.etcd.jetcd.impl.TestUtil.randomByteSequence) Test(org.junit.jupiter.api.Test)

Example 5 with CampaignResponse

use of io.etcd.jetcd.election.CampaignResponse in project jetcd by coreos.

the class ElectionTest method testSynchronizationBarrier.

@Test
public void testSynchronizationBarrier() throws Exception {
    final int threadCount = 5;
    final Random random = new Random();
    ByteSequence electionName = ByteSequence.from(randomString(), StandardCharsets.UTF_8);
    final AtomicInteger sharedVariable = new AtomicInteger(0);
    // create separate clients so they will compete for access to shared resource
    List<Client> clients = new ArrayList<>(threadCount);
    List<Long> leases = new ArrayList<>(threadCount);
    for (int i = 0; i < threadCount; ++i) {
        Client client = TestUtil.client(cluster).build();
        long leaseId = client.getLeaseClient().grant(100).get().getID();
        clients.add(client);
        leases.add(leaseId);
    }
    ExecutorService executor = Executors.newFixedThreadPool(threadCount);
    List<Future<?>> futures = new ArrayList<>(threadCount);
    for (int i = 0; i < threadCount; ++i) {
        final int id = i;
        final ByteSequence proposal = ByteSequence.from(Integer.toString(id), StandardCharsets.UTF_8);
        futures.add(executor.submit(() -> {
            try {
                Election electionClient = clients.get(id).getElectionClient();
                CampaignResponse campaignResponse = electionClient.campaign(electionName, leases.get(id), proposal).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
                int localCopy = sharedVariable.get();
                Thread.sleep(200 + random.nextInt(300));
                sharedVariable.set(localCopy + 1);
                electionClient.resign(campaignResponse.getLeader()).get(OPERATION_TIMEOUT, TimeUnit.SECONDS);
            } catch (Exception e) {
                fail("Unexpected error in thread {}: {}", id, e);
            }
        }));
    }
    executor.shutdown();
    executor.awaitTermination(threadCount * OPERATION_TIMEOUT, TimeUnit.SECONDS);
    futures.forEach(f -> assertThat(f).isDone());
    assertThat(sharedVariable.get()).isEqualTo(threadCount);
    GetOption getOption = GetOption.newBuilder().isPrefix(true).build();
    assertThat(kvClient.get(electionName, getOption).get().getCount()).isEqualTo(0L);
    for (int i = 0; i < threadCount; ++i) {
        clients.get(i).getLeaseClient().revoke(leases.get(i)).get();
        clients.get(i).close();
    }
}
Also used : CampaignResponse(io.etcd.jetcd.election.CampaignResponse) ArrayList(java.util.ArrayList) Election(io.etcd.jetcd.Election) NoLeaderException(io.etcd.jetcd.election.NoLeaderException) NotLeaderException(io.etcd.jetcd.election.NotLeaderException) ExecutionException(java.util.concurrent.ExecutionException) Random(java.util.Random) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutorService(java.util.concurrent.ExecutorService) GetOption(io.etcd.jetcd.options.GetOption) Future(java.util.concurrent.Future) Client(io.etcd.jetcd.Client) ByteSequence(io.etcd.jetcd.ByteSequence) TestUtil.randomByteSequence(io.etcd.jetcd.impl.TestUtil.randomByteSequence) Test(org.junit.jupiter.api.Test)

Aggregations

CampaignResponse (io.etcd.jetcd.election.CampaignResponse)5 ByteSequence (io.etcd.jetcd.ByteSequence)4 TestUtil.randomByteSequence (io.etcd.jetcd.impl.TestUtil.randomByteSequence)4 Test (org.junit.jupiter.api.Test)4 LeaderResponse (io.etcd.jetcd.election.LeaderResponse)3 GetOption (io.etcd.jetcd.options.GetOption)3 Election (io.etcd.jetcd.Election)2 KeyValue (io.etcd.jetcd.KeyValue)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 Client (io.etcd.jetcd.Client)1 CampaignRequest (io.etcd.jetcd.api.CampaignRequest)1 NoLeaderException (io.etcd.jetcd.election.NoLeaderException)1 NotLeaderException (io.etcd.jetcd.election.NotLeaderException)1 ArrayList (java.util.ArrayList)1 Random (java.util.Random)1 ExecutionException (java.util.concurrent.ExecutionException)1 ExecutorService (java.util.concurrent.ExecutorService)1 Future (java.util.concurrent.Future)1