Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: async functions to make sure blocks/chunks are loaded #66

Merged
merged 2 commits into from
Nov 2, 2021

Conversation

keturn
Copy link
Contributor

@keturn keturn commented Sep 8, 2021

This provides a more powerful version of the forceAndWaitForGeneration helper method. The new makeBlocksRelevant and makeChunksRelevant methods load all required chunks to cover the given region.

Depends on:

Reviewers:

  • Which things do you think most need documentation?
  • ChunkRegionFutureTest contains one test.
    • Is it clear to you what it is testing and what information is relevant?
    • What additional tests would you need in order to feel comfortable working on this code and confident in its operation?

@@ -311,14 +366,21 @@ public boolean runWhile(long gameTimeTimeoutMs, Supplier<Boolean> f) {

while (f.get() && !timedOut) {
Thread.yield();
if (Thread.currentThread().isInterrupted()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

ehm.... how current thread can handle this if current thread is interrupted??
there should be try-catch - isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

“Interrupted” in Java threads is a funny thing. As I understand it, Thread#interrupt() does not cause a sudden jump in the code like a POSIX signal in Linux. It only sets a status on the thread to say "hello, I would like you to be interrupted now, please stop—if you feel like it."

Some standard blocking functions like sleep and read notice this and throw an exception. But if we're just crunching numbers in a loop, there might not be anything that would make us take notice of the interrupt request unless we check for it ourselves.

for (TerasologyEngine terasologyEngine : engines) {
terasologyEngine.tick();
boolean keepRunning = terasologyEngine.tick();
if (!keepRunning && terasologyEngine == host) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is host can be shutdown normally?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess someone could write a test that includes shutdown as expected behavior, but that's pretty different from the MTE tests I've seen so far.

@keturn
Copy link
Contributor Author

keturn commented Oct 8, 2021

The required engine PR was merged, so this does build now.

I'm afraid that as much fun as I had writing it, I don't expect this is readable/maintainable for most people:

BiFunction<ChunkRegionListener, Vector3ic, BlockRegionc> naivelyMakesForSize;
BiFunction<ChunkRegionListener, Vector3ic, BlockRegionc> makesForSize;
naivelyMakesForSize = (listener, size) -> relevanceSystem.addRelevanceEntity(entity, size, listener);
makesForSize = Functional.<ChunkRegionListener, Vector3ic, BlockRegionc>
enwiden(ChunkRegionFuture::regionSizeCorrector)
.apply(naivelyMakesForSize);
Function<ChunkRegionListener, BlockRegionc> makeChunksRelevant =
listener -> makesForSize.apply(listener, sizeInChunks);

so I think we had better find another way to write that without the higher-order function gymnastics before merging this one.

@keturn keturn changed the title WIP: async functions to make sure blocks/chunks are loaded feat: async functions to make sure blocks/chunks are loaded Oct 18, 2021
@keturn keturn marked this pull request as ready for review October 18, 2021 15:50
@keturn keturn added the Type: Improvement Request for or addition/enhancement of a feature label Oct 18, 2021
@keturn
Copy link
Contributor Author

keturn commented Oct 19, 2021

amidst all the distractions in the test log, there is this:

[Chunk-Processing-Reactor] ERROR o.t.e.w.c.p.​Chunk­Processing­Pipeline - Cannot run java.​util.​concurrent.​Executor­Completion­Service$​Queueing­Future​@6a1cf258 because queue is full

@keturn
Copy link
Contributor Author

keturn commented Oct 19, 2021

huh. Only saw that particular "queue full" message once; the later test runs don't have it.

Now this is in the unfortunate position of Works On My Machine, Fails in CI. Which I don't like, but it's also status quo—that's why we have @Tag("MteTest").

While I'd be very happy to see that fixed, I would also be okay with merging this without the Integration Tests stage passing, so that other tests can start using these new functions.

Comment on lines 34 to 36
@Test
void createChunkRegionFuture(Context context, ModuleTestingHelper mte) {
ChunkRegionFuture chunkRegionFuture = ChunkRegionFuture.create(context, center, sizeInChunks);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test uses MTEExtension so it can get a Context with a working RelevanceSystem and all. But is it something that could also make use of a stub RelevanceSystem to test something worthwhile?

Might be good to have, especially given that we haven't yet fixed the problems with MTE tests on our CI system.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why don't use entityManager, relevanceSystem instead?
Context using looks like you want to inject something in context.

Which problem?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Really, I want to use the injection system. Some classes, like Test cases and Terasology Systems, get to make references to the things in Context without cluttering up their method signatures.

But I don't know how to get things injected like that when constructing instances of other classes.

Overall, though, I only ended up using two things from the Context, so yeah it's probably worth the cost of one additional argument to remove that confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed to remove the Context reference.

@keturn
Copy link
Contributor Author

keturn commented Oct 24, 2021

Copy link
Contributor

@DarkWeird DarkWeird left a comment

Choose a reason for hiding this comment

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

Tested at FlexibleMovement module - it works (only one engine creating and waiting many generation waiting after every test world purge)

Many checkstyles issue about FIXME and TODO. I guess it will fixed after this PR.
Several JavaDoc's checkstyle issues

return Collections.unmodifiableSet(loadedChunks);
}

/** The entity defining the relevance region. */
Copy link
Contributor

Choose a reason for hiding this comment

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

check style:
no @return

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't have any good ideas about what to do here.

What more information would you like to see about this?


@SuppressWarnings("unused")
public BlockRegionc getChunkRegion() {
return chunks;
Copy link
Contributor

Choose a reason for hiding this comment

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

those chunks should be dense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know what you mean by that.


@Override
public void onChunkIrrelevant(Vector3ic pos) {
// FIXME: Document why this IS, in fact, called regularly.
Copy link
Contributor

Choose a reason for hiding this comment

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

onChunkIrrelevant happens when chunk leave relevant region (entity with Location and Relevant region move away)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That would make sense, but try uncommenting the logger.warn here and running the ChunkRegionFutureTest.

Nothing moves in that test, but onChunkIrrelevant sure does get called!

WorldProvider worldProvider = hostContext.get(WorldProvider.class);
if (worldProvider.isBlockRelevant(blockPos)) {
return;
return null;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you describe this at javadoc's @return line?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm. I didn't really think about this one.

This was previously a void method, so no existing code is using a return value from it.

When I changed this implementation to be on top of makeBlocksRelevant, I thought it would make sense to return the value from that (as seen below on line 277).

But it has this early-escape clause where it doesn't call makeBlocksRelevant at all.

What would make most sense here?

Leave it always returning void?

Remove the isBlockRelevant check, and always return the value from makeBlocksRelevant?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Finding no good way to explain that, I've reverted this back to having no return value.

@@ -399,8 +454,6 @@ public long getSafetyTimeoutMs() {
*
* The safety timeout exists to prevent indefinite execution in Jenkins or long IDE test runs, and should be
* adjusted as needed so that tests pass reliably in all environments.
*
* @param safetyTimeoutMs
Copy link
Contributor

Choose a reason for hiding this comment

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

Describe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved more of the above documentation to be within the @param block, is that what you were looking for?

Comment on lines 34 to 36
@Test
void createChunkRegionFuture(Context context, ModuleTestingHelper mte) {
ChunkRegionFuture chunkRegionFuture = ChunkRegionFuture.create(context, center, sizeInChunks);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why don't use entityManager, relevanceSystem instead?
Context using looks like you want to inject something in context.

Which problem?

@keturn
Copy link
Contributor Author

keturn commented Oct 28, 2021

@DarkWeird when I mentioned “we haven't yet fixed the problems with MTE tests on our CI system,” I was referring to the way the Integration Tests have not been passing for a long time: https://jenkins.terasology.io/teraorg/job/Terasology/job/Modules/job/M/job/ModuleTestingEnvironment/job/develop/

@keturn
Copy link
Contributor Author

keturn commented Oct 28, 2021

I forwarded some questions about what to do about the JavaDoc to #documentation.

Copy link
Contributor Author

@keturn keturn left a comment

Choose a reason for hiding this comment

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

I also pushed some javadoc syntax corrections.

return Collections.unmodifiableSet(loadedChunks);
}

/** The entity defining the relevance region. */
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't have any good ideas about what to do here.

What more information would you like to see about this?

@@ -399,8 +454,6 @@ public long getSafetyTimeoutMs() {
*
* The safety timeout exists to prevent indefinite execution in Jenkins or long IDE test runs, and should be
* adjusted as needed so that tests pass reliably in all environments.
*
* @param safetyTimeoutMs
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved more of the above documentation to be within the @param block, is that what you were looking for?

@keturn keturn force-pushed the spike/loadChunks branch 2 times, most recently from 9574f55 to 3697f80 Compare November 2, 2021 02:47
@keturn keturn requested a review from DarkWeird November 2, 2021 02:53
DarkWeird
DarkWeird previously approved these changes Nov 2, 2021
@keturn keturn merged commit bd1b59c into develop Nov 2, 2021
@keturn keturn deleted the spike/loadChunks branch November 2, 2021 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Improvement Request for or addition/enhancement of a feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants