Skip to content

Commit 5b79c45

Browse files
committed
wip progress
1 parent cff3d66 commit 5b79c45

1 file changed

Lines changed: 88 additions & 22 deletions

File tree

collections/_posts/2022-09-17-typelevel-native.md

Lines changed: 88 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ meta:
88
author: armanbilge
99
---
1010

11+
We recently published
12+
13+
* Cats Effect v3.3.14
14+
* FS2 v3.3.0
15+
* http4s v0.23.16
16+
* Rediculous v0.4.1
17+
1118

1219

1320
#### What is Scala Native?
@@ -26,41 +33,85 @@ It is worth mentioning that in benchmarks Scala Native handily beats GraalVM Nat
2633

2734
Moreover, breaking free from the JVM is an opportunity to design a runtime specifically optimized for the Scala language itself. This is the true potential of the Scala Native project.
2835

29-
**For Typelevel in particular**, Scala Native opens new doors for leveling up our libraries.
36+
**For Typelevel in particular**, Scala Native opens new doors for leveling up our ecosystem. Our flagship libraries are largely designed for deploying high performance I/O-bounded microservices and for the first time ever **we now have direct access to kernel I/O APIs**.
3037

31-
W
32-
33-
I am also excited at the prospect of using Cats Effect to work with (non-Scala) native libraries exposing a C API. [`Resource`] and more generally [`MonadCancel`] provide the necessary combinators for safely navigating manual memory managment.
38+
I am also generally excited to use Cats Effect with (non-Scala) native libraries that expose a C API. [`Resource`] and more generally [`MonadCancel`] are powerful tools for safely navigating manual memory management with all the goodness of error-handling and cancelation.
3439

3540
#### How does it work?
3641

37-
The burden of cross-building the Typelevel ecosystem for Scala Native falls to [Cats Effect] and mostly to [FS2].
42+
The burden of cross-building the Typelevel ecosystem for Scala Native fell almost entirely to [Cats Effect] and [FS2].
43+
44+
**To cross-build Cats Effect for Native we had to get creative** because Scala Native currently does not support multithreading (although it will in the next major release). This is a similar situation to the JavaScript runtime, which is also fundamentally single-threaded. But an important difference is that JS runtimes are implemented as an [event loop] and offer callback-based APIs for scheduling timers and performing non-blocking I/O.
45+
46+
Unfortunately Scala Native .
47+
48+
The [`PollingExecutorScheduler`] implements both [`ExecutionContext`] and [`Scheduler`] and thus maintains two queues:
49+
- a queue of tasks (read: fibers) to execute
50+
- a priority queue of timers (read: `IO.sleep(...)`), sorted by expiration
51+
52+
It also defines an abstract method:
53+
```scala
54+
def poll(timeout: Duration): Boolean
55+
```
56+
57+
The idea of this method is very similar to `Thread.sleep()` except that while sleeping it also “polls” for I/O events. To demonstrate the API contract, consider invoking `poll(3.seconds)`:
58+
59+
*I have nothing to do for the next 3 seconds. So wake me up then, or earlier if there is an incoming I/O event I should handle. But wake me up no later!*
60+
61+
*Oh, and don’t forget to tell me whether there are still outstanding I/O events (`true`) or not (`false`) so I know if I need to call you again. Thanks!*
62+
63+
Thus, with tasks, timers, and the capability to poll for I/O, we can express the event-loop algorithm. A single iteration of the loop looks like this:
64+
65+
1. Check the current time and execute any expired timers.
66+
67+
2. Execute up to 64 tasks, or until there are none left. We limit to 64 to ensure we are fair to timers and I/O.
68+
69+
3. Poll for I/O events. There are three cases to consider:
70+
- **There is at least one task to do.** Call `poll(0.nanos)`, so it will process any available I/O events and then immediately return control.
71+
- **There is at least one outstanding timer**. Call `poll(durationToNextTimer)`, so it will sleep until the next I/O event arrives or the timeout expires, whichever comes first.
72+
- **There are no tasks to do and no outstanding timers.** Call `poll(Duration.Infinite)`, so it will sleep until the next I/O event arrives.
73+
74+
In fact, this is a very basic implementation of the [I/O Integrated Runtime Concept] proposed by Daniel Spiewak. The grander idea is that every `WorkerThread` in the `WorkStealingThreadPool` that underpins the Cats Effect JVM runtime can implement an event loop exactly like the one described above.
75+
76+
So: how do we implement `poll`? The bad news is that the answer is OS-specific, which is a large reason for why projects such as [libuv] exist.
77+
78+
The final piece of the puzzle is TLS. [FS2] . This is effectively the only non-Scala dependency required to use
3879

3980
From there, : any project
4081

4182
#### How can I try it?
4283

