Skip to content

StateDB: split write methods from Table into RWTable#28140

Merged
joamaki merged 4 commits intocilium:mainfrom
joamaki:pr/joamaki/statedb-rwtable
Oct 11, 2023
Merged

StateDB: split write methods from Table into RWTable#28140
joamaki merged 4 commits intocilium:mainfrom
joamaki:pr/joamaki/statedb-rwtable

Conversation

@joamaki
Copy link
Copy Markdown
Contributor

@joamaki joamaki commented Sep 13, 2023

  • Splits Table[Obj] into Table[Obj] (reader) and RWTable[Obj] (reader-writer) and adds
    NewProtectedTableCell. This allows modules to define protected tables where outside modules can only read from the table, or write to the table only in restricted/validated ways.
  • Moves RWTable[*Device] and RWTable[*Route] under the scope of the devices-controller module to protect the tables.

Open questions:

  • Is RWTable a good name? What about TableWriter? Should Table[Obj] be RTable[Obj] or TableReader[Obj]? WDYT?
  • WriteTxn still takes a TableMeta (from Table[Obj]). Reasoning is that we want to be able to construct a WriteTxn against multiple tables (for that cross-table atomic transaction sweetness) even when RWTable isn't directly available (but indirect smart writers are). An alternative I see to this is some sort of WriteTxnBuilder pattern to allow composing together the WriteTxn in a controlled way, e.g. a smart writer would take WriteTxnBuilder and then return (WriterHandle, WriteTxnBuilder). This way one explicitly asks for access to the writer methods, but I'm not sure if this boilerplate brings a lot of value. The downside of allowing WriteTxn with Table[Obj] is that arbitrary code can lock the table without intention or ability to write to it, but I would expect this to be easily catched by code review.

@maintainer-s-little-helper maintainer-s-little-helper bot added the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Sep 13, 2023
@joamaki joamaki force-pushed the pr/joamaki/statedb-rwtable branch from cfa64f2 to 692d641 Compare September 26, 2023 07:28
@joamaki joamaki force-pushed the pr/joamaki/statedb-rwtable branch from 692d641 to 1ef9845 Compare September 27, 2023 07:40
@joamaki joamaki added the release-note/misc This PR makes changes that have no direct user impact. label Sep 27, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot removed the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Sep 27, 2023
@joamaki joamaki changed the title [DRAFT] StateDB RWTable API StateDB: split write methods from Table into RWTable Sep 27, 2023
@joamaki joamaki marked this pull request as ready for review September 27, 2023 08:58
@joamaki joamaki requested review from a team as code owners September 27, 2023 08:58
@joamaki
Copy link
Copy Markdown
Contributor Author

joamaki commented Sep 27, 2023

/test

@joamaki joamaki requested review from bimmlerd and removed request for dylandreimerink September 27, 2023 08:58
Copy link
Copy Markdown
Member

@giorio94 giorio94 left a comment

Choose a reason for hiding this comment

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

The overall logic looks good to me, just a couple of minor comments inline.

Is RWTable a good name? What about TableWriter? Should Table[Obj] be RTable[Obj] or TableReader[Obj]? WDYT?

Personally, I like TableReader and TableReadWriter, but that's fairly verbose. RWTable and RTable also sound good to me (and seem more symmetric than just plain Table). The main issue with just TableWriter is that it actually also provides the read functionalities.

WriteTxn still takes a TableMeta (from Table[Obj]). Reasoning is that we want to be able to construct a WriteTxn against multiple tables (for that cross-table atomic transaction sweetness) even when RWTable isn't directly available (but indirect smart writers are). An alternative I see to this is some sort of WriteTxnBuilder pattern to allow composing together the WriteTxn in a controlled way, e.g. a smart writer would take WriteTxnBuilder and then return (WriterHandle, WriteTxnBuilder). This way one explicitly asks for access to the writer methods, but I'm not sure if this boilerplate brings a lot of value. The downside of allowing WriteTxn with Table[Obj] is that arbitrary code can lock the table without intention or ability to write to it, but I would expect this to be easily catched by code review.

I'm personally fine with keeping the current structure for the moment, and perhaps re-evaluate if more of such usages start to pop up. As you mentioned it seems pretty easy to catch incorrect creations of write transactions on read-only tables.

