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

DRILL-7317: Close ClassLoaders used for udf jars uploading when closing FunctionImplementationRegistry #1822

Merged
merged 1 commit into from Jul 8, 2019

Conversation

vvysotskyi
Copy link
Member

Please see DRILL-7317 for problem description.

* This is write operation, so one user at a time can call perform such action,
* others will wait till first user completes his action.
*/
public void removeAllJars() {
Copy link
Member

Choose a reason for hiding this comment

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

To improve performance please consider adding close method that will just close appropriate classloaders and then nullify map holders.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea!

I have made this change, could you please review it again?

@vvysotskyi
Copy link
Member Author

The latest change caused some tests failures, I'll inform when they are resolved...

}
});

jars.clear();
Copy link
Member

Choose a reason for hiding this comment

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

Giving a second thought we might consider not clearing the maps (better decision would be to nullify them but I assume we won't to remove final flag), then I suggest we leave them as is, since we are closing the Drillbit anyway.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agree, reverted this change.

/**
* Produces search of {@link DrillFuncHolder} which corresponds to specified {@code String functionName}
* with signature from {@code Queue<String> functionSignatures},
* closes its class loader if {@link DrillFuncHolder} is found and returns true. Otherwise faalse is returned.
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
* closes its class loader if {@link DrillFuncHolder} is found and returns true. Otherwise faalse is returned.
* closes its class loader if {@link DrillFuncHolder} is found and returns true. Otherwise false is returned.

Copy link
Member Author

Choose a reason for hiding this comment

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

Tanks, fixed.

Map<String, DrillFuncHolder> functionHolders = functions.get(functionName);
Iterator<String> signaturesIterator = functionSignatures.iterator();
DrillFuncHolder drillFuncHolder = null;
while (signaturesIterator.hasNext() && drillFuncHolder == null) {
Copy link
Member

Choose a reason for hiding this comment

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

Consider using streams findAny.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, it looks better with findAny.

*
* @param functionName name of the function
* @param functionSignatures function signatures
* @return {@code true} if {@link DrillFuncHolder} is found and its class loader is closed
Copy link
Member

Choose a reason for hiding this comment

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

Not exactly, you return true if even there was a failure when closing class loader, more correct would be to describe as return true if func holder was found and attempted to close class loader disregarding the result.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, replaced it with the sentence you have proposed.

}
}
// closes class loader only one time
isClosed = !isClosed && closeClassLoader(function, functionSignatures);
Copy link
Member

Choose a reason for hiding this comment

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

There is only once class loader per jar, we can consider using findAny as I have suggested below.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's correct that there is only one classloader per jar, but except closing it, we should also remove function signatures from functions map, so we need to iterate further.
With the current code, closeClassLoader method is called only once per jar.

Copy link
Member Author

@vvysotskyi vvysotskyi left a comment

Choose a reason for hiding this comment

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

@arina-ielchiieva, thanks for the review. I have addressed CR comments and tests failures.

Changes in the previous commit exposed interesting issue - when several drillbits are run within the same JVM, DrillMergeProjectRule caches its instance and FunctionImplementationRegistry, so all further DrillBits use cached version, but their own may have or may have not some specific functions.
It is important for the case when a user registers functions with the complex output so in this case DrillMergeProjectRule may merge project which cannot be merged.
The solution I propose is to remove caching of DrillMergeProjectRule.
It is added in a separate commit.

}
});

jars.clear();
Copy link
Member Author

Choose a reason for hiding this comment

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

Agree, reverted this change.

/**
* Produces search of {@link DrillFuncHolder} which corresponds to specified {@code String functionName}
* with signature from {@code Queue<String> functionSignatures},
* closes its class loader if {@link DrillFuncHolder} is found and returns true. Otherwise faalse is returned.
Copy link
Member Author

Choose a reason for hiding this comment

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

Tanks, fixed.

*
* @param functionName name of the function
* @param functionSignatures function signatures
* @return {@code true} if {@link DrillFuncHolder} is found and its class loader is closed
Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, replaced it with the sentence you have proposed.

Map<String, DrillFuncHolder> functionHolders = functions.get(functionName);
Iterator<String> signaturesIterator = functionSignatures.iterator();
DrillFuncHolder drillFuncHolder = null;
while (signaturesIterator.hasNext() && drillFuncHolder == null) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, it looks better with findAny.

}
}
// closes class loader only one time
isClosed = !isClosed && closeClassLoader(function, functionSignatures);
Copy link
Member Author

Choose a reason for hiding this comment

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

That's correct that there is only one classloader per jar, but except closing it, we should also remove function signatures from functions map, so we need to iterate further.
With the current code, closeClassLoader method is called only once per jar.

@arina-ielchiieva
Copy link
Member

+1, please squash the commits.

@vvysotskyi vvysotskyi force-pushed the DRILL-7317 branch 2 times, most recently from 4e35df6 to 538ca5e Compare July 7, 2019 20:04
…ng FunctionImplementationRegistry

- Fix issue with caching DrillMergeProjectRule and FunctionImplementationRegistry when different drillbits are started within the same JVM
@vvysotskyi vvysotskyi merged commit 77cf7e2 into apache:master Jul 8, 2019
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.

None yet

2 participants