Skip to content

Chapter 3 Section 12: Resource Management First draft. - #79

Open
sofiabelen wants to merge 6 commits into
mainmatter:mainfrom
sofiabelen:chapter-3-section-12
Open

sofiabelen wants to merge 6 commits into
mainmatter:mainfrom
sofiabelen:chapter-3-section-12

Conversation

@sofiabelen

Copy link
Copy Markdown

No description provided.

@sofiabelen
sofiabelen force-pushed the chapter-3-section-12 branch 4 times, most recently from 1989ee9 to 95d147e Compare October 26, 2026 17:40
@sofiabelen

Copy link
Copy Markdown
Author

I left out a side note on move semantics/return value optimization as it seemed out of scope (but might be interesting to add):

Worried about performance? Moving a Store is a shallow copy of the struct
itself, so heap data isn't copied. Better still, the compiler typically
constructs the value directly in the caller's reserved stack slot.

@sofiabelen

Copy link
Copy Markdown
Author

I've also left out the part on struct field drop order. It optionally be added as a short remark:

Dropping the Store drops its fields in declaration order, unlike local
variables, which drop in reverse. That’s why Store lists journal first,
matching the order store_close releases things in C.

@sofiabelen
sofiabelen force-pushed the chapter-3-section-12 branch from 0f46055 to ef5e78c Compare October 27, 2026 12:13

@daxhuiberts daxhuiberts left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we almost have the right structure.
Fine tune that a little bit, and then we can focus on improving the text to be clearer and less LLMy.

Comment on lines +15 to +16
Our `Store` needs three resources: a data file, an index loaded from that file,
and a journal. Here is `open_store` in C:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain the purpose of open_store and what the intent is.

Comment on lines +3 to +11
Acquiring a resource, such as memory, a file, or a lock, comes with an
obligation to release it. When several are acquired in a row and each may depend
on the previous one, a failure partway through leaves some held and others
never acquired. Exactly the ones that are held must be released, so what needs
cleaning up depends on where the failure happened.

C leaves that bookkeeping to the programmer, who has to write it out for every
failure point. Rust makes it a question of ownership: whoever owns a value is
responsible for releasing it, and the compiler tracks who that is.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This intro is still a bit cryptic/LLMy. Can you clarify it a bit more.

Comment on lines +113 to +122
### RAII and `Drop`

*Resource Acquisition Is Initialization* (RAII) ties resource management to an
object's lifetime: allocate on initialization, deallocate on destruction.

A type can implement the `Drop` trait to specify what happens when a value
is dropped. A `File` closes its underlying file descriptor when it is dropped.
A value is dropped when its owner goes out of scope, which is what happens
on an early return. Local variables are dropped in reverse order of declaration,
so the cleanup happens automatically in the correct order.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the purpose of this section is good, but can use a clearer explanation.

Comment on lines +124 to +126
> **One caveat:** `drop` cannot return an error, so a failure during cleanup is
> silently ignored. If callers need to know about such failures, give the type
> an explicit close method that returns a `Result`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While true, let's skip this.

Comment on lines +128 to +162
## What happens on success?

On success, the C function returns `BM_OK` before reaching the labels, so the
resources stay open. The caller must close them later:

```c
void store_close(struct Store *store) {
journal_close(store->journal);
index_free(store->index);
fclose(store->file);
}
```

In Rust, returning transfers ownership of the resources to the caller:

```rust,no-run
Ok(Store { journal, index, file })
```

Putting `journal`, `index`, and `file` into the `Store` *moves* them. After a move,
the original variable no longer owns the value, so the function doesn't drop
those three locals when it returns. The `Store` owns them now, and `Ok(...)`
hands the `Store` to the caller.

This is the Rust counterpart of returning before the labels. Since a moved value
is never dropped by its old owner, it can never be dropped twice.

The resources then live as long as the caller's `Store` does:

```rust,no-run
{
let store = open_store(Path::new("bookmarks.db"))?;
// ... use `store` ...
} // `store` goes out of scope here: its fields are dropped
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is needed. Let's keep the focus on the 'replace goto with ? and drop'.

Comment on lines +109 to +111
When `Index::load` fails, `?` returns early and `file` is closed automatically.
When `Journal::open` fails, `index` and then `file` are released. But how does
that work behind the scenes?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is also important and possibly warrants it's own tiny section. ? early returns and thus has roughly the same effect as the goto.

@sofiabelen
sofiabelen force-pushed the chapter-3-section-12 branch 5 times, most recently from b5e6d8e to 7a6c1b5 Compare October 28, 2026 12:26
@sofiabelen
sofiabelen marked this pull request as ready for review November 5, 2026 22:18
@memark

memark commented Nov 10, 2026

Copy link
Copy Markdown
Member

@daxhuiberts Looks like most of your comments were addressed by new pushes. Could you briefly follow up?

@sofiabelen Could you please run dprint to fix the failing check?

@memark

memark commented Nov 10, 2026

Copy link
Copy Markdown
Member

@sofiabelen Sorry, but you need to redo the dprint. We merged some changes to main that alters the C code style.

…back to avoid duplicating code snippets, reduce noise in snippets, limit explanations of basic concepts and skip 'struct field order drop' as it's out of scope.
… removing the section on 'What happens on success?', clarifying some parts and reworking the example.
@sofiabelen

sofiabelen commented Nov 10, 2026 •

Copy link
Copy Markdown
Author

@sofiabelen Sorry, but you need to redo the dprint. We merged some changes to main that alters the C code style.

Done, should be good now : )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants