Skip to content

Commit

Permalink
Fixed concurrency issue with FileBasedStateRepository (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
chkal committed Mar 5, 2013
1 parent 4c92dde commit f2c58f9
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public FileBasedStateRepository(File file) {
log.debug(this.getClass().getSimpleName() + " initialized with: " + file.getAbsolutePath());
}

public FeatureState getFeatureState(Feature feature) {
public synchronized FeatureState getFeatureState(Feature feature) {

// update file if changed
fileContent.reloadIfUpdated();
Expand Down Expand Up @@ -106,7 +106,7 @@ public FeatureState getFeatureState(Feature feature) {

}

public void setFeatureState(FeatureState featureState) {
public synchronized void setFeatureState(FeatureState featureState) {

// update file if changed
fileContent.reloadIfUpdated();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package org.togglz.core.repository.file;

import static org.fest.assertions.api.Assertions.assertThat;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.fest.assertions.data.MapEntry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.togglz.core.Feature;
import org.togglz.core.repository.FeatureState;

public class FileBasedStateRepositoryConcurrencyTest {

private File testFile;

private ExecutorService executor;

private final int NUMBER_OF_FEATURES = 100;

@Before
public void before() throws IOException {
testFile = File.createTempFile(this.getClass().getSimpleName(), "test");
executor = Executors.newFixedThreadPool(NUMBER_OF_FEATURES);
}

@Test
public void shouldWorkUnderHeavyLoad() throws Exception {

final FileBasedStateRepository repo = new FileBasedStateRepository(testFile);

// Step 1: concurrently write a large number of state
for (int i = 0; i < NUMBER_OF_FEATURES; i++) {

// build up a feature state containing some data
String name = "FEATURE" + i;
Feature feature = new TestFeature(name);
final FeatureState state = new FeatureState(feature)
.setStrategyId("strategy-for-" + name)
.setParameter("param-of-" + name, "some-value-of-" + name);

// queue a thread writing that state
executor.submit(new Runnable() {
@Override
public void run() {
repo.setFeatureState(state);
}
});

}

// Step 2: Wait for all threads to finish
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);

// Step 3: Verify the state written to the repository
for (int i = 0; i < NUMBER_OF_FEATURES; i++) {

// read the state
String name = "FEATURE" + i;
TestFeature feature = new TestFeature(name);
FeatureState state = repo.getFeatureState(feature);

// verify that the state is as expected
assertThat(state).isNotNull();
assertThat(state.getStrategyId()).isEqualTo("strategy-for-" + name);
assertThat(state.getParameterMap())
.hasSize(1)
.contains(MapEntry.entry("param-of-" + name, "some-value-of-" + name));

}

}

@After
public void after() throws Exception {
executor.shutdownNow();
testFile.delete();
}

private class TestFeature implements Feature {

private final String name;

private TestFeature(String name) {
this.name = name;
}

@Override
public String name() {
return name;
}

@Override
public boolean isActive() {
throw new UnsupportedOperationException();
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
import org.togglz.core.logging.LogFactory;
import org.togglz.core.util.IOUtils;

/**
* Please note that this class is NOT thread-safe.
*/
class ReloadablePropertiesFile {

private final Log log = LogFactory.getLog(ReloadablePropertiesFile.class);
Expand Down

1 comment on commit f2c58f9

@buildhive
Copy link

Choose a reason for hiding this comment

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

Christian Kaltepoth » togglz #45 FAILURE
Looks like this commit caused a build failure
(what's this?)

Please sign in to comment.