Computer Science
Data Processing
Digital Life
Distributed System
Distributed System Infrastructure
Machine Learning
Operating System
Programming Language
Type System
Software Engineering
Life in Guangzhou (2013)
Recent Works (2013)
东京之旅 (2014)
My 2017 Year in Review (2018)
My 2020 in Review (2021)
十三年前被隔离的经历 (2022)
A Travel to Montreal (2022)
My 2022 in Review (2023)
Travel Back to China (2024)
RSS Brain
Migrate Scala2grpc to Cats Effect 3 (2023)
Comment Everywhere (2013)
Fetch Popular Erlang Modules by Coffee Script (2013)
耶鲁大学心理学导论 (2012)

Migrate Scala2grpc to Cats Effect 3

Posted on 23 Sep 2023, tagged ProgrammingScalagRPCCatsFunctional Programming

Scala2grpc is a library and SBT plugin I wrote so that you can integrate gRPC to Scala code in a non-invasive way. In a previous blog post, I talked about the motivation behind it.

The library requires each service method to return Cats Effect’s IO or fs2 stream. However, it’s still using Cats Effect 2.x version. There are big changes in Cats Effect 3 and almost all up to date libraries already support it. So it’s time to migrate it to Cats Effect 3 as well.

Replace Akka gRPC with fs2-grpc

This library was using akka-grpc. But I want to replace it for a few reasons:

  • It uses streamz to convert between Akka streams and fs2 streams. This library doesn’t support Cats Effect 3 and hasn’t been updated for a while. This is the biggest reason that I need to migrate from akka immediately.
  • Akka changed its open source license to a very expensive one which I didn’t know at the time writing this library. Even the license doesn’t cost anything if the revenue doesn’t reach a certain point, I don’t want it to be a liability.
  • It’s good to have a gRPC library that supports for Cats Effect and fs2 streams natively.

So in the newer version, I replaced Akka gRPC with fs2-grpc, a library under Typelevel umbrella and natively supports Cats Effect and fs2. The document is not as good and I spent quite some time to figure out how to actually use it, but I’m happy it finally worked out.

Add Hooks to gRPC Calls

In the previous version of Scala2grpc, there is a feature to log every request. But it is a pretty hacky implementation: I just throw the logging logic into the generated code. Since this version is a breaking change, it’s a good opportunity to revisit the approach and see how to add generic hooks before and after each gRPC calls.

My implementation wraps the gRPC response into a context in the generated code. The context includes the response with type of IO or fs2.Stream. Because of the referential transparency, you can take the response and add hooks before or after it. More detailed document is in this section of readme.

Non-invasive Nature of the Library

The migration brings lots of breaking changes, so it is a good test for the non-invasive nature of the library. I have 2 side projects that are using this library and I migrated one of them recently. Since it’s also using Cats Effect, there are some migration steps unrelated to this library. But regarding of the related parts, the migration process is very smooth: I don’t need to change any implementation code of the services. The generated gPRC protocol files are also not changed either. The only thing I need to change is the single object that implements GRPCGenerator to pass in some new parameters. It is impossible if I used akka gRPC directly and changed it to fs2-grpc since their interface are all different.

I’m so happy with the result: it adds gRPC to pure Scala code so easily without ever touch it. It saves me so much time to build a service and keeps the code clean at the same time. It continue to be a must have for my future Scala gRPC projects.