Skip to content

Commit 43612ae

Browse files
committed
more wip wip
1 parent 5b79c45 commit 43612ae

1 file changed

Lines changed: 39 additions & 33 deletions

File tree

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

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

11-
We recently published
11+
We recently published several major projects for the [Scala Native] platform, notably [Cats Effect], [FS2], and [http4s]. This blog post explores what this new platform means for the Typelevel ecosystem as well as how it works under-the-hood.
1212

13-
* Cats Effect v3.3.14
14-
* FS2 v3.3.0
15-
* http4s v0.23.16
16-
* Rediculous v0.4.1
13+
### What is Scala Native?
1714

15+
[Scala Native] is an optimizing ahead-of-time compiler for the Scala language. Put simply: it enables you to **compile Scala code directly to native executables**.
1816

17+
It is an ambitious project following in the steps of [Scala.js]. Instead of targeting JavaScript, the Scala Native compiler targets the [LLVM] IR and uses its toolchain to generate native executables for a range of architectures, including x86, ARM, and in the near future web assembly.
1918

20-
#### What is Scala Native?
21-
22-
Scala Native is an optimizing ahead-of-time compiler for the Scala language. Put simply: it enables you to **compile Scala code directly to native executables**.
23-
24-
It is an ambitious project following in the steps of Scala.js. Instead of targeting JavaScript, the Scala Native compiler targets the [LLVM] IR and uses its toolchain to generate native executables for a range of architectures, including x86, ARM/M1, and in the near future web assembly.
25-
26-
#### Why is this exciting?
19+
### Why is this exciting?
2720

2821
**For Scala in general**, funnily enough I think [GraalVM Native Image] does a great job summarizing the advantages of native executables, namely:
2922
* instant startup that immediately achieves peak performance, without requiring warmup or the heavy footprint of the JVM
@@ -35,17 +28,23 @@ Moreover, breaking free from the JVM is an opportunity to design a runtime speci
3528

3629
**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**.
3730

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.
31+
I am also enthusiastic 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.
32+
33+
### How can I try it?
34+
35+
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)!
3936

40-
#### How does it work?
37+
### How does it work?
4138

4239
The burden of cross-building the Typelevel ecosystem for Scala Native fell almost entirely to [Cats Effect] and [FS2].
4340

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.
41+
**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 with an [event loop] and offer callback-based APIs for scheduling timers and performing non-blocking I/O.
4542

46-
Unfortunately Scala Native .
43+
Meanwhile, Scala Native core does not implement an event loop nor offer such APIs. There is the [scala-native-loop] project, which wraps the [libuv] event loop runtime, but we did not want to bake such an opinionated dependency into Cats Effect core.
4744

48-
The [`PollingExecutorScheduler`] implements both [`ExecutionContext`] and [`Scheduler`] and thus maintains two queues:
45+
Fortunately Daniel Spiewak had the fantastic insight that the “dummy runtime” I initially used to cross-build Cats Effect for Native could be reformulated into a legitimate event loop implementation.
46+
47+
The [`PollingExecutorScheduler`] implements both [`ExecutionContext`] and [`Scheduler`] and maintains two queues:
4948
- a queue of tasks (read: fibers) to execute
5049
- a priority queue of timers (read: `IO.sleep(...)`), sorted by expiration
5150

@@ -54,13 +53,13 @@ It also defines an abstract method:
5453
def poll(timeout: Duration): Boolean
5554
```
5655

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)`:
56+
The idea of this method is very similar to `Thread.sleep()` except that besides sleeping it may also “poll” for I/O events. To demonstrate the API contract, consider invoking `poll(3.seconds)`:
5857

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!*
58+
*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 that I should handle. But wake me up no later!*
6059

6160
*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!*
6261

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:
62+
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:
6463

6564
1. Check the current time and execute any expired timers.
6665

@@ -71,28 +70,28 @@ Thus, with tasks, timers, and the capability to poll for I/O, we can express the
7170
- **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.
7271
- **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.
7372

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
73+
In fact, this is a very basic implementation of the [I/O Integrated Runtime Concept]. The grander idea is that every `WorkerThread` in the `WorkStealingThreadPool` that underpins the Cats Effect JVM runtime can run an event loop exactly like the one described above, for exceptionally high-performance I/O.
7974

80-
From there, : any project
75+
**So, how do we implement `poll`?** The bad news is that the answer is OS-specific, which is a large reason why projects such as libuv exist. Furthermore, the entire purpose of polling is to support non-blocking I/O, which falls outside of the scope of Cats Effect. This brings us to FS2, and specifically the [`fs2-io`] module.
8176

