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

SchematicsManager: Handling and caching list of known schematics, providing cli suggestions #2212

Closed
wants to merge 10 commits into from

Conversation

seijikun
Copy link
Contributor

@seijikun seijikun commented Nov 8, 2022

I implemented a SchematicsManager that handles the listing / caching of known schematic files.
The SchematicsManager has multiple possible backends.
The preferred backend is:

FileWatcherSchematicsBackend:
This backend uses Java's WatchService to listen for changes in the schematics directory. This rids us of any file listing IO.

PollingSchematicsBackend:
This is the fallback backend for the previous mentioned that is only used when the previous failed to initialize (for whatever reason that might be). It caches the result and returns the previous result as long as it's not older than 10 seconds. This is basically an Eventually Consistent Cache.

I then went on to implement a SchematicConverter to parse Schematics from arguments and provide suggestions.

This fixes #2095

@seijikun
Copy link
Contributor Author

seijikun commented Nov 8, 2022

This change in action:
(The suggestions for //schematics load ... and //schematics delete ...)

SchematicCompletion.mp4

Copy link
Member

@me4502 me4502 left a comment

Choose a reason for hiding this comment

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

I'm happy with this PR outside of the noted log points, but I'd also like someone else to have a go over it too :)

@Joo200
Copy link
Contributor

Joo200 commented Jan 1, 2023

I noticed that the implementation doesn't handle symlinks correctly.
With the setting files.allow-symbolic-links the symlinks will be followed.

Another issue with symlinks: Using recursive symlinks doesn't work fine:

  1. Create a folder in schematics (e.g. mkdir dummy)
  2. Create a symlink that points to one directory upwards (e.g. cd dummy && ln -fs ../ test)
    With this setup WorldEdit will follow the schematic path:
[12:45:30 INFO]: New Schematic found: /home/user/dev/server/paper/plugins/WorldEdit/schematics/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test/dummy/test

Copy link
Member

@octylFractal octylFractal left a comment

Choose a reason for hiding this comment

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

I like this a lot, but there are some edgecases to handle and cleanup to do.

Can we also move the com.sk89q.worldedit.util.schematic stuff to com.sk89q.worldedit.internal.schematic? I don't think this should be exposed as API. The RecursiveDirectoryWatcher should probably also be moved to com.sk89q.worldedit.internal.util.

@@ -21,6 +21,7 @@

import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
Copy link
Collaborator

Choose a reason for hiding this comment

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

extra import?

Comment on lines +64 to +71
var fileWatcherBackend = FileWatcherSchematicsBackend.create(schematicsDir);
if (fileWatcherBackend.isPresent()) {
backend = fileWatcherBackend.get();
} else {
createFallbackBackend();
}
} catch (IOException e) {
createFallbackBackend();
Copy link
Collaborator

Choose a reason for hiding this comment

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

we're generally not in the habit of using optionals in WE; it's being passed up from the recursivedirectory watcher, but isn't at all consistent with the fallback. additionally, it uses an empty optional to signify unsupportedexception, but on IOexception it just creates the fallback anyway. there is no difference in results.

Comment on lines 70 to 74
if (event instanceof RecursiveDirectoryWatcher.FileCreatedEvent) {
LOGGER.debug("New Schematic found: " + event.path());
} else if (event instanceof RecursiveDirectoryWatcher.FileDeletedEvent) {
LOGGER.debug("Schematic deleted: " + event.path());
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

why can't this just be inside the try statement, the instanceof is already being checked once.

@UntouchedOdin0
Copy link
Contributor

Has this unfortunately been abandoned now? It seemed like a really good idea.

@me4502
Copy link
Member

me4502 commented Jun 1, 2024

Closing in favour of #2542

@me4502 me4502 closed this Jun 1, 2024
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.

Add tab completion for loading schematics
6 participants