Skip to content

Conversation

@ArbaazKhan1
Copy link
Contributor

closes issue #5828

Moved Fate threads outside of the constructor and into a new start() method. Created a new FateConfig class to handle instantiations of variables being pass into the constructor and updated Fate calls to handle the new start method.

Copy link
Member

@kevinrr888 kevinrr888 left a comment

Choose a reason for hiding this comment

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

Can you run
mvn clean verify -Dspotbugs.skip -Dtest=skip -Dit.test=org.apache.accumulo.test.fate.**
to verify that all fate tests still pass?

@kevinrr888 kevinrr888 added this to the 4.0.0 milestone Oct 7, 2025
@ArbaazKhan1
Copy link
Contributor Author

I've run the command and it says that all test pass

Copy link
Member

@kevinrr888 kevinrr888 left a comment

Choose a reason for hiding this comment

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

Looks good, just some minor changes


public void start() {
log.info("Start {} FATE", store.type());
keepRunning.set(true);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
keepRunning.set(true);

Already set to true at initialization

}
}

private record FateConfiguration<T>(T environment, boolean runDeadResCleaner,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
private record FateConfiguration<T>(T environment, boolean runDeadResCleaner,
private record FateThreadsConfiguration<T>(T environment, boolean runDeadResCleaner,

A bit more descriptive

private final AtomicInteger needMoreThreadsWarnCount = new AtomicInteger(0);
private final ExecutorService deadResCleanerExecutor;
private ExecutorService deadResCleanerExecutor;
private final FateConfiguration<T> fateConfig;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
private final FateConfiguration<T> fateConfig;
private final FateConfiguration<T> fateThreadsConfig;

along with other suggestion

Comment on lines 39 to 44
public FastFate(T environment, FateStore<T> store, boolean runDeadResCleaner,
Function<Repo<T>,String> toLogStrFunc, AccumuloConfiguration conf) {
super(environment, store, runDeadResCleaner, toLogStrFunc, conf,
new ScheduledThreadPoolExecutor(2));
start();
}
Copy link
Member

Choose a reason for hiding this comment

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

For consistency, should call start after the FastFate is created:

var fastFate = new FastFate(...);
fastFate.start();

Is a bit more confusing having some tests:

var fate = new Fate(...);
fate.start();

and others:

var fastFate = new FastFate(...);

Comment on lines 39 to 47
public FlakyFate(T environment, FateStore<T> store, Function<Repo<T>,String> toLogStrFunc,
AccumuloConfiguration conf) {
super(environment, store, false, toLogStrFunc, conf, new ScheduledThreadPoolExecutor(2));
for (var poolConfig : getPoolConfigurations(conf, getStore().type()).entrySet()) {
fateExecutors.add(new FlakyFateExecutor<>(this, environment, poolConfig.getKey(),
poolConfig.getValue().getValue(), poolConfig.getValue().getKey()));
}
start();
}
Copy link
Member

Choose a reason for hiding this comment

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

same thing here

Comment on lines 54 to 62
public SlowFateSplit(T environment, FateStore<T> store, Function<Repo<T>,String> toLogStrFunc,
AccumuloConfiguration conf) {
super(environment, store, false, toLogStrFunc, conf, new ScheduledThreadPoolExecutor(2));
for (var poolConfig : getPoolConfigurations(conf, getStore().type()).entrySet()) {
fateExecutors.add(new SlowFateSplitExecutor(this, environment, poolConfig.getKey(),
poolConfig.getValue().getValue(), poolConfig.getValue().getKey()));
}
start();
}
Copy link
Member

Choose a reason for hiding this comment

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

same thing here

Copy link
Member

@DomGarguilo DomGarguilo left a comment

Choose a reason for hiding this comment

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

I think a few new things have to be considered with these changes. Specifically what should the behavior be in all combinations of calling .start() and .shutdown().

For example, if we do the following:

var fate = new Fate<>(...);
fate.start();
fate.start();

I think this will spin up new sets of internal resources (watcher, cleaner) and replace the old ones without the old ones being shut down. It might be best to require that a Fate object be shut down before calling .start() on it if we even want to allow for reuse of these objects. I am not sure.

Another scenario we need to consider is the following:

var fate = new Fate<>(...);
fate.shutdown();

Will probably get some NPE on resources that are created in the .start method now.

Seems like we need a new AtomicBoolean started now to track the started state and handle these cases properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

schedule fate threads after fate construction

3 participants