Skip to content
This repository was archived by the owner on Jan 12, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 4 additions & 58 deletions barge-core/src/main/java/org/robotninjas/barge/ClusterConfig.java
Original file line number Diff line number Diff line change
@@ -1,65 +1,11 @@
package org.robotninjas.barge;

import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
public interface ClusterConfig {

import static com.google.common.collect.Iterables.unmodifiableIterable;
import static com.google.common.collect.Lists.newArrayList;
Replica local();

public class ClusterConfig {
Iterable<Replica> remote();

private final Replica local;
private final Iterable<Replica> remote;
Replica getReplica(String info);

ClusterConfig(Replica local, Iterable<Replica> remote) {
this.local = local;
this.remote = remote;
}

public static ClusterConfig from(Replica local, Replica... remote) {
return new ClusterConfig(local, newArrayList(remote));
}

public static ClusterConfig from(Replica local, Iterable<Replica> remote) {
return new ClusterConfig(local, remote);
}

public Replica local() {
return local;
}

public Iterable<Replica> remote() {
return unmodifiableIterable(remote);
}

@Override
public int hashCode() {
Iterable<Replica> all = Iterables.concat(newArrayList(local), remote);
return Objects.hashCode(Iterables.toArray(all, Replica.class));
}

@Override
public boolean equals(Object o) {

if (o == this) {
return true;
}

if (!(o instanceof ClusterConfig)) {
return false;
}

ClusterConfig other = (ClusterConfig) o;
return local.equals(other.local) &&
Iterables.elementsEqual(remote, other.remote);

}

@Override
public String toString() {
return Objects.toStringHelper(this)
.add("local", local)
.add("remote", remote)
.toString();
}
}
82 changes: 1 addition & 81 deletions barge-core/src/main/java/org/robotninjas/barge/Replica.java
Original file line number Diff line number Diff line change
@@ -1,86 +1,6 @@
/**
* Copyright 2013 David Rusek <dave dot rusek at gmail dot com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.robotninjas.barge;

import com.google.common.base.Objects;
import com.google.common.base.Throwables;
import com.google.common.net.HostAndPort;

import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;

import static com.google.common.base.Preconditions.checkNotNull;

@Immutable
@ThreadSafe
public class Replica {

private final InetSocketAddress address;

Replica(@Nonnull InetSocketAddress address) {
this.address = checkNotNull(address);
}

@Nonnull
public static Replica fromString(@Nonnull String info) {
try {
checkNotNull(info);
HostAndPort hostAndPort = HostAndPort.fromString(info);
InetAddress addr = InetAddress.getByName(hostAndPort.getHostText());
InetSocketAddress saddr = new InetSocketAddress(addr, hostAndPort.getPort());
return new Replica(saddr);
} catch (UnknownHostException e) {
throw Throwables.propagate(e);
}
}

public SocketAddress address() {
return address;
}

@Override
public int hashCode() {
return Objects.hashCode(address());
}

@Override
public boolean equals(Object o) {

if (o == this) {
return true;
}

if (o instanceof Replica) {
Replica other = (Replica) o;
return Objects.equal(address(), other.address());
}

return false;
public interface Replica {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment than for ClusterConfig: There's no need to declare hashcode/equals/toString methods here...


}

@Nonnull
@Override
public String toString() {
return address.getAddress().getHostName() + ":" + address.getPort();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.common.collect.Maps;
import journal.io.api.Journal;
import journal.io.api.Location;
import org.robotninjas.barge.ClusterConfig;
import org.robotninjas.barge.Replica;
import org.robotninjas.barge.proto.LogProto;
import org.robotninjas.barge.proto.RaftEntry;
Expand All @@ -21,10 +22,12 @@
class RaftJournal {

private final Journal journal;
private final ClusterConfig config;
private final TreeMap<Long, Location> entryIndex = Maps.newTreeMap();

public RaftJournal(Journal journal) {
public RaftJournal(Journal journal, ClusterConfig config) {
this.journal = journal;
this.config = config;
}

public void init() {
Expand Down Expand Up @@ -200,7 +203,7 @@ public void replay(Visitor visitor) {
LogProto.Vote vote = entry.getVote();
String votedfor = vote.getVotedFor();
Replica replica = votedfor == null
? null : Replica.fromString(votedfor);
? null : config.getReplica(votedfor);
visitor.vote(Optional.fromNullable(replica));
}

Expand Down
11 changes: 10 additions & 1 deletion barge-core/src/main/java/org/robotninjas/barge/log/RaftLog.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public class RaftLog {
@Inject
RaftLog(@Nonnull Journal journal, @Nonnull ClusterConfig config,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we only use journal as an argument to creating RaftJournal, I would rather pass a RaftJournal here if possible.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, however, it's not necessarily as easy as that, the interaction between RaftJournal and RaftLog is (too) complex. I think we should address this separately.

@Nonnull StateMachineProxy stateMachine) {
this.journal = new RaftJournal(checkNotNull(journal));
this.journal = new RaftJournal(checkNotNull(journal), checkNotNull(config));
this.config = checkNotNull(config);
this.stateMachine = checkNotNull(stateMachine);
}
Expand Down Expand Up @@ -204,6 +204,10 @@ public long commitIndex() {
return commitIndex;
}

public ClusterConfig config() {
return config;
}

public void commitIndex(long index) {
commitIndex = index;
journal.appendCommit(index);
Expand Down Expand Up @@ -243,6 +247,11 @@ public List<Replica> members() {
return unmodifiableList(newArrayList(config.remote()));
}

@Nonnull
public Replica getReplica(String info) {
return config.getReplica(info);
}

@Override
public String toString() {
return Objects.toStringHelper(getClass())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public StateType type() {
boolean shouldVoteFor(@Nonnull RaftLog log, @Nonnull RequestVote request) {

Optional<Replica> lastVotedFor = log.lastVotedFor();
Replica candidate = Replica.fromString(request.getCandidateId());
Replica candidate = log.getReplica(request.getCandidateId());

boolean hasAtLeastTerm = request.getLastLogTerm() >= log.lastLogTerm();
boolean hasAtLeastIndex = request.getLastLogIndex() >= log.lastLogIndex();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
import static com.google.common.util.concurrent.Futures.addCallback;
import static org.robotninjas.barge.proto.RaftProto.*;
import static org.robotninjas.barge.state.MajorityCollector.majorityResponse;
import static org.robotninjas.barge.state.RaftPredicates.voteGranted;
import static org.robotninjas.barge.state.Raft.StateType.*;
import static org.robotninjas.barge.state.RaftPredicates.voteGranted;

@NotThreadSafe
class Candidate extends BaseState {
Expand Down Expand Up @@ -122,7 +122,7 @@ public RequestVoteResponse requestVote(@Nonnull RaftStateContext ctx, @Nonnull R

LOGGER.debug("RequestVote received for term {}", request.getTerm());

Replica candidate = Replica.fromString(request.getCandidateId());
Replica candidate = log.getReplica(request.getCandidateId());

boolean voteGranted = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@
import com.google.common.base.Optional;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Inject;
import org.robotninjas.barge.NoLeaderException;
import org.robotninjas.barge.NotLeaderException;
import org.robotninjas.barge.RaftException;
import org.robotninjas.barge.Replica;
import org.robotninjas.barge.*;
import org.robotninjas.barge.log.RaftLog;
import org.robotninjas.barge.rpc.RaftScheduler;
import org.slf4j.Logger;
Expand Down Expand Up @@ -86,7 +83,7 @@ public RequestVoteResponse requestVote(@Nonnull RaftStateContext ctx, @Nonnull R
log.currentTerm(request.getTerm());
}

Replica candidate = Replica.fromString(request.getCandidateId());
Replica candidate = log.getReplica(request.getCandidateId());
voteGranted = shouldVoteFor(log, request);

if (voteGranted) {
Expand Down Expand Up @@ -117,7 +114,7 @@ public AppendEntriesResponse appendEntries(@Nonnull RaftStateContext ctx, @Nonnu
log.currentTerm(request.getTerm());
}

leader = Optional.of(Replica.fromString(request.getLeaderId()));
leader = Optional.of(log.getReplica(request.getLeaderId()));
timeoutTask.reset();
success = log.append(request);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public RequestVoteResponse requestVote(@Nonnull RaftStateContext ctx, @Nonnull R
log.currentTerm(request.getTerm());
stepDown(ctx);

Replica candidate = Replica.fromString(request.getCandidateId());
Replica candidate = log.getReplica(request.getCandidateId());
voteGranted = shouldVoteFor(log, request);

if (voteGranted) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package org.robotninjas.barge;

import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;

import javax.annotation.Nullable;

public class ClusterConfigStub implements ClusterConfig {

private final Replica local = new ReplicaStub("local");
private final Iterable<Replica> remote;

private ClusterConfigStub(Iterable<Replica> replicas) {
remote = Lists.newArrayList(replicas);
}

public static ClusterConfigStub getStub(String... ids) {
return new ClusterConfigStub(FluentIterable.from(Lists.newArrayList(ids))
.transform(new Function<String, Replica>() {
public Replica apply(@Nullable String input) {
return new ReplicaStub(input);
}
}));
}

@Override
public Replica local() {
return local;
}

@Override
public Iterable<Replica> remote() {
return remote;
}

@Override
public Replica getReplica(String info) {
return new ReplicaStub(info);
}

private static class ReplicaStub implements Replica {

private final String info;

private ReplicaStub(String info) {
this.info = info;
}

@Override
public int hashCode() {
return Objects.hashCode(info);
}

@Override
public boolean equals(Object o) {

if (o == this) {
return true;
}

if (!(o instanceof ReplicaStub)) {
return false;
}

ReplicaStub stub = (ReplicaStub) o;
return Objects.equal(stub.info, info);

}

@Override
public String toString() {
return info;
}
}

}
Loading