scala-native
scala-native copied to clipboard
scripted-tests java-net-server-socket appears to be broken.
Another "forget-me-not" & announcement.
java-net-server-socket appears to be totally non-functional. This breakage appears to be of long duration; probably more than 5 months on SN 0.5.0 and 4 months on 0.4.n.
The test is specifically designed to exercise javalib ServerSocket#accept
.
Issue #3131 reports a problem with accept()
which makes it totally non-functional:
hard broken, both IPv4 & IPv6, that is busted.
The broken accept()
in the September, 2022 PR passed java-net-server-socket
so
it was submitted as a PR which was then merged into SN 0.5.0 and eventually backported
to SN 0.4.n series. Given the nature of the problem reported in #3131 and the fix required,
it is almost absolutely certain that java-net-server-socket
is broken.
The java-net-server-socket
code can be described, at best, as "challenging". It makes sense
to wait until the multithread code is merged and exercised before attempting a re-write.
From a first examination, it appears to me that accept()
is failing in a Future and that
failure is not getting propagated back to a level of java-net-server-socket
which should
be reporting it. Or, the error output and any failure status is going into a black hole.
Oh-oh bad news. I hope this is fixable in a reasonable time. I use this as example (i.e. multi-client time server) in a small actor framework i am writing. It would be really nice to release full cross-platform (JVM, JS, Native). Thanks a lot for all your good work so far, i stay tuned! 👀
@devlaam if you are looking for (non-blocking) sockets, may I point you towards epollcat, which Lee and I have worked on together? It implements JDK AsynchronousSocketChannel
and related APIs.
https://github.com/armanbilge/epollcat
If it's helpful to your projects, note that most of the Typelevel stack runs on all three platforms: HTTP/1 and HTTP/2 server+client, Postgres client, Redis client, on JVM, Node.js, and Native.
https://typelevel.org/blog/2022/09/19/typelevel-native.html
@devlaam I submitted an 0.5.0 PR with the fix this morning.
I am trying to get a clean SN 0.4.x baseline build to ensure that the code in the 0.5.0 PR backports cleanly.
I/we are/am glad that you are including Scala Native in your examples.
As a quicky, you could try building with SN 0.4.7. That was released before the broken code entered the 0.4.x stream. I am told that there is a concept in German of "Buttered Bread always falls butter side down". Here that translate to "there is probably some fix in 0.4.8 or above which you need.". Arrgh!
Being exceedingly bothered about how this embarrassment escaped into the wild, I tracked down and examined the existing SN test that was supposed to exercise accept() and report flaws. That test is scripted-tests java-net-server-socket. I've created issue #3139 so that it does not get forgotten.
I also spent time remembering that @armanbilge 's typelevel code exercised client/server quite well. To date, that uses SN 0.4.x. I wondered why it passed and the SN 0.5.0 javalib flipped onto its back dead the first time it was used. Then I remembered that Arman tends to use posix sockets and avoid the java overhead.
I like to do 'defect analysis', not in the sense of finding 'fault' in the bad, recrimination, sense, but in the sense of "How did this happen so that we do not get to enjoy it again?".
As a quicky, you could try building with SN 0.4.7. That was released before the broken code entered the 0.4.x stream. I am told that there is a concept in German of "Buttered Bread always falls butter side down". Here that translate to "there is probably some fix in 0.4.8 or above which you need.". Arrgh!'
Well luckily i am living in Austria, although we do speak German over here, this saying does not apply. However, i tried a couple of versions <=0.4.7 and they all give the same problem. So, it could be that my sbt is not picking up the changed version somehow. Is there a way to ask at runtime what version for building was used?
https://github.com/armanbilge/epollcat https://typelevel.org/blog/2022/09/19/typelevel-native.html
These are interesting projects indeed. Thanks for bringing them to my attention.
A note-to-self so I can keep track of the discussion. There are two defects in motion here. This Issue tracks the failing test, so I do not forget it. Issue #3131 tracks the underlying defect: failing javalib accept().
Issue #3131 was addressed for SN 0.5.x by merged PR #3140
The fix for SN 0.4.x stream is PR #PR #3443, which is now in CI.
There is no fix or schedule for the broken "java-net-server-socket" test.
That will be "bigger than a breadbox", to continue the bread theme.
@devlaam
Motivated by your questions & experience, I went diving into the history of the file affected by Issue
#3131, and the underlying defect. Looks like the underlying accept()
defect was introduced 3.5+ years
ago. So, none of the 4.n series (and probably none of the 3.n series) will give the "magic fix" I had
been hoping for. Sorry for any time you spent on my misdirection.
Re: you question about telling which Scala Native version is actually being used by Sbt.
sbt> eval nativeVersion
[info] ans: String = 0.4.10
I ask myself that question several times a day. I am constantly switching between SN 0.5.x and 0.4.x. @armanbilge positively influences me to not forget 0.4.x, as it is in active use and 0.5.x is a dream, making massive progress towards being solid.
I have a private local.sbt
which has some code to allow me to do
"""
sbt> show scalaNativeVersion
[info] 0.4.10
// Similar/parallel to existing sbt> show javaVersion [info] 19 """
Re: you question about telling which Scala Native version is actually being used by Sbt.
Unfortunately I think it's a bit more complicated for users. For example, you may have sbt-scala-native 0.4.7 in your build.
However, you may depend on a library that was published with sbt-scala-native 0.4.10. Therefore, that library has a dependency on 0.4.10 of Nativelib, Javalib, etc. So these newer versions will evict the 0.4.7 versions.
In effect, you will be using the 0.4.7 compiler toolchain with the 0.4.10 version of the Javalib library.
In summary: just because you rollback the sbt-scala-native version, doesn't mean you are using old versions of the Javalib library. This can only be determined by analyzing your entire dependency tree.
Arman, thank you for that info! Guess I am too used to living in my own province.
I am constantly amazed by the cost of bugs and the difficulty of stamping them out once introduced.
I think there is an sbt plugin which will show the entire dependency tree, but I have never used it.
You can use the evicted
task in sbt to find out what's actually going on. Here's a little demo.
project/plugins.sbt
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.8")
build.sbt
enablePlugins(ScalaNativePlugin)
libraryDependencies += "org.typelevel" %%% "cats-effect" % "3.4.6"
sbt:sandbox> eval nativeVersion
[info] ans: String = 0.4.8
sbt:sandbox> evicted
[info] Here are other dependency conflicts that were resolved:
[info] * org.scala-native:nativelib_native0.4_2.12:0.4.9 is selected over 0.4.3
[info] +- org.scala-native:posixlib_native0.4_2.12:0.4.9 (depends on 0.4.9)
[info] +- org.scala-native:windowslib_native0.4_2.12:0.4.9 (depends on 0.4.9)
[info] +- org.scala-native:auxlib_native0.4_2.12:0.4.9 (depends on 0.4.9)
[info] +- org.scala-native:clib_native0.4_2.12:0.4.9 (depends on 0.4.9)
[info] +- io.github.cquiroz:cldr-api_native0.4_2.12:3.1.0 (depends on 0.4.3)
[info] * org.portable-scala:portable-scala-reflect_native0.4_2.12:1.1.2 is selected over 1.1.1
[info] +- io.github.cquiroz:scala-java-time_native0.4_2.12:2.4.0 (depends on 1.1.2)
[info] +- io.github.cquiroz:cldr-api_native0.4_2.12:3.1.0 (depends on 1.1.1)
[info] * org.scala-native:auxlib_native0.4_2.12:0.4.9 is selected over 0.4.3
[info] +- org.scala-native:scalalib_native0.4_2.12:0.4.8 (depends on 0.4.9)
[info] +- io.github.cquiroz:cldr-api_native0.4_2.12:3.1.0 (depends on 0.4.3)
[info] * org.scala-native:scalalib_native0.4_2.12:0.4.9 is selected over {0.4.8, 0.4.3, 0.4.4, 0.4.4, 0.4.4, 0.4.7, 0.4.7}
[info] +- default:sandbox_native0.4_2.12:0.1.0-SNAPSHOT (depends on 0.4.9)
[info] +- org.typelevel:cats-effect_native0.4_2.12:3.4.6 (depends on 0.4.9)
[info] +- org.typelevel:cats-effect-std_native0.4_2.12:3.4.6 (depends on 0.4.9)
[info] +- org.typelevel:cats-effect-kernel_native0.4_2.12:3.4.6 (depends on 0.4.9)
[info] +- org.typelevel:cats-kernel_native0.4_2.12:2.9.0 (depends on 0.4.7)
[info] +- org.typelevel:cats-core_native0.4_2.12:2.9.0 (depends on 0.4.7)
[info] +- org.portable-scala:portable-scala-reflect_native0.4_2.12:1.1.2 (depends on 0.4.4)
[info] +- io.github.cquiroz:scala-java-time_native0.4_2.12:2.4.0 (depends on 0.4.4)
[info] +- io.github.cquiroz:scala-java-locales_native0.4_2.12:1.4.0 (depends on 0.4.4)
[info] +- io.github.cquiroz:cldr-api_native0.4_2.12:3.1.0 (depends on 0.4.3)
[info] +- org.scala-native:scalalib_native0.4_2.12:0.4.8 (depends on 0.4.8)
[info] * org.scala-native:javalib_native0.4_2.12:0.4.9 is selected over 0.4.3
[info] +- org.scala-native:scalalib_native0.4_2.12:0.4.8 (depends on 0.4.9)
[info] +- io.github.cquiroz:cldr-api_native0.4_2.12:3.1.0 (depends on 0.4.3)
[success] Total time: 0 s, completed Feb 6, 2023, 5:40:30 PM
Wonderful! With (indeed in project/plugins.sbt)
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.6")
after reload
, clean
, compile
and run
, we have
sbt:native1> eval nativeVersion
[info] ans: String = 0.4.9
and
sbt:native1> evicted
[warn] Scala version was updated by one of library dependencies:
[warn] * org.scala-lang:scala-library:2.13.10 is selected over {2.13.8, 2.13.8}
[warn] +- org.scala-native:scalalib_native0.4_2.13:0.4.9 (depends on 2.13.10)
[warn] +- org.scala-lang:scala3-library_3:3.2.0 (depends on 2.13.8)
[warn] To force scalaVersion, add the following:
[warn] scalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))
[info] Here are other dependency conflicts that were resolved:
[info] * org.scala-lang:scala3-library_3:3.2.0 is selected over {3.1.3, 3.1.3, 3.1.3, 3.1.3, 3.1.3, 3.1.3, 3.1.3}
[info] +- default:native1_native0.4_3:0.1.0-SNAPSHOT (depends on 3.2.0)
[info] +- org.scala-native:windowslib_native0.4_3:0.4.9 (depends on 3.1.3)
[info] +- org.scala-native:scala3lib_native0.4_3:0.4.9 (depends on 3.1.3)
[info] +- org.scala-native:posixlib_native0.4_3:0.4.9 (depends on 3.1.3)
[info] +- org.scala-native:nativelib_native0.4_3:0.4.9 (depends on 3.1.3)
[info] +- org.scala-native:javalib_native0.4_3:0.4.9 (depends on 3.1.3)
[info] +- org.scala-native:clib_native0.4_3:0.4.9 (depends on 3.1.3)
[info] +- org.scala-native:auxlib_native0.4_3:0.4.9 (depends on 3.1.3)
[success] Total time: 0 s, completed 6 Feb 2023, 21:31:42
version 0.4.6 not even present (although i can see they libs are fetched)! Debugging gets kind of hard this way🤪
BTW, if i move to 0.4.10 this works as advertised:
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.10")
and
sbt:native1> eval nativeVersion
[info] ans: String = 0.4.10
sbt:native1> evicted
[info] Here are other dependency conflicts that were resolved:
[info] * org.scala-lang:scala3-library_3:3.2.1 is selected over {3.1.3, 3.1.3, 3.1.3, 3.1.3, 3.1.3, 3.1.3, 3.1.3}
[info] +- default:native1_native0.4_3:0.1.0-SNAPSHOT (depends on 3.2.1)
[info] +- org.scala-native:windowslib_native0.4_3:0.4.10 (depends on 3.1.3)
[info] +- org.scala-native:scala3lib_native0.4_3:0.4.10 (depends on 3.1.3)
[info] +- org.scala-native:posixlib_native0.4_3:0.4.10 (depends on 3.1.3)
[info] +- org.scala-native:nativelib_native0.4_3:0.4.10 (depends on 3.1.3)
[info] +- org.scala-native:javalib_native0.4_3:0.4.10 (depends on 3.1.3)
[info] +- org.scala-native:clib_native0.4_3:0.4.10 (depends on 3.1.3)
[info] +- org.scala-native:auxlib_native0.4_3:0.4.10 (depends on 3.1.3)
[success] Total time: 0 s, completed 6 Feb 2023, 21:39:21
Somehow i do not get it below version 0.4.9 (i adjusted to scala versions likewise).
But, to stay on topic, it does not matter anyway, so let's not waste time on this. I certainly hope we get some 0.4.11 with the socket fixed in the near future.
And, guilt by association, scripted-tests java-net-socket should be verified as actually testing something and reporting failures, if existing.