playframework / play-grpc

Play + Pekko gRPC
Apache License 2.0
35 stars 29 forks source link

[0.11.x] Activate Scala 3 when using the Akka stack #498

Closed mkurz closed 4 months ago

mkurz commented 10 months ago

A bit more tricky than on main branch because following dependencies do not provide Scala 3 artifacts:

com.lightbend.akka.grpc:akka-grpc-codegen:2.1.5
com.lightbend.akka.grpc:akka-grpc-runtime:2.1.5

com.typesafe.akka:akka-http-spray-json:10.2.10
com.typesafe.akka:akka-http2-support:10.2.10
com.typesafe.akka:akka-http:10.2.10
mkurz commented 10 months ago

Seems we ran into a show stopper here when using the outdated akka-grpc 2.1.x dependencies:

[error] -- Error: /home/runner/work/play-grpc/play-grpc/play-testdata/target/scala-3.3.1/src_managed/main/example/myapp/helloworld/grpc/helloworld/GreeterServiceMarshallers.scala:23:15 
[error] 23 |  implicit val HelloRequestSerializer = example.myapp.helloworld.grpc.helloworld.GreeterService.Serializers.HelloRequestSerializer
[error]    |               ^
[error]    |               type of implicit definition needs to be given explicitly
[error] -- Error: /home/runner/work/play-grpc/play-grpc/play-testdata/target/scala-3.3.1/src_managed/main/example/myapp/helloworld/grpc/helloworld/GreeterServiceMarshallers.scala:25:15 
[error] 25 |  implicit val HelloReplySerializer = example.myapp.helloworld.grpc.helloworld.GreeterService.Serializers.HelloReplySerializer
[error]    |               ^
[error]    |               type of implicit definition needs to be given explicitly
[warn] 6 warnings found
[error] two errors found
...
[error] -- Error: /home/runner/work/play-grpc/play-grpc/play-interop-test-scala/target/scala-3.3.1/src_managed/main/example/myapp/helloworld/grpc/helloworld/GreeterServiceMarshallers.scala:23:15 
[error] 23 |  implicit val HelloRequestSerializer = example.myapp.helloworld.grpc.helloworld.GreeterService.Serializers.HelloRequestSerializer
[error]    |               ^
[error]    |               type of implicit definition needs to be given explicitly
[error] -- Error: /home/runner/work/play-grpc/play-grpc/play-interop-test-scala/target/scala-3.3.1/src_managed/main/example/myapp/helloworld/grpc/helloworld/GreeterServiceMarshallers.scala:25:15 
[error] 25 |  implicit val HelloReplySerializer = example.myapp.helloworld.grpc.helloworld.GreeterService.Serializers.HelloReplySerializer
[error]    |               ^
[error]    |               type of implicit definition needs to be given explicitly
[warn] 5 warnings found
[error] two errors found

The generated code does not explicitly define the type of the implicits, which is needed for Scala 3. This was fixed in pekko-grpc already but akka-grpc only fixed that in version 2.3.0 which already is licenced under the BSL.

Conclusion: With the last Open Source version of akka-grpc, which is 2.1.x, it is impossible to provide Scala 3 artifacts for play-grpc. So I will put this on hold for now. We could in theory pull in the BSL licenced akka-grpc artifacts which already come with native Scala 3 support and everything should work, including the ALPN problem, just to make tests pass. We could mark them as provided for the Scala 3 build, so if someone using the akka stack under the BSL licences could in theory also make use of play-grpc by adding the deps manually. If you read this and are interested in that, please comment here and let us now.

felixbr commented 9 months ago

If you read this and are interested in that, please comment here and let us now.

Hi, I am interested in that. My company uses Akka in many projects and we have acquired the BSL last year and don't intend to migrate to Pekko in the near future*. In particular play-grpc is currently the last blocker for switching to Scala 3 in one of our projects.

As I understand 0.12.x and beyond will use Pekko and 0.11.x will be the version/branch for Akka support. In this scenario your proposal of pulling in akka-grpc 2.3.x as provided makes sense, as people without a BSL will want to use 0.12.x anyway.

If I can assist in any way, let me know 🙂

~ Felix

*I'm not necessarily against migrating to Pekko but these migrations tend to be a massive headache if you have a big existing codebase.

mkurz commented 8 months ago

@felixbr Are you still interested in this PR?

felixbr commented 8 months ago

