Code Monkey home page Code Monkey logo

Comments (11)

LeeTibbert avatar LeeTibbert commented on May 28, 2024 1

@RustedBones , @armanbilge, @ekrich Thoughts, concerns?

I hear you getting your running shoes on and trying to make distance, quickly ;-)

from scala-native.

LeeTibbert avatar LeeTibbert commented on May 28, 2024

I may be somewhere between off in the weeds and dead wrong but let me capture a concern
which developed over several runs at implementing this stuff.

Relatively early in the process j.n.Socket and j.n.DatagramSocket may need new private[java] constructors.

Currently the getChannel() method in Socket and ServerSocket is not implemented (commented out).
DatagramSocket implements getChannel() as always returning null, reasonable with the current state of the code.

When a, say DatagramSocket can be created by channel, the former's getChannel() is supposed to report
the channel which created it. When that DatagramSocket is created directly as such, it is OK for it to continue
to report null.

When a say, DatagramSocket comes to be implemented in terms of a channel, there may be some
circularity or rabbit hole between the socket getChannel() and the channel socket() methods.
The channel creates a socket which has to track the socket which created it and the channel it uses
to do I/O. The channel it uses to do I/O probably needs to avoid creating a socket which creates a channel
which creates a socket, ad infinitum (?). My mind ached when I tried tracing this without the benefit
of actual experimental code.

from scala-native.

LeeTibbert avatar LeeTibbert commented on May 28, 2024

@armanbilge

I seem to remember that you implemented a few nio.channels files in some of your experimental
repositories (epollcat?, io_uring?) . I also seem to remember that they were up to your usual standards: somewhere between clean and exemplary.

Off the top of your head, do you remember where? Do you remember how happy you were with them?
I do not want to take more than 2 minutes of your time. "Check the repositories (then you will remember, grasshopper)"
is always a good & proper answer.

If they meet your standards, are you willing to contribute (some of) them to Scala Native, with thanks and
proper attribution?

from scala-native.

LeeTibbert avatar LeeTibbert commented on May 28, 2024

Implementation Note:

WIP PR #978, the oldest open SN PR, has some java.nio.channels files which might be useful,
particularly to provide the early stage "top of the pyramid" classes/traits required before even
getting to DatagramChannel.

As a courtesy, I asked the author of that PR if we could use those files but have not heard back.
I think that by the the SN Contributor's Agreement they, or code derived from them, can be used by SN.

Since these files are now well aged (perhaps 10 or 15 years old), I think there might be issues of content & style.
Content meaning things such as SN now using traits instead of classes. The files may not implement all of the
elements of Java 8. Then they may not implement Java 21 elements.

I remember the coding style needing/wanting to be brought up to current SN practice.

Still, even with these caveats, buffing them up may be easier than starting from a clean sheet of electrons
(ab ovo).

from scala-native.

LeeTibbert avatar LeeTibbert commented on May 28, 2024

Some files/classes/traits needed by j.n.channels.DatagramChannel already exist in SN.

I think, without having implemented, the unimplemented hierarchy for j.n.channels.DatagramChannel goes:

  1. NetworkChannel
  2. MulticastChannel
  3. java.nio.channels.AbstractInterruptableChannel // exists, may not be complete or usable as-is.
  4. SelectableChannel
  5. java.nio.channels.spi.AbstractSelectableChannel
  6. java.nio.channels.SelectorProvider // See Note 1 below
  7. DatagramChannel

I have not looked at the Java descriptions for numbers 3, 4, and 5. I suspect those, especially 4 & 5 are
likely to take some study/work.

It may make sense to start at the top and work our way down.

Note 1:
The Java documentation for java.nio.channels.SelectorProvider#provider gives a sequence for possibly
loading a system SelectorProvider based upon java system properties or the existence of a .jar file with
certain properties. As a to-be-documented implementation expedience, we may want to skip to the
third step of using a fixed provider and punting the first two steps until the "whole cloth" is working.
Who has the temerity to say that out loud?

from scala-native.

LeeTibbert avatar LeeTibbert commented on May 28, 2024

re: {DatagramSocket, Socket*}-over-channels

The JDK had a number of years and releases over which to switch the underlying implementation of
DatagramSocket, ServerSocket, and Socket to use channels. The JDK documentation describe a mechanism
to fall back from the channel based implementation to the well exercised traditional implementation.
I have a vague memory that the first release or two was opt-in, near the final release, it became opt-out.
A good, conservative, but resource expensive approach.

