Skip to content

Commit

Permalink
Refactor Raft implementation as a standalone interface dependent only…
Browse files Browse the repository at this point in the history
… on I/O and Cluster.
  • Loading branch information
kuujo committed May 23, 2015
1 parent af6198e commit 0bc54d3
Show file tree
Hide file tree
Showing 91 changed files with 1,465 additions and 1,016 deletions.
2 changes: 1 addition & 1 deletion raft/pom.xml
Expand Up @@ -29,7 +29,7 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>net.kuujo.copycat</groupId> <groupId>net.kuujo.copycat</groupId>
<artifactId>copycat-core</artifactId> <artifactId>copycat-cluster</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
Expand Down
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package net.kuujo.copycat.protocol.raft; package net.kuujo.copycat.raft;


/** /**
* Application exception. * Application exception.
Expand Down
43 changes: 43 additions & 0 deletions raft/src/main/java/net/kuujo/copycat/raft/Apply.java
@@ -0,0 +1,43 @@
/*
* Copyright 2015 the original author or authors.
*
* 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 net.kuujo.copycat.raft;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Annotation for applying commands to the state machine.
*
* @author <a href="http://github.com/kuujo">Jordan Halterman</a>
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Apply {

/**
* The command types to apply.
*/
Class<? extends Command>[] value();

/**
* Indicates that all commands should be applied.
*/
static class All implements Command {
}

}
Expand Up @@ -13,26 +13,25 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package net.kuujo.copycat.protocol.raft; package net.kuujo.copycat.raft;


/** /**
* Delete exception. * Command operation.
* *
* @author <a href="http://github.com/kuujo">Jordan Halterman</a> * @author <a href="http://github.com/kuujo">Jordan Halterman</a>
*/ */
public class DeleteException extends RaftException { public interface Command<T> extends Operation<T> {
private static final RaftError.Type TYPE = RaftError.Type.DELETE_ERROR;


public DeleteException(String message, Object... args) { /**
super(TYPE, message, args); * Command builder.
} */

static class Builder<T extends Builder<T, U>, U extends Command<?>> extends Operation.Builder<U> {
public DeleteException(Throwable cause, String message, Object... args) { protected final U command;
super(TYPE, cause, message, args);
}


public DeleteException(Throwable cause) { public Builder(U command) {
super(TYPE, cause); super(command);
this.command = command;
}
} }


} }
71 changes: 71 additions & 0 deletions raft/src/main/java/net/kuujo/copycat/raft/Commit.java
@@ -0,0 +1,71 @@
/*
* Copyright 2015 the original author or authors.
*
* 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 net.kuujo.copycat.raft;

/**
* Protocol commit.
*
* @author <a href="http://github.com/kuujo">Jordan Halterman</a>
*/
public class Commit<T extends Operation> {
private final long index;
private final long timestamp;
private final T operation;

public Commit(long index, long timestamp, T operation) {
this.index = index;
this.timestamp = timestamp;
this.operation = operation;
}

/**
* Returns the commit index.
*
* @return The commit index.
*/
public long index() {
return index;
}

/**
* Returns the commit timestamp.
*
* @return the commit timestamp.
*/
public long timestamp() {
return timestamp;
}

/**
* Returns the commit type.
*
* @return The commit type.
*/
@SuppressWarnings("unchecked")
public Class<T> type() {
return (Class<T>) operation.getClass();
}

/**
* Returns the operation.
*
* @return The operation.
*/
public T operation() {
return operation;
}

}
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package net.kuujo.copycat.protocol.raft; package net.kuujo.copycat.raft;


/** /**
* Illegal member state exception. * Illegal member state exception.
Expand Down
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package net.kuujo.copycat.protocol.raft; package net.kuujo.copycat.raft;


/** /**
* Not leader exception. * Not leader exception.
Expand Down
69 changes: 69 additions & 0 deletions raft/src/main/java/net/kuujo/copycat/raft/Operation.java
@@ -0,0 +1,69 @@
/*
* Copyright 2015 the original author or authors.
*
* 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 net.kuujo.copycat.raft;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
* State machine operation.
*
* @author <a href="http://github.com/kuujo">Jordan Halterman</a>
*/
public interface Operation<T> extends Serializable {

/**
* Returns a cached instance of the given builder.
*
* @param type The builder type.
* @return The builder.
*/
@SuppressWarnings("unchecked")
static <T extends Builder<U>, U extends Operation<?>> T builder(Class<T> type) {
return (T) Builder.BUILDERS.get().computeIfAbsent(type, t -> {
try {
return type.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new IllegalArgumentException("failed to instantiate builder: " + type, e);
}
});
}

/**
* Operation builder.
*/
static abstract class Builder<T extends Operation<?>> implements net.kuujo.copycat.Builder<T> {
private static final ThreadLocal<Map<Class<? extends Builder>, Builder>> BUILDERS = new ThreadLocal<Map<Class<? extends Builder>, Builder>>() {
@Override
protected Map<Class<? extends Builder>, Builder> initialValue() {
return new HashMap<>();
}
};

private final T operation;

protected Builder(T operation) {
this.operation = operation;
}

@Override
public T build() {
return operation;
}
}

}
66 changes: 66 additions & 0 deletions raft/src/main/java/net/kuujo/copycat/raft/Query.java
@@ -0,0 +1,66 @@
/*
* Copyright 2015 the original author or authors.
*
* 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 net.kuujo.copycat.raft;

/**
* Query operation.
*
* @author <a href="http://github.com/kuujo">Jordan Halterman</a>
*/
public interface Query<T> extends Operation<T> {

/**
* Returns the query consistency.
*
* @return The query consistency.
*/
Consistency consistency();

/**
* Query consistency.
*/
static enum Consistency {

/**
* Provides serializable consistency.
*/
SERIALIZABLE,

/**
* Provides linearizable consistency based on a leader lease.
*/
LINEARIZABLE_LEASE,

/**
* Provides strict linearizable consistency.
*/
LINEARIZABLE_STRICT

}

/**
* Query builder.
*/
static class Builder<T extends Builder<T, U>, U extends Query<?>> extends Operation.Builder<U> {
protected final U query;

public Builder(U query) {
super(query);
this.query = query;
}
}

}

0 comments on commit 0bc54d3

Please sign in to comment.