Skip to content

android: add support for registering a platform KV store#2134

Merged
goaway merged 29 commits intomainfrom
ms/java-kv-store
May 17, 2022
Merged

android: add support for registering a platform KV store#2134
goaway merged 29 commits intomainfrom
ms/java-kv-store

Conversation

@goaway
Copy link
Contributor

@goaway goaway commented Mar 29, 2022

Description: This PR allows platform implementations of a generic (and potentially persistent) key-value store to be registered with the Engine. Internal components can look up these implementations by name. The internal implementation and wiring in this PR is platform agnostic, but this PR adds a public API for Java/Kotlin only, initially. iOS and other public APIs to follow in upcoming PRs.

Part of #2077.

Risk Level: Low
Testing: New Unit + Integration Coverage

Signed-off-by: Mike Schore mike.schore@gmail.com

goaway added 2 commits March 31, 2022 02:30
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
@goaway goaway force-pushed the ms/java-kv-store branch from bd5669e to a5c1612 Compare March 30, 2022 18:30
goaway added 9 commits April 4, 2022 20:17
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
@goaway goaway marked this pull request as ready for review April 13, 2022 10:40
@goaway goaway changed the title [wip] android: add support for registering a platform KV store android: add support for registering a platform KV store Apr 13, 2022
goaway added 4 commits April 21, 2022 17:55
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
@jpsim jpsim self-assigned this Apr 29, 2022
goaway added 7 commits May 6, 2022 01:41
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Copy link
Contributor

@RyanTheOptimist RyanTheOptimist left a comment

Choose a reason for hiding this comment

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

Nice! A few small comments. I think it would also be nice to flesh out the PR description to explain a bit more the details of what's going on.