When the time comes, if channel based DatagramSockets have been exercised enough that we
have confidence in them, we could probably switch to the channel based implementation with out a fallback.
Of course, this would demand a prominent release note.

When the time comes to change to a channel based ServerSocket/Socket implementation, we may need to
follow the JDK approach and keep the conventional (current) code available and selectable. A lot will depend
upon the length of time it has been exercised. If it is years, that is evidence for "go-for-it". if it is weeks or months
that leads one to the overhead of the JDK approach.

from scala-native.

LeeTibbert avatar LeeTibbert commented on May 28, 2024

The actual implementation of DatagramChannel (and later *SocketChannel) should keep in mind the
eventual hope of switching to *socket-over-channel. This means that a, say, a write() done by a
DatagramChannel instance should probably not call a Socket instance write() method, but may
be able to call a possibly private[java] java.net.SocketImpl write method.

Then again, loathe to re-write a working wheel, it may be easier to make direct posixlib calls (beware
Windows complexities). A key is probably figuring out when byte I/O is being used by the SocketImpl
and when it has bulk (more than one byte) methods.

from scala-native.

armanbilge avatar armanbilge commented on May 28, 2024

Yes that's right, there are partial implementations of AsynchronousSocketChannel and AsynchronousServerSocketChannel in epollcat:

https://github.com/armanbilge/epollcat/tree/8f091ed7c4e426df61169bbc0f680a40dcf949da/core/src/main/scala/epollcat/internal/ch

Do you remember how happy you were with them?

As happy as one could be, within the limits of single-threading and JDK interfaces 😅

If they meet your standards, are you willing to contribute (some of) them to Scala Native, with thanks and
proper attribution?

Absolutely, I'd be very happy to see that code upstreamed. The goal is ultimately to retire that project and it would be a shame for the efforts there to go to waste.


There is an interesting question of the relationship between NIO1 (Selector, SocketChannel, ServerSocketChannel) and NIO2 (AsynchronousSocketChannel, AsynchronousServerSocketChannel).

What I mean is that it may make more sense to implement Selector, SocketChannel, and ServerSocketChannel first and then to implement the Asynchronous* counterparts in terms of those. But this is not strictly necessary: it's fully possible to implement NIO1 and NIO2 independently of each other.


Lastly, it's always good if there are target projects to help motivate this work. The epollcat effort to support AsynchronousSocketChannel was motivated by the fact that FS2 used these APIs (it no longer does, it now directly supports Scala Native). However, for example Apache Pekko uses Selector with SocketChannel.

from scala-native.

LeeTibbert avatar LeeTibbert commented on May 28, 2024

Later: TL;DR - Not a problem

Even though this concern is embarrassing to me, I am leaving it in place. Not the least so that I
can find the answer when I have exactly the same concern next month.

I used to know what @armanbilge patiently explained, for the 1000+ time, on Discourse.
When javalib compiles, it "sees" only the methods in the JDK active in the process.
When an application compiled against Java 8 actually runs, javalib can call any method
actually implemented in SN javalib, say a Java 21 method.

In the current discussion, that means we can use Java 8+ methods freely, as we may need them.
However, we may need to implement them in Scala Native javalib. Fair enough.

Need for at least baseline metrics remains, but not belabored.

Original:

Whilst reading the description of PR #3681, I realized that some of the claimed performance improvements of
either or both channels and mumbleSockets-over-channels may come from methods added after Java 8.

The key methods probably have to do with bulk (multi-character or multi-byte) I/O and/or buffer data
movements/access.

The design studies advocated by this Issue give an opportunity to study if/how the range from Java 8 to
Java 21 (or the Long Term Support version closest to that) can be supported with economic effort.

A good reason for at least some ballpark performance tests, probably at the channels level. Those tests can
be expanded over time.

from scala-native.

LeeTibbert avatar LeeTibbert commented on May 28, 2024

Arman,

Thank you for your entire comment. Insightful & useful as always.

Thank you also for your permission to upstream some of your existing work, which motivated
this discussion. Yeah, it takes me time to get things in motion.

from scala-native.

LeeTibbert avatar LeeTibbert commented on May 28, 2024

re: Java interfaces & multithreading

Note to self & others.

We need to ensure that a SN program using Channels or *Sockets that does not otherwise use multithreading,
does not bring in (or can justify bringing in) the overhead of SN Multithreading. (Especially since the SN compiler
can not detect and optimize single threading.)

When SN virtual threads arrive, we will have to see if javalib using virtual threads kicks off SN Multithreading.
By that time we may know if virtual threads are enabled for reasons other than *Sockets. Hard to glean the future.

from scala-native.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.