Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.ServiceLoader;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

public class EdgeFeatureHubConfig implements FeatureHubConfig {
Expand Down Expand Up @@ -81,6 +82,16 @@ public void init() {
}
}

@Override
public void init(long timeout, TimeUnit unit) {
try {
final Future<ClientContext> futureContext = newContext().build();
futureContext.get(timeout, unit);
} catch (Exception e) {
log.error("Failed to initialize FeatureHub client", e);
}
}

@Override
public boolean isServerEvaluation() {
return serverEvaluation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

public interface FeatureHubConfig {
Expand All @@ -21,6 +22,13 @@ public interface FeatureHubConfig {
*/
void init();

/**
* If you are using a client evaluated feature context, this will initialise the service and block until
* the provided timeout or until you have received your first set of features. Server Evaluated contexts
* should not use it because it needs to re-request data from the server each time you change your context.
*/
void init(long timeout, TimeUnit unit);

/**
* The API Key indicates this is going to be server based evaluation
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,41 @@ class EdgeFeatureHubConfigSpec extends Specification {
1 * mockRequest.get() >> Readyness.Ready
0 * _
}

def "init completes successfully if future resolves within the given time"() {
given: "A client eval feature config"
def config = new EdgeFeatureHubConfig("http://localhost/", "123*abc")
and: "A mock future that completes successfully"
def futureContext = Mock(Future<ClientContext>)
def mockContext = Mock(ClientContext)
and: "I mock the context and future"
def clientContext = Mock(ClientContext)
clientContext.build() >> futureContext
config = Spy(config) {
newContext() >> clientContext
}
when: "init is called with a reasonable timeout"
config.init(100, TimeUnit.MILLISECONDS)
then: "The get method on the future should be called with timeout"
1 * futureContext.get(100, TimeUnit.MILLISECONDS) >> mockContext
0 * _
}

def "init should timeout if future does not complete within the given time"() {
given: "A client eval feature config"
def config = new EdgeFeatureHubConfig("http://localhost/", "123*abc")
and: "A mock future that does not complete in time"
def futureContext = Mock(Future<ClientContext>)
and: "I mock the context and future"
def clientContext = Mock(ClientContext)
clientContext.build() >> futureContext
config = Spy(config) {
newContext() >> clientContext
}
when: "init is called with a very short timeout"
config.init(1, TimeUnit.MILLISECONDS)
then: "The get method on the future should be called with timeout"
1 * futureContext.get(1, TimeUnit.MILLISECONDS) >> { throw new java.util.concurrent.TimeoutException() }
0 * _
}
}