Skip to content

KAFKA-7918: Inline generic parameters Pt. I: in-memory key-value store#6293

Merged
guozhangwang merged 4 commits intoapache:trunkfrom
ableegoldman:InlineByteStoreTypes
Feb 26, 2019
Merged

KAFKA-7918: Inline generic parameters Pt. I: in-memory key-value store#6293
guozhangwang merged 4 commits intoapache:trunkfrom
ableegoldman:InlineByteStoreTypes

Conversation

@ableegoldman
Copy link
Copy Markdown
Member

First PR in series to inline the generic parameters of the following bytes stores:

[x] InMemoryKeyValueStore
[ ] RocksDBWindowStore
[ ] RocksDBSessionStore
[ ] MemoryLRUCache
[ ] MemoryNavigableLRUCache
[ ] (awaiting merge) InMemoryWindowStore

A number of tests took advantage of the generic InMemoryKeyValueStore and had to be reworked somewhat -- this PR covers everything related to the in-memory key-value store.

Committer Checklist (excluded from commit message)

  • Verify design and implementation
  • Verify test coverage and CI build status
  • Verify documentation (including upgrade notes)

@ableegoldman
Copy link
Copy Markdown
Member Author

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I felt it was reasonable here to simply wrap a plain old Map with the required functionality, rather than take advantage of the KeyValueBytesStoreWrapper used elsewhere. This was largely to avoid having to write serdes for LRUCacheEntry, but if anyone feels strongly about it this test can be reworked to follow the others.

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 it's perfectly reasonable (and preferable) to use a simple map store so that we can more effectively isolate our testing concerns.

The only thing I'd add is that, even though it wasn't the intent of these other tests to exercise the bytes store, they did. So, we should make sure that the bytes store still has full coverage after these changes.

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.

For this specific test though, FilteredCacheIterator is only for the caching layer not for the underlying (in-memory) store layer.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I felt this was useful enough to pull out into a separate class, but perhaps this isn't the right place for it?

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.

It seems fine to me, although a more descriptive name wouldn't hurt.

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.

nit: we usually put such test util classes in src/test/o/a/k/test and packaged as o.a.k.test.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Serialization isn't done in the most efficient way, but within the scope of this test is quite sufficient.

@ableegoldman ableegoldman changed the title Inlined generic parameters Pt 1: in-memory key-value store KAFKA-7918: Inline generic parameters Pt. 1: in-memory key-value store Feb 20, 2019
Copy link
Copy Markdown
Contributor

@vvcephei vvcephei left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!

The change LGTM. The only concern I had was about the testing code. I'm wondering if we can eschew the new serialization wrapper store and just use your simpler KeyValueStoreWrapper implementation in the tests.

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.

Would it be possible to re-write the test not to need the set serde?

IIUC, the objective is just to make sure the reduce processor invokes add/subtract properly. Previously, it was convenient to use a Set to define this logic, but it's not so convenient anymore.

I don't have a problem with your implementation, it just seems like a huge chunk of code to do something we don't strictly need to do.

Alternatively, I just saw your KeyValueStoreWrapper below. You could make that store implementation available for all the tests that don't really need to test the bytes store logic. I think I'd prefer this approach.

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'd agree, adding a StringSetSerde seems like an overkill here to me. I'd suggest we just use String as value, and reduce function like v1+v2 (there are already some mock reducers in o.a.k.test) to separate the two values for easier validation.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If we extend the KeyValueStoreWrapper idea and extract it for use by all the tests we basically end up with a copy of the old generic InMemoryKeyValueStore, that we use just for testing. Maybe that is actually the cleanest way to do things given how different tests were relying on it for different things..?

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.

Personally, I think it is cleaner, since tests like this one get to focus more on the logic under test (the processor) and less on managing the state store layers just right, which should be the responsibility of other tests.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I also agree on the StringSetSerde is a little heavyweight.

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 it's perfectly reasonable (and preferable) to use a simple map store so that we can more effectively isolate our testing concerns.

The only thing I'd add is that, even though it wasn't the intent of these other tests to exercise the bytes store, they did. So, we should make sure that the bytes store still has full coverage after these changes.

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 I'd recommend renaming this to something more accurate (i.e., it's not a store wrapper), and elevating it to its own class so it's available for other tests.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need it for other tests? Seems to be very specific. I would rather make it private.

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.

👍 Either way. In another comment, I pointed out that other tests could be simplified by using this class instead of implementing a special serde and using the bytes store. In that case, it would be used by other tests and would need to be in its own class.

But, yes, if it stays in this test only, then it should be private.

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.

It seems fine to me, although a more descriptive name wouldn't hurt.

Copy link
Copy Markdown
Contributor

@guozhangwang guozhangwang left a comment

Choose a reason for hiding this comment

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

Left some very minor comments. Otherwise LGTM!

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.

nit: we usually put such test util classes in src/test/o/a/k/test and packaged as o.a.k.test.

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'd agree, adding a StringSetSerde seems like an overkill here to me. I'd suggest we just use String as value, and reduce function like v1+v2 (there are already some mock reducers in o.a.k.test) to separate the two values for easier validation.

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.

For this specific test though, FilteredCacheIterator is only for the caching layer not for the underlying (in-memory) store layer.