Copy link
Copy Markdown
Member

@bimmlerd bimmlerd left a comment

Choose a reason for hiding this comment

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

I'm afraid of the footgun in the DeleteTracker API.

@joamaki joamaki force-pushed the pr/joamaki/statedb-rwtable branch from 1ef9845 to 987fc7d Compare October 4, 2023 10:28
@joamaki joamaki requested review from bimmlerd and giorio94 October 4, 2023 10:29
@joamaki
Copy link
Copy Markdown
Contributor Author

joamaki commented Oct 4, 2023

/test

@joamaki joamaki force-pushed the pr/joamaki/statedb-rwtable branch from 987fc7d to ea9d30a Compare October 4, 2023 12:54
Copy link
Copy Markdown
Member

@bimmlerd bimmlerd left a comment

Choose a reason for hiding this comment

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

Yep I like this much better. Confused about the Delete semantics currently, other than that looks good!

@joamaki joamaki force-pushed the pr/joamaki/statedb-rwtable branch from ea9d30a to ad97b4e Compare October 9, 2023 08:03
@joamaki joamaki requested a review from bimmlerd October 9, 2023 08:03
Copy link
Copy Markdown
Member

@bimmlerd bimmlerd left a comment

Choose a reason for hiding this comment

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

two nits, after that I'm happy!

To allow control over where a table can be modified, split the Table[Obj]
interface into reader (Table[Obj]) and writer (RWTable[Obj]) parts.
RWTable[Obj] is a superset of Table[Obj], and can thus be used everywhere
where a Table[Obj] is required.

For convenience, implement NewProtectedTableCell() to provide the
RWTable[Obj] only in the hive module's scope, and Table[Obj] globally.

With this, the cell defining the table can choose to either not allow modifications
at all to the table (tests can still go via NewTable() to create a modifiable table),
or only allow modifications under very controller and validated ways.

Signed-off-by: Jussi Maki <[email protected]>

Refresh of statedb-split-write-methods
Make RWTable[*Device] and RWTable[*Route] private to the devices
controller to make sure they're not modified by anyone else.

The DeviceTableCell and RouteTableCell are still available in the
tables package for tests to use.

Signed-off-by: Jussi Maki <[email protected]>
These allow efficiently doing optimistic concurrency control in
cases where a long-running computation is performed against the
data and then results written back to a table, e.g.

 1. With ReadTxn compute results for each object (with revision number)
 2. With WriteTxn commit the results using CompareAndDelete. If the
    object has changed, the stale result for that object is ignored.
 3. Wait for changes and repeat

Signed-off-by: Jussi Maki <[email protected]>
Benchmark the delay and throughput for propagating changes from one table
to another. This simulates the expected use-case for statedb where we would
be reading from one or more tables and computing desired state that is written
to another table.

Results on my machine:
  goos: linux
  goarch: amd64
  pkg: github.com/cilium/cilium/pkg/statedb
  cpu: AMD Ryzen 9 5950X 16-Core Processor
  BenchmarkDB_PropagationDelay 	 224287	     5071 ns/op
  --- BENCH: BenchmarkDB_PropagationDelay
      benchmarks_test.go:349: Propagation delay (N: 224287) 50p: 37.12µs, 90p: 91.633µs, 99p: 123.924µs

On a single core, 197k objects per second with batch size of 10. For batch size of 1
I got 61k objects per second, so even small increase in batch size oversets the
cost of waiting for the watch channel to close. Propagating the batch
took ~123 microseconds (99 percentile).

Signed-off-by: Jussi Maki <[email protected]>
@joamaki joamaki force-pushed the pr/joamaki/statedb-rwtable branch from ad97b4e to 7763aad Compare October 10, 2023 12:47
@joamaki joamaki requested a review from bimmlerd October 10, 2023 12:47
@joamaki
Copy link
Copy Markdown
Contributor Author

joamaki commented Oct 10, 2023

/test

Copy link
Copy Markdown
Member

@dylandreimerink dylandreimerink left a comment

Choose a reason for hiding this comment

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

LGTM!

@maintainer-s-little-helper maintainer-s-little-helper bot added the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label Oct 11, 2023
@joamaki joamaki merged commit e677b96 into cilium:main Oct 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-note/misc This PR makes changes that have no direct user impact.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants