anton-vinogradov commented on code in PR #13440:
URL: https://github.com/apache/ignite/pull/13440#discussion_r3745472326
##########
modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManager.java:
##########
@@ -402,6 +404,76 @@ private GridDeployment checkDeployment(GridDeployment
deployment, String store)
return locStore.getDeployment(meta);
}
+ /**
+ * Resolves the class loader the classes of a message must be read with.
Blocks when the deployment has to be
+ * requested from its owner, so it must not be called from a
socket-reading thread.
+ *
+ * @param msg Message carrying its own deployment.
+ * @return Class loader of the carried deployment, or the local one if the
message carries none.
+ * @throws IgniteDeploymentCheckedException If the deployment cannot be
obtained.
+ */
+ public ClassLoader classLoader(DeploymentAware msg) throws
IgniteDeploymentCheckedException {
+ return classLoader(msg.deploymentInfo(), msg.deployedClassName());
+ }
+
+ /**
+ * Resolves the class loader classes described by {@code depInfo} must be
read with. Blocks when the deployment has
+ * to be requested from its owner, so it must not be called from a
socket-reading thread.
+ *
+ * @param depInfo Deployment of the classes, or {@code null} when they
carry none.
+ * @param clsName Name of a class the deployment must be able to load.
+ * @return Class loader of the deployment, or the local one when there is
no deployment.
+ * @throws IgniteDeploymentCheckedException If the deployment cannot be
obtained.
+ */
+ public ClassLoader classLoader(@Nullable GridDeploymentInfo depInfo,
String clsName)
+ throws IgniteDeploymentCheckedException {
+ if (depInfo == null)
+ return U.resolveClassLoader(ctx.config());
+
+ return U.resolveClassLoader(globalDeployment(depInfo,
clsName).classLoader(), ctx.config());
+ }
+
+ /**
+ * Resolves the deployment {@code depInfo} describes, for the classes of
{@code clsName}. The sender of those
+ * classes is the node that created the class loader, or a participant
when the deployment has any.
+ *
+ * @param depInfo Deployment of the classes, as it came with the message
carrying them.
+ * @param clsName Name of a class the deployment must be able to load.
+ * @return The deployment the classes are loaded with.
+ * @throws IgniteDeploymentCheckedException If the deployment is gone or
peer class loading is off.
+ */
+ public GridDeployment globalDeployment(GridDeploymentInfo depInfo, String
clsName)
+ throws IgniteDeploymentCheckedException {
+ GridDeployment dep = globalDeployment(depInfo, clsName, clsName);
+
+ if (dep == null) {
+ throw new IgniteDeploymentCheckedException("Failed to obtain
deployment for class (is peer class " +
+ "loading turned on?): " + clsName);
+ }
+
+ return dep;
+ }
+
+ /**
+ * Resolves the deployment {@code depInfo} describes, as {@link
#globalDeployment(GridDeploymentInfo, String)}
+ * does, but under {@code rsrcName} (a task may be deployed under a name
of its own) and returns {@code null}
+ * instead of throwing, for callers that have somewhere else to look.
+ *
+ * @param depInfo Deployment of the classes, as it came with the message
carrying them.
+ * @param rsrcName Name the classes are deployed under.
+ * @param clsName Name of a class the deployment must be able to load.
+ * @return The deployment, or {@code null} when there is none.
+ */
+ @Nullable public GridDeployment globalDeployment(GridDeploymentInfo
depInfo, String rsrcName, String clsName) {
+ return getGlobalDeployment(depInfo.deployMode(),
+ rsrcName,
+ clsName,
+ depInfo.userVersion(),
+ depInfo.classLoaderId().globalId(),
Review Comment:
I was wrong here, and your question is what led me to it - thanks.
The two nodes are not the same in general. `GridCacheDeploymentManager`
states it directly:
```java
assert sndId.equals(ldrId.globalId()) || participants != null;
```
and `GridDeploymentManager#deploy` hands out the deployment of the
*original* owner when the class arrived by peer loading - the comment there
calls it a nested execution:
```java
// Check for nested execution. In that case, if task
// is available locally by name, then we should ignore class loader ID.
dep = checkDeployment(ldrStore.getDeployment(ldr.classLoaderId()),
"perLoader");
```
So a node that received classes from another one passes them further as a
participant of the same deployment, while being the sender itself.
And the receiving side needs the sender, not the owner:
`GridDeploymentPerVersionStore` asks it for the classes, records it with
`addParticipant`, and refuses the deployment when
`discovery().node(senderNodeId) == null`. Deriving the node from the loader id
would break exactly the case where the owner has left and the sender still
holds the classes.
Fixed: the resolution takes the node as a parameter again. Since generated
code has no way to know the sender, the `DeploymentAware` interface is gone
with it, and the callers - which do know the sender - pass it in.
##########
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/continuous/CacheContinuousQueryDeployableObject.java:
##########
@@ -88,11 +88,7 @@ protected CacheContinuousQueryDeployableObject(Object obj,
GridKernalContext ctx
<T> T unmarshal(UUID nodeId, GridKernalContext ctx) throws
IgniteCheckedException {
assert ctx != null;
- GridDeployment dep =
ctx.deploy().getGlobalDeployment(depInfo.deployMode(), clsName, clsName,
- depInfo.userVersion(), nodeId, depInfo.classLoaderId(),
depInfo.participants(), null);
-
- if (dep == null)
- throw new IgniteDeploymentCheckedException("Failed to obtain
deployment for class: " + clsName);
+ GridDeployment dep = ctx.deploy().globalDeployment(depInfo, clsName);
Review Comment:
Correction to my previous reply: the parameter is back.
The deployment resolution needs the sending node after all - it is not
derivable from the loader id, see the other thread. So `p2pUnmarshal(UUID
nodeId, GridKernalContext ctx)` keeps its signature, and the node is passed
down to the resolution instead of only feeding an assert.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]