Skip to content

Channel connecting two JVM instances #13206

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

Merged
merged 26 commits into from
Jun 4, 2025
Merged

Conversation

JaroslavTulach
Copy link
Member

@JaroslavTulach JaroslavTulach commented May 30, 2025

Pull Request Description

Usage

@Persistable(id = 323432)
record PowerOf(int value) implements Function<Channel,  Integer> {
  public Integer apply(Channel otherJVM) {
     return value * value;
  }
}

final class PoolOfMessages implements Supplier<Persistable.Pool> {
  public Persistable.Pool get() {
    return Persistables.POOL;
  }
}

JVM jvm = JVM.create(....);
var channel = Channel.create(jvm, PoolOfMessages.class);
var four = channel.execute(new PowerOf(2))
assert 4 == four.intValue();

PoolOfMessages must be available for Class.forName in the jvm - either on classpath or module path.

Checklist

Please ensure that the following checklist has been satisfied before submitting the PR:

  • The documentation has been updated, if necessary.
  • All code follows the
    Scala,
    Java,
  • Unit tests have been written where possible.
    • Call from SVM to HotSpot JVM via a Message - back and forth factorial
    • Call from HotSpot back to SVM via Message - done
    • Propagation of exceptions from one side to another
    • Extensibility of the Pool with other messages
    • Select compatible Pool on both sides of the Channel

@JaroslavTulach JaroslavTulach marked this pull request as draft May 30, 2025 12:51
Copy link

github-actions bot commented May 30, 2025

✨ GUI Checks Results

Summary

  • 🧹 Prettier: ✅ Passed
  • 🧰 GUI Checks: ❌ Failed
  • 📚 Storybook: ❌ Failed

⚠️ Action Required: Please review the failed checks and fix them before merging.

See individual check results for more details.

@JaroslavTulach JaroslavTulach added the CI: No changelog needed Do not require a changelog entry for this PR. label May 30, 2025
@JaroslavTulach JaroslavTulach self-assigned this May 30, 2025
@JaroslavTulach JaroslavTulach added the CI: Clean build required CI runners will be cleaned before and after this PR is built. label Jun 3, 2025
),
Compile / moduleDependencies ++= slf4jApi ++ Seq(
"org.netbeans.api" % "org-openide-util-lookup" % netbeansApiVersion
Copy link
Member Author

Choose a reason for hiding this comment

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

NetBeans Lookup shouldn't be used during runtime: 879a092

@@ -4313,6 +4311,7 @@ lazy val `os-environment` =
),
Compile / internalModuleDependencies ++= Seq(
(`engine-common` / Compile / exportedModule).value,
(`persistance` / Compile / exportedModule).value,
Copy link
Member Author

@JaroslavTulach JaroslavTulach Jun 3, 2025

Choose a reason for hiding this comment

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

os-environment now contains support for passing Messages via Channel. Messages serde is handled via persistance - hence the dependency.

@JaroslavTulach JaroslavTulach linked an issue Jun 3, 2025 that may be closed by this pull request
3 tasks
import org.graalvm.nativeimage.c.type.CCharPointer;
import org.graalvm.nativeimage.c.type.CTypeConversion;

/** Channel connects two {@link JVM} instances. */
Copy link
Member Author

Choose a reason for hiding this comment

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

Since e28e6ea the channels are allocated in pairs. There is always an SubstrateVM side and HotSpot JVM side of the channel. Right now these two sides are going to have the same ID stored in ID_TO_CHANNEL map.

@JaroslavTulach JaroslavTulach marked this pull request as ready for review June 3, 2025 17:42
Function<MemorySegment, Long> send) {
try (var arena = Arena.ofConfined()) {
var bytes = pool.write(msg, null);
var memory = arena.allocate(Math.max(bytes.length, 4096));
Copy link
Member Author

Choose a reason for hiding this comment

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

  • Current limitation: the size of reply cannot be bigger than size of request or 4096.
  • I guess we can live with it and integrate
  • then proceed with other parts of Dual NI + JVM Mode for Loading Libraries #13172 to execute something in the other JVM
  • then go back and fix this limitation and also do some performance work

@JaroslavTulach JaroslavTulach changed the title Sending messages between two JVMs with the help of Persistance.Pool Sending messages between two JVMs with the help of Persistance.Pool Jun 3, 2025
@JaroslavTulach
Copy link
Member Author

JaroslavTulach commented Jun 4, 2025

Debugging the HotSpot code

One can influence HotSpot virtual machine options created by the JVM class by _JAVA_OPTIONS environment variable. Thus one can be debug with:

enso$ sbt os-environment/test
enso$ _JAVA_OPTIONS=-agentlib:jdwp=transport=dt_socket,address=5005 ./test-os-env
ERROR: transport error 202: connect failed: Connection refused
ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)

E.g. instruct your IDE to listen on 5005 port and debug the code running in HotSpot JVM.

Btw:

@JaroslavTulach JaroslavTulach changed the title Sending messages between two JVMs with the help of Persistance.Pool Channel connecting two JVM instances Jun 4, 2025
Copy link
Member

@Akirathan Akirathan left a comment

Choose a reason for hiding this comment

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

Looks good. Few minor comments inline.

@JaroslavTulach JaroslavTulach added the CI: Ready to merge This PR is eligible for automatic merge label Jun 4, 2025
@mergify mergify bot merged commit 62acca9 into develop Jun 4, 2025
116 of 121 checks passed
@mergify mergify bot deleted the wip/jtulach/JvmMessage13172 branch June 4, 2025 12:27
@hubertp
Copy link
Collaborator

hubertp commented Jun 5, 2025

Our CI is reporting problems with this change on MacOS ARM:

 INFO ide_ci::program::command: sbt ℹ️ [1/8] Initializing...                                                                                    (0,0s @ 0,95GB)
 INFO ide_ci::program::command: sbt ℹ️ Error: Support for the Foreign Function and Memory API is currently available only on the AMD64 architecture.
 INFO ide_ci::program::command: sbt ℹ️ Internal exception: com.oracle.svm.core.util.UserError$UserException: Support for the Foreign Function and Memory API is currently available only on the AMD64 architecture.

https://github.com/enso-org/enso/actions/runs/15457103830/job/43511280601#step:10:3634

GitHub
Enso Analytics is a self-service data prep and analysis platform designed for data teams. - Nightly Release · 8931518

@JaroslavTulach
Copy link
Member Author

JaroslavTulach commented Jun 5, 2025

Our CI is reporting problems with this change on MacOS ARM:

 INFO ide_ci::program::command: sbt ℹ️ [1/8] Initializing...                                                                                    (0,0s @ 0,95GB)
 INFO ide_ci::program::command: sbt ℹ️ Error: Support for the Foreign Function and Memory API is currently available only on the AMD64 architecture.
 INFO ide_ci::program::command: sbt ℹ️ Internal exception: com.oracle.svm.core.util.UserError$UserException: Support for the Foreign Function and Memory API is currently available only on the AMD64 architecture.

https://github.com/enso-org/enso/actions/runs/15457103830/job/43511280601#step:10:3634

I guess I should have read this GraalVM document sooner:

foreign calls are supported on the x64 architecture. Specifically, downcalls are supported on x64 Linux, Windows and MacOS, while upcalls are supported only on x64 Linux.

I'll think about alternative approaches today:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI: Clean build required CI runners will be cleaned before and after this PR is built. CI: No changelog needed Do not require a changelog entry for this PR. CI: Ready to merge This PR is eligible for automatic merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Dual NI + JVM Mode for Loading Libraries
3 participants