An I/O-integrated runtime for Cats Effect on Scala Native, implemented with the epoll
API on Linux and the kqueue
API on macOS.
The primary goal of this project is to provide implementations for Java network I/O APIs used in the fs2-io library so that its fs2.io.net
package can cross-build for Scala Native. This in turn enables projects such as http4s Ember and Skunk to cross-build for Native as well.
libraryDependencies += "com.armanbilge" %%% "epollcat" % "0.1.4"
If you are developing a Scala Native application for Linux and macOS that does network I/O with fs2-io or any library built on top of it, such as http4s Ember or Skunk. If you are not doing network I/O, then the default Cats Effect runtime will work fine.
There are a couple options:
-
Where you would normally use
IOApp
orIOApp.Simple
, simply useEpollApp
orEpollApp.Simple
instead: it's a drop-in replacement. -
For test frameworks and other unusual situations, you may need to use
EpollRuntime.global
. For example to use with munit-cats-effect:
override def munitIORuntime = EpollRuntime.global
I do not recommend it. This project is intended for only applications, it is too opinionated for libraries to force it onto their users:
- It supports only Linux and macOS.
- It partially implements
java.*
APIs which it does not hold the "namespace rights" to, but these implementations are not canonical nor do they intend to be. - Your user may want to use a different runtime in their application (for example the
CurlRuntime
from http4s-curl). It is not possible to mix runtimes; expect bad things to happen.
However, you may want to add this dependency in your project's Test scope so that you can run your test suite on Native. You may also recommend Native users of your library add this dependency to their applications.
Actually, no :) inside EpollRuntime.global
you will find a vanilla ExecutionContext
and Scheduler
with APIs in terms of Java Runnable
. You can use these to run your Scala Future
s or other effect types and interact directly with the Java APIs.
Despite the project name, epollcat supports macOS as well via the kqueue
API.
Sorry, nope :)
First of all, I think a libuv-based runtime is a great idea, particularly due to the cross-platform compatibility and also because it provides async DNS and file system APIs (via its own blocking pool). If anyone wants to work on this I would be very happy to help you get started!
I thought a lot about this and where I should best put my time and energy. Here is some of my reasoning.
-
Actually, libuv is a bit too high-level for our needs: it essentially offers an entire runtime, including a scheduler and a blocking pool. Ideally we would use only its cross-platform I/O polling capability within our own Cats Effect runtime, but this does not seem to be exposed unfortunately.
This becomes especially relevant when Scala Native supports multi-threading. Cats Effect JVM ships with a fantastic runtime that I am hopeful we can eventually cross-build for Native. Meanwhile, the libuv event loop is fundamentally single-threaded.
Since in the long run implementing our own async I/O library seems inevitable, this project makes an early investment in that direction.
-
Dependencies on native libraries create build complexity, and build complexity is a burden on maintainers as well as contributors.
-
epollcat is a pretty cool name and I couldn't think of anything comparable for libuv :) besides unicorn velociraptors probably eat cats for lunch!