43-
Christopher Davenport has put up a [scala-native-ember-example](https://github.com/ChristopherDavenport/scala-native-ember-example) and reported some benchmark results!
84+
Christopher Davenport has put up a [scala-native-ember-example](https://github.com/ChristopherDavenport/scala-native-ember-example) and reported some [benchmark results](#ember-native-benchmark)!
85+
86+
#### What’s next and how can I get involved?
4487

88+
Please try the Typelevel Native stack! And even better deploy it, and do so loudly!
4589

46-
#### What's next and how can I get involved?
90+
Besides that, here is a brain-dump of project ideas or existing projects that would love contributors. I am happy to help folks get started!
91+
92+
* Cross-building existing libraries and developing new, Typelevel-native ones:
93+
- Go [feral] and implement a pure Scala [custom AWS Lambda runtime] that cross-builds for Native.
94+
- A pure Scala [gRPC] implementation built on http4s would be fantastic, even for the JVM. Christopher Davenport has published a [proof-of-concept][grpc-playground].
95+
- [fs2-data] has pure Scala support for a plethora of data formats. The [http4s-fs2-data] integration needs your help to get off the ground!
96+
97+
* Integrations with native libraries:
98+
- I kick-started [http4s-curl] and would love to see someone take the reigns!
99+
- An [NGINX Unit] server backend for http4s promises exceptional performance. [snunit] pioneered this approach.
100+
- Using [quiche] for HTTP/3 looks fun!
101+
- An idiomatic wrapper for [SQLite]. See also [davenverse/sqlite-sjs#1] which proposes cross-platform API backed by Doobie on the JVM.
102+
103+
* Developing I/O-integrated runtimes:
104+
- [epollcat] supports Linux and macOS and has plenty of opportunity for optimization and development.
105+
- A [libuv]-based runtime would have solid cross-OS support, including Windows. Prior art in [scala-native-loop].
106+
- Personally I am excited to work on an [io_uring] runtime.
47107

48-
* Please try the Typelevel Native stack! And even better deploy it, and do so loudly!
49-
* Cross-building existing libraries and developing new, Typelevel stack ones
50-
- a pure Scala [gRPC] implementation built on http4s would be fantastic, even for the JVM. Christopher Davenport has published [proof-of-concept][grpc-playground].
51-
- the fledgling [otel4s] project will need pure Scala backends
52-
*
53-
- An [NGINX Unit] server backend for http4s promises exceptional performance
54-
- I kick-started [http4s-curl]
55-
* Developing I/O-integrated runtimes.
56-
- [epollcat] supports Linux and macOS and has plenty of opportunity for optimization.
57-
- A [libuv]-based runtime
58-
-
59108
* Tooling. Anton Sviridov has spear-headed two major projects in this area:
60-
- [sn-bindgen]
61-
- [sbt-vcpkg]
109+
- [sbt-vcpkg] is working hard to solve the native dependency problem.
110+
- [sn-bindgen] generates Scala Native bindings to native libraries directly from `*.h` header files. I found it immensely useful while working on http4s-curl, epollcat, and the s2n-tls integration in FS2.
62111

63-
#### Ember example benchmark
112+
* Scala Native itself. Lots to do there!
113+
114+
#### Ember native benchmark
64115

65116
```
66117
$ hey -z 30s http://localhost:8080
@@ -110,19 +161,34 @@ Status code distribution:
110161
```
111162

112163
[Cats Effect]: https://typelevel.org/cats-effect/
164+
[custom AWS Lambda runtime]: https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html
165+
[davenverse/sqlite-sjs#1]: https://github.com/davenverse/sqlite-sjs/pull/1
166+
[`ExecutionContext`]: https://www.scala-lang.org/api/2.13.8/scala/concurrent/ExecutionContext.html
167+
[event loop]: https://javascript.info/event-loop
113168
[epollcat]: https://github.com/armanbilge/epollcat
169+
[feral]: https://github.com/typelevel/feral
114170
[FS2]: https://fs2.io/
171+
[fs2-data]: https://github.com/satabin/fs2-data/
115172
[GraalVM Native Image]: https://www.graalvm.org/22.2/reference-manual/native-image/
116173
[gRPC]: https://grpc.io/
117174
[grpc-playground]: https://github.com/ChristopherDavenport/grpc-playground
118175
[http4s]: https://http4s.org/
119176
[http4s-curl]: https://github.com/http4s/http4s-curl/
177+
[http4s-fs2-data]: https://github.com/http4s/http4s-fs2-data
178+
[I/O Integrated Runtime Concept]: https://github.com/typelevel/cats-effect/discussions/3070
179+
[io_uring]: https://en.wikipedia.org/wiki/Io_uring
120180
[libuv]: https://github.com/libuv/libuv/
121181
[LLVM]: https://llvm.org/
122182
[NGINX Unit]: https://unit.nginx.org/
123-
[io_uring]: https://en.wikipedia.org/wiki/Io_uring
183+
[`PollingExecutorScheduler`]: https://github.com/typelevel/cats-effect/blob/7ca03db50342773a79a01ecf137d953408ac6b1d/core/native/src/main/scala/cats/effect/unsafe/PollingExecutorScheduler.scala
184+
[quiche]: https://github.com/cloudflare/quiche
124185
[sbt-vcpkg]: https://github.com/indoorvivants/sbt-vcpkg/
186+
[ScalablyTyped]: https://scalablytyped.org/
125187
[Scala Native]: https://scala-native.org/
188+
[scala-native-loop]: https://github.com/scala-native/scala-native-loop/
189+
[`Scheduler`]: https://github.com/typelevel/cats-effect/blob/236a0db0e95be829de34d7a8e3c06914738b7b06/core/shared/src/main/scala/cats/effect/unsafe/Scheduler.scala
190+
[snunit]: https://github.com/lolgab/snunit
126191
[sn-bindgen]: https://github.com/indoorvivants/sn-bindgen
192+
[SQLite]: https://www.sqlite.org/index.html
127193
[`MonadCancel`]: https://typelevel.org/cats-effect/docs/typeclasses/monadcancel
128194
[`Resource`]: https://typelevel.org/cats-effect/docs/std/resource

0 commit comments

Comments
 (0)