@mkurz I'm still interested, yes

mkurz commented 8 months ago

@felixbr I maybe take a look on this monday.

mkurz commented 5 months ago

@felixbr @muuki88 if you are still interested, I released 0.11.1-M1 which you can give a try. It provides Scala 3 artifacts, built with newer akka libraries that are BSL licensed. However, these dependencies marked as provided so you would have to pull them in yourself, because we do not ship any bsl dependencies. Making this work is an exception now, because there is no other way to provide Scala 3 artifacts for play-grpc using Play 2.9. I was interested myself how to make this work so I gave it a try.

That means in plugins.sbt you would have to:

libraryDependencies += "com.typesafe.play" %% "play-grpc-generators" % "0.11.1-M1"
libraryDependencies += "com.lightbend.akka.grpc" %% "akka-grpc-codegen" % "2.3.4" // or newer

and in build.sbt:

libraryDependencies += "com.typesafe.play" %% "play-grpc-runtime" % "0.11.1-M1"
libraryDependencies += "com.typesafe.akka" %% "akka-discovery" % "2.7.0" // or newer
libraryDependencies += "com.typesafe.akka" %% ... // see below

and all other provided dependencies listed in the pom here: view-source:https://repo1.maven.org/maven2/com/typesafe/play/play-grpc-runtime_3/0.11.1-M1/play-grpc-runtime_3-0.11.1-M1.pom

felixbr commented 5 months ago

Thank you for that effort!

I'll try and make time in the next two weeks to give our Scala 3 migration another push with those artifacts and report back.

If the migration works out well, we might tackle Pekko next. We do have a license for Akka but if using it puts unnecessary strain on open-source maintainers like you in the long run, we should do our part to alleviate that.

felixbr commented 5 months ago

I'm trying out 0.11.1-M1 for play-grpc with Scala 3 and it seems to resolve but I cannot really test it as there are other issues with Play still:

[error] Modules were resolved with conflicting cross-version suffixes in ProjectRef(uri("file:/Users/felix.bruckmeier/g/gd/yo/"), "server"):
[error]    com.typesafe.akka:akka-http-core _3, _2.13
[error]    com.typesafe.akka:akka-parsing _3, _2.13
[error]    com.typesafe.akka:akka-http2-support _3, _2.13

After some digging it seems that some Play 2.9 modules for Scala 3 still depend on Scala 2.13 modules even though there's Scala 3 versions available.

For example com.typesafe.play:play-akka-http-server_3:2.9.4-M1 depends on com.typesafe.akka:akka-http-core_2.13:10.2.10

After excluding those 2.13 dependencies manually it compiled but when trying to start the server akka complains that many modules are version 2.6.21 even though I've explicitly added all akka-dependencies as 2.8.5. The eviction probably doesn't work because those 2.6.21 dependencies are also 2.13 instead of 3 for some reason.

My guess is one of the Play or Akka plugins adds those 2.6.21 dependencies with Scala 2.13 hardcoded. I'm not going to investigate further at this point. It is clear that Akka and Play will no longer work together in the future and adding Scala 3 makes it even worse.

The only way forward is to move everything to Pekko and Play 3.x but at that point I'd rather just rewrite our services using typelevel libraries.

In any case, thank you for your time and effort 🙂

mkurz commented 5 months ago

@felixbr Did you set PlayKeys.akkaHttpScala3Artifacts := true in build.sbt?

See

felixbr commented 4 months ago

akkaHttpScala3Artifacts helps, thanks. I had to sort out some unrelated Scala 3 things but everything at least compiles now. We will roll this out and monitor if everything works as expected.

mkurz commented 4 months ago

@felixbr Great! I will release stable 0.11.1 then.

felixbr commented 4 months ago

The updated version with Scala 3 has been live in production for more than 2 hours and everything looks stable.

I think releasing and documenting 0.11.1 makes sense. How you want to proceed maintenance for play-grpc with akka is up to you.

As I said before, I don't really want us to be an additional burden on open-source maintainers, so migrating to Pekko (or typelevel) is not out of the picture in the mid- to long-term. Still, this release buys us a bit more time and made a Scala 3 migration possible which is great!

Thanks again 🙂

mkurz commented 4 months ago

@felixbr Just to let you know I did release 0.11.1 last week, see release notes: https://github.com/playframework/play-grpc/releases/tag/0.11.1