-
Notifications
You must be signed in to change notification settings - Fork 552
Python: route imports through a PythonImportService so Java ChangeType stops corrupting files #8323
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -239,6 +239,18 @@ void evictDropsTreeFromBothPeers() { | |
| assertThat(server.remoteObjects).doesNotContainKey(id); | ||
| } | ||
|
|
||
| /** | ||
| * The id-keyed object maps must stay concurrent, since {@code GetObject.Handler} reads them from | ||
| * its own thread pool while in-flight visits write them and a {@code HashMap} resize race dropped | ||
| * a present key as "Tree not found" (customer-requests#2858) -- an invariant rather than a | ||
| * behavioral test because the resize window is too small to hit deterministically. | ||
| */ | ||
| @Test | ||
| void sharedObjectMapsAreThreadSafe() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't find this test particularly useful. |
||
| assertThat(client.localObjects).isInstanceOf(java.util.concurrent.ConcurrentMap.class); | ||
| assertThat(client.remoteObjects).isInstanceOf(java.util.concurrent.ConcurrentMap.class); | ||
| } | ||
|
|
||
| @DocumentExample | ||
| @Test | ||
| void sendReceiveIdempotence() { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -241,6 +241,12 @@ private void addImport(JavaType.FullyQualified owningClass) { | |
| j = ((TypedTree) tree).withType(updateType(((TypedTree) tree).getType())); | ||
| } else if (tree instanceof JavaSourceFile) { | ||
| JavaSourceFile sf = (JavaSourceFile) tree; | ||
| // Languages that keep imports among the statements (Python) expose none through | ||
| // getImports(), so hand removal to their import service; on a genuinely import-less | ||
| // Java file there is nothing to remove and this is a no-op. | ||
| boolean removeThroughImportService = targetType instanceof JavaType.FullyQualified && | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Since |
||
| sf.getImports().isEmpty(); | ||
|
|
||
| if (targetType instanceof JavaType.FullyQualified) { | ||
| for (J.Import anImport : sf.getImports()) { | ||
| if (anImport.isStatic()) { | ||
|
|
@@ -280,6 +286,12 @@ private void addImport(JavaType.FullyQualified owningClass) { | |
| } | ||
| } | ||
|
|
||
| if (removeThroughImportService) { | ||
| // Queued after the addition so the import service sees the name already bound by | ||
| // the new import, which is what makes the old one safe to retire. | ||
| maybeRemoveImport(originalType.getFullyQualifiedName()); | ||
| } | ||
|
|
||
| j = sf.withImports(ListUtils.map(sf.getImports(), i -> { | ||
| Cursor cursor = getCursor(); | ||
| setCursor(new Cursor(cursor, i)); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The javadoc says
GetObject.Handlerreads these "while multiple in-flightvisitcalls write them." GivenRewriteRpcProcessManager'sThreadLocal, multiple in-flight visits are on differentRewriteRpcinstances with different maps — so the concurrent writer described here doesn't exist, and the only genuine cross-thread pair is this instance's owner and its jsonrpc dispatcher. Worth rewording to whichever model you land on, since this javadoc is the thing the next person will reason from.