---
title: "Internals"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Internals}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
```

This article is an implementation note, not a compatibility guarantee.

## Dataflow

At runtime, all operations go through three explicit stages:

1. **R wrapper** builds a typed argument object and lightweight error checks,
2. **Rust layer** executes async OpenDAL operations,
3. **R result or C result object** surfaces either a value or an
   `opendalErrorValue`.

`OpendalFs` is the stable user-facing handle. Async completion is represented by
`OpendalAio`, which carries completion state and result storage.

## Async and thread safety

Background work runs in a Rust Tokio runtime. Callbacks and completion paths do
not call into the R C API directly; this is intentional, so synchronization and
waiting are explicit on the R side (`call_aio()`, `collect_aio()`, `cv_wait()`,
`aio_monitor()`).

## Serialization and codecs pipeline

The package keeps bytes as the storage contract and applies optional transforms in
this order:

- serializer for R object/text materialization (`raw`, `text`, `serial`),
- optional native codec (`identity`, `gzip`, `zlib`),
- backend transport.

That means byte-level options remain explicit and inspectable in both sync and
async paths.

## Layer controls

Layer constructors are opt-in and composable:

- `runtime_config(threads = ...)`
- `layer_concurrent_limit(max = ...)`
- `layer_timeout(request_timeout = ..., io_timeout = ...)`

All are attached at handle construction so behavior is consistent per `OpendalFs`.

## API boundaries by function family

Public functions are split by surface, with async forms sharing the same shape as
sync forms where practical:

- filesystem operations: read/write/stat/exists/list/ls/delete/copy/rename/mkdir
- stream readers/writers: `fs_read_iter()`, `fs_write_iter()`
- monitors and collection: `collect_aio()`, `read_monitor()`, `aio_monitor()`

The C header mirrors this boundary as a separate pure-C API for downstream users
who need async bytes or completions without R-specific dependencies.
