-
Notifications
You must be signed in to change notification settings - Fork 3
precomputed client #236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
precomputed client #236
Conversation
Add EppoPrecomputedClient for precomputed flag assignments computed server-side at the edge endpoint. Key features: - Subject-specific initialization (client bound to user at init time) - HTTP POST to edge endpoint: https://fs-edge-assignment.eppo.cloud/assignments - Obfuscation support with MD5 hashing and Base64 decoding - All assignment methods: string, boolean, integer, numeric, JSON, bandit - Offline mode with initialConfiguration for sync without network - Polling support for configuration updates - Assignment logging with deduplication via IAssignmentCache - Graceful mode for error handling New files: - DTOs: PrecomputedFlag, PrecomputedBandit, PrecomputedConfigurationResponse, BanditResult - Utilities: ObfuscationUtils (MD5 hashing) - Storage: PrecomputedCacheFile, PrecomputedConfigurationStore - Client: EppoPrecomputedClient with Builder pattern - Exception: MissingSubjectKeyException - Tests: Unit and instrumented tests
Add a new activity to the example app demonstrating the EppoPrecomputedClient. The new tab allows users to: - Initialize the precomputed client with a subject ID - Test different flag types (string, boolean, integer, numeric) - View assignment logs in real-time Files changed: - PrecomputedActivity.java: New activity for precomputed client demo - activity_precomputed.xml: Layout for the precomputed activity - MainActivity.java: Add button to launch precomputed activity - activity_main.xml: Add precomputed button to main layout - AndroidManifest.xml: Register PrecomputedActivity - strings.xml: Add new string resources
Use MD5 hash of subject key instead of safeCacheKey() to ensure consistent length and avoid StringIndexOutOfBoundsException when subject key is shorter than 8 characters.
- Add dynamic subject attributes table to PrecomputedActivity - Users can add/remove key-value pairs for subject attributes - Numeric values are automatically detected and typed correctly - Add HTTP request/response logging to EppoPrecomputedClient - Log request URL, payload, and detailed error messages
Both keys and values in bandit actionNumericAttributes and actionCategoricalAttributes are Base64 encoded in the server response.
- Update Makefile to fetch precomputed-v1.json test data - Add tests for all assignment types using sdk-test-data fixtures - Add bandit action tests - Tests validate string, boolean, integer, numeric, and JSON flags
Keep sdk-test-data tests for canonical evaluation behavior. Keep mock data tests only for SDK behavior: cache, lifecycle, validation, logging.
The extraLogging and metaData parameters were swapped, causing getMetaData() to return the wrong map and failing the test.
- Rename MainActivity to HomeActivity - Rename SecondActivity to StandardClientActivity - Add action bar back button to StandardClientActivity and PrecomputedActivity - Set parent activity for proper up navigation
β¦ctivity - Replace single Initialize button with "From Server" and "From Disk" buttons - From Server: fetches configuration from edge endpoint - From Disk: uses offline mode with cached configuration only - Update status messages to indicate initialization source
- Disable Get Assignment button until client is initialized - Update Clear Cache to also delete precomputed cache files - Show count of deleted precomputed caches in toast message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces a new EppoPrecomputedClient that solves Android ANR (Application Not Responding) issues during initialization for deployments with many flags and complex targeting rules. Instead of evaluating flags client-side, all assignments are computed server-side and delivered as a batch, providing instant O(1) lookups with zero evaluation time.
Changes:
- Implemented
EppoPrecomputedClientwith builder pattern matching existingEppoClientAPI style, supporting all flag types and bandit actions - Added supporting infrastructure including
PrecomputedConfigurationStorefor in-memory/disk caching,ObfuscationUtilsfor MD5 hashing, and related DTOs - Enhanced example app with new
PrecomputedActivitydemonstrating the precomputed client functionality
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
example/src/main/res/values/strings.xml |
Added string resource for launching precomputed client |
example/src/main/res/layout/activity_precomputed.xml |
New layout for precomputed client demo with subject attributes, flag type selection, and assignment logging |
example/src/main/res/layout/activity_home.xml |
Added button to launch precomputed activity |
example/src/main/java/cloud/eppo/androidexample/StandardClientActivity.java |
Renamed from SecondActivity and added back navigation support |
example/src/main/java/cloud/eppo/androidexample/PrecomputedActivity.java |
New activity demonstrating precomputed client with server/disk initialization options |
example/src/main/java/cloud/eppo/androidexample/HomeActivity.java |
Renamed from MainActivity, added precomputed activity launcher and cache clearing for precomputed clients |
example/src/main/AndroidManifest.xml |
Updated activity names and added parent activity declarations for back navigation |
eppo/src/test/java/cloud/eppo/android/PrecomputedConfigurationResponseTest.java |
Unit tests for precomputed configuration response deserialization |
eppo/src/test/java/cloud/eppo/android/ObfuscationUtilsTest.java |
Unit tests for MD5 hashing utility |
eppo/src/main/java/cloud/eppo/android/util/ObfuscationUtils.java |
Utility class for MD5 hashing used in flag key obfuscation |
eppo/src/main/java/cloud/eppo/android/exceptions/MissingSubjectKeyException.java |
New exception for missing subject key validation |
eppo/src/main/java/cloud/eppo/android/dto/PrecomputedFlag.java |
DTO for precomputed flag assignments with Base64-encoded fields |
eppo/src/main/java/cloud/eppo/android/dto/PrecomputedConfigurationResponse.java |
Wire protocol response from precomputed edge endpoint |
eppo/src/main/java/cloud/eppo/android/dto/PrecomputedBandit.java |
DTO for precomputed bandit assignments |
eppo/src/main/java/cloud/eppo/android/dto/BanditResult.java |
Return type for bandit action assignments |
eppo/src/main/java/cloud/eppo/android/PrecomputedConfigurationStore.java |
Configuration storage with disk caching |
eppo/src/main/java/cloud/eppo/android/PrecomputedCacheFile.java |
Disk cache file management for precomputed configuration |
eppo/src/main/java/cloud/eppo/android/EppoPrecomputedClient.java |
Main precomputed client implementation with assignment methods, logging, and polling |
eppo/src/androidTest/java/cloud/eppo/android/EppoPrecomputedClientTest.java |
Integration tests for precomputed client using test data |
Makefile |
Updated test data copying to include precomputed configuration files |
π‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import java.util.List; | ||
|
|
||
| /** | ||
| * Example activity demonstrating the EppoPrecomputedClient. The precomputed client computes all |
Copilot
AI
Jan 22, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'recieve' to 'receive' in class documentation.
| * Example activity demonstrating the EppoPrecomputedClient. The precomputed client computes all | |
| * Example activity demonstrating the EppoPrecomputedClient. The precomputed client receives all |
Eppo Internal:
ποΈ Fixes issue
π Design Doc: link if applicable
Motivation and Context
When using the standard client with very large flag deployments (many flags with complex targeting rules), the client-side evaluation during initialization can exceed Android's 5-second ANR (Application Not Responding) threshold. This creates a poor user experience with unresponsive apps on startup.
The Precomputed API solves this by:
Description
Core SDK Changes
New EppoPrecomputedClient - A new client optimized for precomputed assignments:
Supporting Classes:
How has this been documented?
Example App Improvements
How has this been tested?