Skip to content

Conversation

@lukevalenta
Copy link
Contributor

@lukevalenta lukevalenta commented May 16, 2025

This PR contains quite a bit of refactoring of the pool logic in order to address #33. The most significant change is using a separate https://docs.rs/tokio/latest/tokio/sync/watch/index.html {Sender, Receiver} pair per entry instead of per "pool" of entries. This gives us the flexibility to break up pools of pending entries so we can hold back some entries when sequencing to try to prefer creating full tiles.

The commits can be reviewed independently and each have more detailed commit messages, although some of the commits remove or refactor code added in previous commits (e.g., the Pool struct).

  • 2af4060 Add ability to hold entries back from sequencing to reduce partial tiles
  • f9cc093 Use Vec::with_capacity where applicable, and pass owned PendingLogEntry to avoid clone
  • 3a0f655 Use one Sender per PendingLogEntry instead of per batch
  • 41ec703 Add PendingLogEntry struct to avoid overloading LogEntry
  • 7fce31e Merge Pool struct into PoolState
  • 143fd22 Add pool receiver directly to in_sequencing HashMap
  • 17261a8 Refactor pool logic

@lukevalenta lukevalenta self-assigned this May 16, 2025
@lukevalenta lukevalenta requested a review from cjpatton May 16, 2025 20:25
Base automatically changed from lvalenta/staging-do-storage to main May 19, 2025 13:23
@lukevalenta lukevalenta force-pushed the lvalenta/pool-cleanup branch from 0b55e86 to 56fdac7 Compare May 19, 2025 13:25
* Clean up AddLeafResult enum and add source() method to replace
  separate AddLeafResultSource enum
* Move majority of logic for add_leaf_to_pool to mthods of PoolState.
  This will allow us to more easily change how the pooling works in a
  future PR (e.g., #33).
* Remove pool_size parameter from configuration. It's never been useful
  to customize per log, so better to just make it a constant.
@lukevalenta lukevalenta force-pushed the lvalenta/pool-cleanup branch from 56fdac7 to d3932b9 Compare May 19, 2025 19:41
- Move Pool struct fields into PoolState, renaming by_hash to pending
  and done to pending_done.
- Add take() and reset() functions to PoolState to mutate state
- Rename pending_leaves -> pending_entries, sequence_pool ->
  sequence_entries
@lukevalenta lukevalenta force-pushed the lvalenta/pool-cleanup branch from d3932b9 to 8ff3f8e Compare May 19, 2025 23:28
PendingLogEntry contains all of the fields of LogEntry except for the leaf index and timestamp.
@lukevalenta lukevalenta marked this pull request as draft May 20, 2025 00:22
@lukevalenta lukevalenta force-pushed the lvalenta/pool-cleanup branch from 8ff3f8e to 4568c22 Compare May 20, 2025 17:22
Instead of using a Sender per pool of entries, allocate one Sender per
pending entry. This is slightly less efficient as we're creating more
channels, but gives much more flexibility for how we handle individual
entries. More thorough benchmarking is needed, but from some quick tests
there was no noticeable difference. This change also allows us to stop
tracking the 'pool_index' of each log entry, and just transmit the final
index on each entry's channel.

This refactor will make it easier to only select a subset of the pending
entries each time sequencing occurs, so we can try to keep the tree as a
multiple of the full tile width (256), so we create fewer partial data
and level-0 tiles (#33).
@lukevalenta lukevalenta force-pushed the lvalenta/pool-cleanup branch from 07b1cc1 to ccc52f0 Compare May 20, 2025 20:13
Add parameter specifying the maximum number of times a pending entry
might be held back to prefer creating full tiles instead of partial
tiles. fixes #33

This change required moving the logic to load the SequenceState from the
sequence_entries function to the wrapping sequence function, and
updating tests accordingly.
@lukevalenta lukevalenta force-pushed the lvalenta/pool-cleanup branch from ccc52f0 to 2af4060 Compare May 20, 2025 20:22
@lukevalenta lukevalenta marked this pull request as ready for review May 20, 2025 20:25
Copy link
Contributor

@rozbb rozbb left a comment

Choose a reason for hiding this comment

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

Looks good! Just some small notes

// Flush all of the leftover entries if the oldest is before the cutoff.
let flush_oldest = self.holds >= max_pending_entry_holds;

if leftover == 0 || flush_oldest {
Copy link
Contributor

Choose a reason for hiding this comment

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

So if flush_oldest is triggered when there's 1.5 tiles pending, we'll publish 1.5 files? Why not just publish a full one and hold back the half?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, that's what will currently happen, unless max_pending_entry_holds = 0, in which case we always flush the oldest (which is the previous behavior before this PR).

This test demonstrates that behavior: https://github.com/cloudflare/azul/pull/38/files#diff-04abdf856a7b917bbd1ca592d4f3026c5f36bd03afcc4928103cf5a58143670bR1509.

@lukevalenta lukevalenta merged commit c5388c9 into main May 21, 2025
1 check passed
@lukevalenta lukevalenta deleted the lvalenta/pool-cleanup branch May 21, 2025 17:43
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.

2 participants