82-
#### How can I try it?
77+
**The final important piece of the cross-build puzzle was a [TLS] implementation** for `TLSSocket` and related APIs in FS2. Although this task was daunting, ultimately it was straightforward to directly integrate with [s2n-tls], which has a well-designed and well-documented API. This is effectively the only non-Scala dependency required to use the Typelevel stack on Native.
8378

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)!
79+
And that is pretty much it. **From here, any library or application that is built using Cats Effect and FS2 cross-builds for Scala Native effectively for free.** Three spectacular examples of this are:
80+
* [http4s] Ember, a server+client duo with HTTP/2 support
81+
* [Skunk], a Postgres client
82+
* [rediculous], a Redis client
8583

86-
#### What’s next and how can I get involved?
84+
### What’s next and how can I get involved?
8785

8886
Please try the Typelevel Native stack! And even better deploy it, and do so loudly!
8987

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!
88+
Besides that, here is a brain-dump of project ideas and existing projects that would love contributors. I am happy to help folks get started on any of these, or ideas of your own!
9189

92-
* Cross-building existing libraries and developing new, Typelevel-native ones:
90+
* Cross-building existing libraries and developing new, Typelevel-stack ones:
9391
- Go [feral] and implement a pure Scala [custom AWS Lambda runtime] that cross-builds for Native.
9492
- 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].
9593
- [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!
94+
- Lack of cross-platform cryptography is one of the remaining sore points in cross-building. I started the [bobcats] project to fill the gap but I am afraid it needs love from a more dedicated maintainer.
9695

9796
* Integrations with native libraries:
9897
- I kick-started [http4s-curl] and would love to see someone take the reigns!
@@ -111,7 +110,7 @@ Besides that, here is a brain-dump of project ideas or existing projects that wo
111110

112111
* Scala Native itself. Lots to do there!
113112

114-
#### Ember native benchmark
113+
### Ember native benchmark
115114

116115
```
117116
$ hey -z 30s http://localhost:8080
@@ -160,6 +159,7 @@ Status code distribution:
160159
[200] 114525 responses
161160
```
162161

162+
[bobcats]: https://github.com/typelevel/bobcats
163163
[Cats Effect]: https://typelevel.org/cats-effect/
164164
[custom AWS Lambda runtime]: https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html
165165
[davenverse/sqlite-sjs#1]: https://github.com/davenverse/sqlite-sjs/pull/1
@@ -169,6 +169,7 @@ Status code distribution:
169169
[feral]: https://github.com/typelevel/feral
170170
[FS2]: https://fs2.io/
171171
[fs2-data]: https://github.com/satabin/fs2-data/
172+
[`fs2-io`]: https://fs2.io/#/io
172173
[GraalVM Native Image]: https://www.graalvm.org/22.2/reference-manual/native-image/
173174
[gRPC]: https://grpc.io/
174175
[grpc-playground]: https://github.com/ChristopherDavenport/grpc-playground
@@ -182,13 +183,18 @@ Status code distribution:
182183
[NGINX Unit]: https://unit.nginx.org/
183184
[`PollingExecutorScheduler`]: https://github.com/typelevel/cats-effect/blob/7ca03db50342773a79a01ecf137d953408ac6b1d/core/native/src/main/scala/cats/effect/unsafe/PollingExecutorScheduler.scala
184185
[quiche]: https://github.com/cloudflare/quiche
186+
[rediculous]: https://github.com/davenverse/rediculous
185187
[sbt-vcpkg]: https://github.com/indoorvivants/sbt-vcpkg/
186188
[ScalablyTyped]: https://scalablytyped.org/
187189
[Scala Native]: https://scala-native.org/
190+
[Scala.js]: https://www.scala-js.org/
188191
[scala-native-loop]: https://github.com/scala-native/scala-native-loop/
189192
[`Scheduler`]: https://github.com/typelevel/cats-effect/blob/236a0db0e95be829de34d7a8e3c06914738b7b06/core/shared/src/main/scala/cats/effect/unsafe/Scheduler.scala
193+
[Skunk]: https://github.com/tpolecat/skunk
194+
[SQLite]: https://www.sqlite.org/index.html
190195
[snunit]: https://github.com/lolgab/snunit
191196
[sn-bindgen]: https://github.com/indoorvivants/sn-bindgen
192-
[SQLite]: https://www.sqlite.org/index.html
197+
[s2n-tls]: https://github.com/aws/s2n-tls
198+
[TLS]: https://en.wikipedia.org/wiki/Transport_Layer_Security
193199
[`MonadCancel`]: https://typelevel.org/cats-effect/docs/typeclasses/monadcancel
194200
[`Resource`]: https://typelevel.org/cats-effect/docs/std/resource

0 commit comments

Comments
 (0)