You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: collections/_posts/2022-09-17-typelevel-native.md
+39-33Lines changed: 39 additions & 33 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,22 +8,15 @@ meta:
8
8
author: armanbilge
9
9
---
10
10
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.
12
12
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?
17
14
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**.
18
16
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.
19
18
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?
27
20
28
21
**For Scala in general**, funnily enough I think [GraalVM Native Image] does a great job summarizing the advantages of native executables, namely:
29
22
* 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
35
28
36
29
**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**.
37
30
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)!
39
36
40
-
####How does it work?
37
+
### How does it work?
41
38
42
39
The burden of cross-building the Typelevel ecosystem for Scala Native fell almost entirely to [Cats Effect] and [FS2].
43
40
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.
45
42
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.
47
44
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:
49
48
- a queue of tasks (read: fibers) to execute
50
49
- a priority queue of timers (read: `IO.sleep(...)`), sorted by expiration
51
50
@@ -54,13 +53,13 @@ It also defines an abstract method:
54
53
defpoll(timeout: Duration):Boolean
55
54
```
56
55
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)`:
58
57
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!*
60
59
61
60
*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
61
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 eventloop algorithm. A single iteration of the loop looks like this:
64
63
65
64
1. Check the current time and execute any expired timers.
66
65
@@ -71,28 +70,28 @@ Thus, with tasks, timers, and the capability to poll for I/O, we can express the
71
70
-**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
71
-**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
72
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.
79
74
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.
81
76
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.
83
78
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
85
83
86
-
####What’s next and how can I get involved?
84
+
### What’s next and how can I get involved?
87
85
88
86
Please try the Typelevel Native stack! And even better deploy it, and do so loudly!
89
87
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!
91
89
92
-
* Cross-building existing libraries and developing new, Typelevel-native ones:
90
+
* Cross-building existing libraries and developing new, Typelevel-stack ones:
93
91
- Go [feral] and implement a pure Scala [custom AWS Lambda runtime] that cross-builds for Native.
94
92
- 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
93
-[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.
96
95
97
96
* Integrations with native libraries:
98
97
- 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
0 commit comments