namespace Envoy {
namespace Extensions {
namespace HttpFilters {
namespace TestKeyValueStore {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would have expected the name of this to be something like PlatformKeyValueStore. Is this filter intended to be used in production? Maybe it's just test-only?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Your presumption is correct - this is a test-only filter that exist alongside some other test-only filters in an entirely unintuitive location. Ideally, these should be moved elsewhere. I can certainly add a clarifying comment.

* Remove a value from the key value store implementation.
*
* @param key, key identifying the value to be removed.
* @return String, value mapped to the key, or null if not present.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Looks like this returns void?

* Save a value to the key value store implementation.
*
* @param key, key identifying the value to be saved.
* @param value, the value to be saved.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Looks like this returns void?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this it still outstanding.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry I may be being dense - what's the fix here? I fixed the @return for remove, but this method doesn't have one.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, shoot. You're right. I somehow totally misread this. :(

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All good - thanks for all the comments. :)


using TestKeyValueStoreFilterConfigSharedPtr = std::shared_ptr<TestKeyValueStoreFilterConfig>;

class TestKeyValueStoreFilter final : public ::Envoy::Http::PassThroughFilter {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Please add a comment which describes what this filter does.

envoy_data bridged_value = Data::Utility::copyToBridgeData(contents);
bridged_store_.save(bridged_key, bridged_value, bridged_store_.context);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I would have expected a remove() method. Is that not required?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@alyssawilk shared that you all didn't have a use case for it right now (which I sort of found surprising, but then again, if you supply the KV store implementation, you can always remove stuff from it elsewhere). I went ahead and wired remove at the other layers anyways, simply because I do expect we will have a use for it.

jobject j_context = static_cast<jobject>(const_cast<void*>(context));

jclass jcls_JvmKeyValueStoreContext = env->GetObjectClass(j_context);
jmethodID jmid_read = env->GetMethodID(jcls_JvmKeyValueStoreContext, "read", "([B)[B");
Copy link
Contributor

Choose a reason for hiding this comment

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

It's too bad there is no magic for auto-generating these method signature strings, but c'est la vie.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In fact, there is! ...but I never figured out how it might work with Bazel. But javac itself has support for generating jni headers based on native method signatures in class definitions in java.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, this is bound to bite us at some point. cxx.rs automatically generates these which helps avoid typos. If we start introducing Rust at this layer it would be worth considering using it for JNI codegen.

@RyanTheOptimist RyanTheOptimist self-assigned this May 13, 2022
@goaway
Copy link
Contributor Author

goaway commented May 16, 2022

Nice! A few small comments. I think it would also be nice to flesh out the PR description to explain a bit more the details of what's going on.

👍

goaway added 2 commits May 16, 2022 15:02
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
@goaway goaway requested a review from RyanTheOptimist May 16, 2022 07:06
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Copy link
Contributor

@RyanTheOptimist RyanTheOptimist left a comment

Choose a reason for hiding this comment

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

LGTM, modulo one nit.

* Save a value to the key value store implementation.
*
* @param key, key identifying the value to be saved.
* @param value, the value to be saved.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this it still outstanding.

/**
* Function signature for reading value from implementation.
*/
typedef envoy_data (*envoy_kv_store_read_f)(envoy_data key, const void* context);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason you went with a synchronous approach here? Is the idea that consumers would take care of moving this to a separate thread if they don't want to block on reading/writing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, for read asynchronous would introduce a whole new calling paradigm ("onRead"?). Honestly, I'd think an implementation should probably do caching/pre-caching/memoization if read performance is likely to be a bottleneck somewhere. For write/remove , yes, I think that's also better off as a feature of the actual provided platform implementation.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok. Another thing to consider is whether or not errors should be propagated between the platform and native layers.

/**
* Function signature for saving value to implementation.
*/
typedef void (*envoy_kv_store_save_f)(envoy_data key, envoy_data value, const void* context);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this document what's expected as the context pointer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a more general description to the root c_types.h, since we use these everywhere.

}

static void jvm_kv_store_remove(envoy_data key, const void* context) {
jni_log("[Envoy]", "jvm_store_remove");
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit:

Suggested change
jni_log("[Envoy]", "jvm_store_remove");
jni_log("[Envoy]", "jvm_kv_store_remove");

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, good catch.

<methods>;
}

-keep, includedescriptorclasses class io.envoyproxy.envoymobile.engine.JvmKeyValueStoreContext {
Copy link
Contributor

@jpsim jpsim May 16, 2022

Choose a reason for hiding this comment

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

How is this file updated? Asking so I know when/how to do this next time I touch the Java implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Manually, when a new JNI-facing class is added.

Signed-off-by: Mike Schore <mike.schore@gmail.com>
@jpsim
Copy link
Contributor

jpsim commented May 16, 2022

Can you please add a changelog entry for the user-facing change?

goaway added 2 commits May 17, 2022 04:50
Signed-off-by: Mike Schore <mike.schore@gmail.com>
Signed-off-by: Mike Schore <mike.schore@gmail.com>
@goaway goaway requested a review from jpsim May 16, 2022 20:53
// NOLINT(namespace-envoy)

/**
* Throughout this file one may note that most callbacks take a void* context parameter, and most
Copy link
Contributor

Choose a reason for hiding this comment

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

👌 excellent comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

:)

Copy link
Contributor

@jpsim jpsim left a comment

Choose a reason for hiding this comment

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

Nice work. Looking forward to seeing the default persistent kv store too.

@goaway goaway merged commit b309613 into main May 17, 2022
@goaway goaway deleted the ms/java-kv-store branch May 17, 2022 00:59
jpsim added a commit that referenced this pull request May 17, 2022
* origin/main:
  api: disallow setting 'host' header directly (#2275)
  android: add support for registering a platform KV store (#2134)
  Bump Lyft Support Rotation (#2278)

Signed-off-by: JP Simard <jp@jpsim.com>
jpsim added a commit that referenced this pull request May 17, 2022
…atcher-again

* main:
  envoy: update to d88f31b (#2279)
  api: disallow setting 'host' header directly (#2275)
  android: add support for registering a platform KV store (#2134)
  Bump Lyft Support Rotation (#2278)
  tools: Enable the VSCode completion db to use bazelisk if available (#2277)

Signed-off-by: JP Simard <jp@jpsim.com>
jpsim added a commit that referenced this pull request May 17, 2022
* origin/main: (97 commits)
  docs: update python packages to work with Python 3.10 (#2286)
  test: adding a cancel test, cleaning up copy-paste code (#2283)
  envoy: update to d88f31b (#2279)
  api: disallow setting 'host' header directly (#2275)
  android: add support for registering a platform KV store (#2134)
  Bump Lyft Support Rotation (#2278)
  tools: Enable the VSCode completion db to use bazelisk if available (#2277)
  Release v0.4.6.20220513-4
  Fix android_release_deploy
  Release v0.4.6.20220513-3
  Release v0.4.6.20220513-2
  net: enable happy eyeballs by default (#2272)
  git: avoid merge conflicts when adding changelog entries (#2273)
  docs: fix sphinx reference mismatch warning (#2274)
  tests: add -Xcheck:jni to kotlin integration tests by default (#2269)
  configuration: enable h2 ping by default (#2270)
  Add version history entries for user-facing changes (#2271)
  configuration: filter unroutable addresses on Android by default (#2267)
  Integrate rules_xcodeproj (#2263)
  Add assert when failing to get_env (#2253)
  ...

Signed-off-by: JP Simard <jp@jpsim.com>
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