Skip to content

Commit

Permalink
Introduce a one-and-only dependency resolver strategy
Browse files Browse the repository at this point in the history
For least element of surprise coding.
Used for defensive coding in RecoverConsensusLogIndex.
  • Loading branch information
martinfurmanski committed Mar 8, 2018
1 parent e66ac59 commit 848a256
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 10 deletions.
Expand Up @@ -22,6 +22,8 @@
import java.util.Iterator;
import java.util.function.Supplier;

import static org.neo4j.graphdb.DependencyResolver.SelectionStrategy.FIRST;

/**
* Find a dependency given a type. This can be the exact type or a super type of
* the actual dependency.
Expand Down Expand Up @@ -73,15 +75,8 @@ interface SelectionStrategy
* @throws IllegalArgumentException if no suitable candidate was found.
*/
<T> T select( Class<T> type, Iterable<? extends T> candidates ) throws IllegalArgumentException;
}

/**
* Adapter for {@link DependencyResolver} which will select the first available candidate by default
* for {@link #resolveDependency(Class)}.
*/
abstract class Adapter implements DependencyResolver
{
private static final SelectionStrategy FIRST = new SelectionStrategy()
SelectionStrategy FIRST = new SelectionStrategy()
{
@Override
public <T> T select( Class<T> type, Iterable<? extends T> candidates ) throws IllegalArgumentException
Expand All @@ -95,6 +90,40 @@ public <T> T select( Class<T> type, Iterable<? extends T> candidates ) throws Il
}
};

/**
* Returns the one and only dependency, or throws.
*/
SelectionStrategy ONLY = new SelectionStrategy()
{
@Override
public <T> T select( Class<T> type, Iterable<? extends T> candidates ) throws IllegalArgumentException
{
Iterator<? extends T> iterator = candidates.iterator();
if ( !iterator.hasNext() )
{
throw new IllegalArgumentException( "Could not resolve dependency of type:" + type.getName() );
}

T only = iterator.next();

if ( iterator.hasNext() )
{
throw new IllegalArgumentException( "Multiple dependencies of type:" + type.getName() );
}
else
{
return only;
}
}
};
}

/**
* Adapter for {@link DependencyResolver} which will select the first available candidate by default
* for {@link #resolveDependency(Class)}.
*/
abstract class Adapter implements DependencyResolver
{
@Override
public <T> T resolveDependency( Class<T> type ) throws IllegalArgumentException
{
Expand Down
Expand Up @@ -24,6 +24,8 @@
import org.neo4j.kernel.impl.util.Dependencies;
import org.neo4j.logging.LogProvider;

import static org.neo4j.graphdb.DependencyResolver.SelectionStrategy.ONLY;

/**
* Retrieves last raft log index that was appended to the transaction log, so that raft log replay can recover while
* preserving idempotency (avoid appending the same transaction twice).
Expand All @@ -41,8 +43,8 @@ public RecoverConsensusLogIndex( Dependencies dependencies, LogProvider logProvi

public long findLastAppliedIndex()
{
TransactionIdStore transactionIdStore = dependencies.resolveDependency( TransactionIdStore.class );
LogicalTransactionStore transactionStore = dependencies.resolveDependency( LogicalTransactionStore.class );
TransactionIdStore transactionIdStore = dependencies.resolveDependency( TransactionIdStore.class, ONLY );
LogicalTransactionStore transactionStore = dependencies.resolveDependency( LogicalTransactionStore.class, ONLY );

return new LastCommittedIndexFinder( transactionIdStore, transactionStore, logProvider )
.getLastCommittedIndex();
Expand Down

0 comments on commit 848a256

Please sign in to comment.