# \[ANN\] nanoev 0.1

**URL:** <https://discuss.ocaml.org/t/ann-nanoev-0-1/16682>\
**Category:** Community\
**Tags:** announce\
**Created:** [May 21, 2025, 3:55pm UTC](https://discuss.ocaml.org/t/ann-nanoev-0-1/16682 "2025-05-21T15:55:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![c-cube](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/c-cube/32/1727_2.png) [@c-cube](https://discuss.ocaml.org/u/c-cube)\
**Post date:** [May 21, 2025, 3:55pm UTC](https://discuss.ocaml.org/t/ann-nanoev-0-1/16682/1 "2025-05-21T15:55:45Z")

</div>

Hello,

I’m happy to announce the first release of [nanoev](https://github.com/c-cube/nanoev), yet another event loop abstraction. My goal with it is to have a narrow-waist interface between event loops (for now, `select` and `poll`) and various abstractions built directly on top (for now using `picos`), without tying the event loop abstraction itself to a particular scheduler. The core interface for the event loop is basically:

```ocaml
type t

val wakeup_from_outside : t -> unit

val step : t -> unit
(** Run one step of the event loop until something happens *)

val close : t -> Unix.file_descr -> unit
(** Close the file descriptor and clean it up *)

val max_fds : t -> int
(** Maximum number of file descriptors that can be observed at once. *)

val on_readable :
  t -> Unix.file_descr -> 'a -> 'b -> (closed:bool -> 'a -> 'b -> unit) -> unit

val on_writable :
  t -> Unix.file_descr -> 'a -> 'b -> (closed:bool -> 'a -> 'b -> unit) -> unit

val run_after_s : t -> float -> 'a -> 'b -> ('a -> 'b -> unit) -> unit

```

and nothing else. I’ve also started experimenting with using it to drive [tiny\_httpd](https://github.com/c-cube/tiny_httpd).

docs: [https://c-cube.github.io/nanoev/](https://c-cube.github.io/nanoev/)  
release link: [https://github.com/c-cube/nanoev/releases/tag/v0.1](https://github.com/c-cube/nanoev/releases/tag/v0.1)

---

<div class="post-metadata">

**Author:** ![gasche](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/gasche/32/4_2.png) [@gasche](https://discuss.ocaml.org/u/gasche)\
**Post date:** [May 21, 2025, 5:00pm UTC](https://discuss.ocaml.org/t/ann-nanoev-0-1/16682/2 "2025-05-21T17:00:18Z")

</div>

Two quick points of feedback:

- I don’t understand from reading your post which implementations of this interface you provide in the module. (You mention “various abstractions built directly on top (for now using `picos`)”, but this does not suggest that a `nanoev` interface can be built on top of `picos`, maybe rather the converse or something else.) By looking at the code I see a POSIX implementation.

- I followed the link you give to the [docs](https://c-cube.github.io/nanoev/), and I end up on a page that does not say what Nanoev is. I even wasn’t able to find, by clicking on a few links from there, a page that says what Nanoev is. (My best guess was [nanoev \> Nanoev](https://c-cube.github.io/nanoev/nanoev/Nanoev/index.html), but no luck.) I find this a bit disappointing as a documentation webpage.

---

<div class="post-metadata">

**Author:** ![c-cube](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/c-cube/32/1727_2.png) [@c-cube](https://discuss.ocaml.org/u/c-cube)\
**Post date:** [May 21, 2025, 5:28pm UTC](https://discuss.ocaml.org/t/ann-nanoev-0-1/16682/3 "2025-05-21T17:28:13Z")

</div>

Ha! That’s fair, I think. I’ll improve the docs.

The idea is that a `Nanoev.t` is an encapsulated event loop. There are two implementations, one with `select`, one with `poll` (which can handle more than 1024 FDs, woo). Then _on top of_ that, there’s a picos interface that provides things like `read` and `write` that relies on nanoev to wakeup the fiber when a FD is ready. But you could also use nanoev from other scheduler abstractions, it’s not tied to picos.

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [June 7, 2025, 2:45pm UTC](https://discuss.ocaml.org/t/ann-nanoev-0-1/16682/4 "2025-06-07T14:45:26Z")

</div>

Thanks for the interesting package. Glancing at the docs, I see:

> <https://github.com/c-cube/nanoev/blob/dc7f2ec92ea85734e6443c3aefcce14d922323b5/src/core/nanoev.mli#L5-L7>

However, in the sinopsys I see the following signatures:

> [@c-cube](#):
>
> ```auto
> val on_readable :
> t -> Unix.file_descr -> 'a -> 'b -> (closed:bool -> 'a -> 'b -> unit) -> unit
> 
> val on_writable :
> t -> Unix.file_descr -> 'a -> 'b -> (closed:bool -> 'a -> 'b -> unit) -> unit
> 
> ```

Given that IOCP on Windows are “completion-based” (you request an I/O operation and the OS tells you when it is complete) while the Un\*x API are “readiness-based” (the OS tells you when it is ready to perform I/O), the above signatures seem adapted for the latter but not the former.

I guess what I am asking is whether the comment about supporting IOCP is serious and, if yes, how exactly is it supposed to work?

Cheers,  
Nicolas

---

<div class="post-metadata">

**Author:** ![c-cube](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/c-cube/32/1727_2.png) [@c-cube](https://discuss.ocaml.org/u/c-cube)\
**Post date:** [June 8, 2025, 1:17am UTC](https://discuss.ocaml.org/t/ann-nanoev-0-1/16682/5 "2025-06-08T01:17:41Z")

</div>

That’s a good question, I honestly know little about Windows. It might never happen (unless Windows adopts io\_uring which, as far as I understand, can be used for readiness?). It’s not on my near-term plans at all. Sorry.