Copy link
Copy Markdown
Member

@mjsax mjsax left a comment

Choose a reason for hiding this comment

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

Thanks for the PR. Overall LGTM. Just some minor comments.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: fix indention

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: avoid empty lines

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need it for other tests? Seems to be very specific. I would rather make it private.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: break too long line into one parameter per line

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ack

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: we should call this wrapped (to unify our naming in the code base).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fair enough

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we should call stringSerde.close() and intSerde.close() here (in case we don't remove this code anyway)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as above

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as above

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: use { } (preferred code style for all blocks.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should call stringSerde.configure(...) and intSerde.configure(...) here (in case we don't remove this code anyway)

@bbejeck
Copy link
Copy Markdown
Member

bbejeck commented Feb 21, 2019

retest this please

Copy link
Copy Markdown
Member

@bbejeck bbejeck left a comment

Choose a reason for hiding this comment

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

Sorry for the late review, just one minor comment otherwise LGTM.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I also agree on the StringSetSerde is a little heavyweight.

@bbejeck
Copy link
Copy Markdown
Member

bbejeck commented Feb 22, 2019

Failures are related. Since the MockProcessorContextTest is in test-utils package it doesn't have visibility into streams test packages. Maybe we need to move it back to the original package you had it in? (MockProcessorContext itself is not in the test package I imagine for the same reason)

Copy link
Copy Markdown
Contributor

@guozhangwang guozhangwang left a comment

Choose a reason for hiding this comment

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

The current PR lgtm.

Regarding @bbejeck 's final comment about the packaging, I had a discussion with @ableegoldman and we think that a better way to keep code clean and also have small future updates is to modify the shouldStoreAndReturnStateStores test itself tot use a bytes inmemory store. And after we have KAFKA-6460 that we will have in the public APIs for those mock stores, we can then remove this class (the test-util mocks should be quite similar to this one) and let all its callers access that one.

@ableegoldman ableegoldman changed the title KAFKA-7918: Inline generic parameters Pt. 1: in-memory key-value store KAFKA-7918: Inline generic parameters Pt. I: in-memory key-value store Feb 26, 2019
@guozhangwang
Copy link
Copy Markdown
Contributor

retest this please

@guozhangwang guozhangwang merged commit 21b7963 into apache:trunk Feb 26, 2019
@guozhangwang
Copy link
Copy Markdown
Contributor

Merged to trunk, thanks @ableegoldman !

jarekr pushed a commit to confluentinc/kafka that referenced this pull request Apr 18, 2019
* AK/trunk: (36 commits)
  KAFKA-7962: Avoid NPE for StickyAssignor (apache#6308)
  Address flakiness of CustomQuotaCallbackTest#testCustomQuotaCallback (apache#6330)
  KAFKA-7918: Inline generic parameters Pt. II: RocksDB Bytes Store and Memory LRU Caches (apache#6327)
  MINOR: fix parameter naming (apache#6316)
  KAFKA-7956 In ShutdownableThread, immediately complete the shutdown if the thread has not been started (apache#6218)
  MINOR: Refactor replica log dir fetching for improved logging (apache#6313)
  [TRIVIAL] Remove unused StreamsGraphNode#repartitionRequired (apache#6227)
  MINOR: Increase produce timeout to 120 seconds (apache#6326)
  KAFKA-7918: Inline generic parameters Pt. I: in-memory key-value store (apache#6293)
  MINOR: Fix line break issue in upgrade notes (apache#6320)
  KAFKA-7972: Use automatic RPC generation in SaslHandshake
  MINOR: Enable capture of full stack trace in StreamTask#process (apache#6310)
  KAFKA-7938: Fix test flakiness in DeleteConsumerGroupsTest (apache#6312)
  KAFKA-7937: Fix Flaky Test ResetConsumerGroupOffsetTest.testResetOffsetsNotExistingGroup (apache#6311)
  MINOR: Update docs to say 2.2 (apache#6315)
  KAFKA-7672 : force write checkpoint during StreamTask #suspend (apache#6115)
  KAFKA-7961; Ignore assignment for un-subscribed partitions (apache#6304)
  KAFKA-7672: Restoring tasks need to be closed upon task suspension (apache#6113)
  KAFKA-7864; validate partitions are 0-based (apache#6246)
  KAFKA-7492 : Updated javadocs for aggregate and reduce methods returning null behavior. (apache#6285)
  ...
pengxiaolong pushed a commit to pengxiaolong/kafka that referenced this pull request Jun 14, 2019
apache#6293)

First PR in series to inline the generic parameters of the following bytes stores:

[x] InMemoryKeyValueStore
[ ] RocksDBWindowStore
[ ] RocksDBSessionStore
[ ] MemoryLRUCache
[ ] MemoryNavigableLRUCache
[ ] (awaiting merge) InMemoryWindowStore

A number of tests took advantage of the generic InMemoryKeyValueStore and had to be reworked somewhat -- this PR covers everything related to the in-memory key-value store.

Reviewers: Guozhang Wang <wangguoz@gmail.com>, Matthias J. Sax <mjsax@apache.org>,  John Roesler <john@confluent.io>, Bill Bejeck <bbejeck@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants