-
-
Notifications
You must be signed in to change notification settings - Fork 171
Improve Project Caching and Invalidation Consistency #1600
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
Conversation
WalkthroughIntroduces a new ProjectCache abstraction (ID-keyed primary cache + API-key → ID index), wires eviction callbacks into LRUWithExpires, updates Mongo client to use ProjectCache and change cache invalidation to accept keys slice (IDs), and updates RPC server to broadcast invalidation using project IDs. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Admin as Admin RPC
participant Client as Mongo Client
participant PC as ProjectCache
participant LRU as LRUWithExpires
participant DB as MongoDB
Note over Admin,Client: Find by API key flow
Admin->>Client: FindProjectInfoByPublicKey(apiKey)
Client->>PC: GetByAPIKey(apiKey)
PC->>PC: resolve id from apiKey index (sync.Map)
alt id found
PC->>LRU: Get(id)
alt hit
LRU-->>PC: projectInfo
PC-->>Client: projectInfo (cached)
else miss
PC->>DB: fetch by id
DB-->>PC: projectInfo
PC->>LRU: Add(id, deepCopy(projectInfo))
PC-->>Client: projectInfo
end
else id missing
PC-->>Client: not found
end
sequenceDiagram
autonumber
participant Admin as Admin RPC
participant Broad as Broadcaster
participant Client as Mongo Client
participant PC as ProjectCache
participant LRU as LRUWithExpires
Note over Admin,Client: Invalidate by project ID flow
Admin->>Broad: BroadcastCacheInvalidation(cacheType, [projectID])
Broad->>Client: InvalidateCache(cacheType, [projectID])
Client->>PC: Remove(projectID)
PC->>LRU: Remove(projectID)
LRU-->>PC: evict callback (key, value)
PC->>PC: delete apiKey -> id mapping
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
api/yorkie/v1/admin.pb.gois excluded by!**/*.pb.goapi/yorkie/v1/cluster.pb.gois excluded by!**/*.pb.goapi/yorkie/v1/resources.pb.gois excluded by!**/*.pb.goapi/yorkie/v1/yorkie.pb.gois excluded by!**/*.pb.go
📒 Files selected for processing (7)
api/docs/yorkie/v1/cluster.openapi.yaml(1 hunks)api/yorkie/v1/cluster.proto(1 hunks)cluster/client.go(1 hunks)server/backend/backend.go(2 hunks)server/backend/database/mongo/client.go(11 hunks)server/rpc/admin_server.go(2 hunks)server/rpc/cluster_server.go(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ggyuchive
Repo: yorkie-team/yorkie PR: 1463
File: server/backend/database/mongo/client.go:1220-1247
Timestamp: 2025-08-23T15:34:38.056Z
Learning: In the Yorkie MongoDB database client, there's an inconsistency in "removed_at" filtering: FindDocInfosByKeys excludes removed documents with "removed_at": {"$exists": false}, but FindDocInfoByRefKey and FindDocInfosByIDs do not apply this filter, only checking project_id and document ID criteria.
🧬 Code graph analysis (2)
server/rpc/admin_server.go (3)
api/types/id.go (1)
ID(37-37)pkg/document/change/id.go (1)
ID(26-48)pkg/document/crdt/primitive.go (1)
String(40-40)
cluster/client.go (3)
api/yorkie/v1/cluster.pb.go (7)
InvalidateCacheRequest(611-617)InvalidateCacheRequest(630-630)InvalidateCacheRequest(645-647)CacheType(39-39)CacheType(74-76)CacheType(78-80)CacheType(87-89)api/types/cache_type.go (1)
CacheType(20-20)api/converter/to_pb.go (1)
ToCacheType(741-753)
🔇 Additional comments (11)
api/docs/yorkie/v1/cluster.openapi.yaml (1)
639-645: LGTM!The OpenAPI schema correctly reflects the proto change from a single
keystring to an array ofkeysstrings. The schema definition is properly structured withtype: arrayanditems: { type: string }.server/rpc/cluster_server.go (1)
290-290: LGTM!The change correctly uses
req.Msg.Keys(plural) to align with the updated proto definition, passing multiple keys to the MongoDB client's InvalidateCache method.server/rpc/admin_server.go (2)
242-242: LGTM!The broadcast cache invalidation correctly passes both the project's
PublicKeyandIDas a slice, ensuring both cache indices are invalidated when a project is updated.
820-820: LGTM!The broadcast cache invalidation correctly passes both the previous project's
PublicKeyandIDas a slice, ensuring both cache indices are invalidated when project keys are rotated.server/backend/backend.go (1)
295-322: LGTM!The method signature correctly updated to accept multiple keys (
keys []string), and the implementation properly propagates these keys to each cluster node's InvalidateCache call. The error handling and control flow remain intact.cluster/client.go (1)
235-241: LGTM!The method signature and request construction correctly updated to handle multiple keys. The change from
Key: keytoKeys: keysaligns with the proto definition update.server/backend/database/mongo/client.go (4)
108-126: LGTM!The dual cache initialization is well-structured. Both
projectCacheByAPIKeyandprojectCacheByIDare properly configured with the same size and TTL, and both are registered with the cache manager. The naming clearly distinguishes the two cache indices.
602-604: LGTM!After fetching project info by public key, the code correctly populates both cache indices (
projectCacheByAPIKeyandprojectCacheByID). This ensures subsequent lookups by either key will hit the cache.
668-670: LGTM!After fetching project info by ID, the code correctly populates both cache indices (
projectCacheByIDandprojectCacheByAPIKey). This ensures subsequent lookups by either key will hit the cache.
728-733: LGTM!The cache invalidation logic correctly removes entries from both cache indices using the previous project info before updating the keys. This ensures the old keys are properly invalidated.
api/yorkie/v1/cluster.proto (1)
95-95: This is a new RPC method, not a breaking change.
InvalidateCacheis a newly added RPC method (as documented in the CHANGELOG) designed withrepeated string keysfrom the start. There is no existing single-key API being modified, so backward compatibility concerns do not apply. The implementation across the proto definition, generated Go code, server handler, and client is consistently aligned for supporting multiple cache keys.
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.
Go Benchmark Analysis 📊
This is a comparison result between the previous(e816a17) and the current commit(2ec8ce2).
Significant Changes (≥20% difference)
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| BenchmarkRPC/client_to_client_via_server/ (ns/op) | 1.17 s | 155.78 ms | 🟢 -86.69% |
| BenchmarkRPC/client_to_client_via_server/ (B/op) | 26.39 MB | 39.44 MB | 🔴 +49.43% |
| BenchmarkRPC/client_to_client_via_server/ (allocs/op) | 236,365 allocs | 481,418 allocs | 🔴 +103.68% |
| BenchmarkRPC/attach_large_document/ (allocs/op) | 98,011 allocs | 159,035 allocs | 🔴 +62.26% |
| BenchmarkChannelAttachDetach/attach-detach-10/ (ns/op) | 20.45 ms | 12.06 ms | 🟢 -41.02% |
| BenchmarkChannelAttachDetach/attach-detach-10/ (allocs/op) | 19,534 allocs | 13,708 allocs | 🟢 -29.82% |
| BenchmarkChannelAttachDetach/attach-detach-50/ (ns/op) | 101.20 ms | 59.02 ms | 🟢 -41.67% |
| BenchmarkChannelAttachDetach/attach-detach-50/ (allocs/op) | 96,979 allocs | 67,663 allocs | 🟢 -30.23% |
| BenchmarkChannelAttachDetach/attach-detach-250/ (ns/op) | 512.91 ms | 285.29 ms | 🟢 -44.38% |
| BenchmarkChannelAttachDetach/attach-detach-250/ (allocs/op) | 485,706 allocs | 338,875 allocs | 🟢 -30.23% |
| BenchmarkVersionVector/clients_100/ (3_pushpull(ms)) | 4.00 ms | 3.00 ms | 🟢 -25.00% |
| BenchmarkVersionVector/clients_100/ (4_attach(ms)) | 4.00 ms | 3.00 ms | 🟢 -25.00% |
| BenchmarkVersionVector/clients_1000/ (7_pushpull_after_detach(ms)) | 3.00 ms | 9.00 ms | 🔴 +200.00% |
Key Observations 🔍
- The
BenchmarkRPC/client_to_client_via_server/benchmark suite showed significant improvements in performance across various metrics:- The duration decreased from 1.17 s to 155.78 ms, representing a substantial improvement of -86.69%.
- The number of allocations (allocs/op) increased by 103.68%, indicating potentially higher resource usage.
- The
BenchmarkChannelAttachDetach/suite exhibited consistent performance gains:- Across different scenarios for
attach-detach, improvements in the range of -29.82% to -44.38% were observed for both nanoseconds per operation and allocations per operation.
- Across different scenarios for
- The
BenchmarkVersionVector/clients_1000/test experienced a notable increase in duration by +200.00%, from 3.00 ms to 9.00 ms for the 7_pushpull_after_detach operation. - Overall, the benchmark data showed a mix of performance improvements and slight regressions across different test scenarios. The most significant changes were observed in the RPC and ChannelAttachDetach benchmark suites, with noticeable trends in performance metrics.
Clock Analysis
Lamport vs VersionVector
BenchmarkVersionVector Test
Lamport (v0.5.2)
| Metric | 10 clients | 100 clients | 1000 clients |
|---|---|---|---|
| Total Operation Time | 84.96 ms | 793.94 ms | 34.79 s |
| Memory Allocations | 35.11 MB | 219.92 MB | 4.91 GB |
| Number of Allocations (allocs/op) | 69,271 | 1,246,728 | 81,485,288 |
| ChangePack Size | 138.0 B | 137.0 B | 141.0 B |
| Snapshot Size | 379.0 B | 3.08 KB | 30.08 KB |
| Push-Pull Time | 2.0 ms | 1.5 ms | 4.0 ms |
| Attach Time | 4.5 ms | 11.0 ms | 31.0 ms |
| ChangePack After Detach | 138.0 B | 140.0 B | 141.0 B |
| Snapshot After Detach | 136.0 B | 137.0 B | 139.0 B |
| Push-Pull After Detach | 2.5 ms | 5.0 ms | 9.5 ms |
Version Vector (current)
| Metric | 10 clients | 100 clients | 1000 clients |
|---|---|---|---|
| Total Operation Time | 86.77 ms | 713.13 ms | 9.13 s |
| Memory Allocations | 6.91 MB | 58.76 MB | 1.39 GB |
| Number of Allocations (allocs/op) | 57,238 | 577,744 | 17,708,362 |
| ChangePack Size | 186.00 B | 185.00 B | 186.00 B |
| Snapshot Size | 399.00 B | 3.10 KB | 30.10 KB |
| Push-Pull Time | 3.00 ms | 3.00 ms | 3.00 ms |
| Attach Time | 3.00 ms | 3.00 ms | 6.00 ms |
| ChangePack After Detach | 231.00 B | 231.00 B | 231.00 B |
| Snapshot After Detach | 156.00 B | 156.00 B | 156.00 B |
| Push-Pull After Detach | 3.00 ms | 3.00 ms | 9.00 ms |
BenchmarkSyncConcurrency Test
| Metric | Clients | Lamport (v0.5.2) | Version Vector (current) |
|---|---|---|---|
| Total Operation Time | 1-100-10-10 | 7.48 s | 7.59 s |
| 100-100-10-10 | 9.62 s | 8.42 s | |
| 300_100-10-10 | 14.77 s | 10.14 s | |
| Memory Allocations | 1-100-10-10 | 1.15 GB | 4.14 GB |
| 100-100-10-10 | 1.45 GB | 4.20 GB | |
| 300_100-10-10 | 2.19 GB | 4.39 GB | |
| Number of Allocations (allocs/op) | 1-100-10-10 | 17,107,766 | 106,022,123 |
| 100-100-10-10 | 20,084,480 | 106,770,997 | |
| 300_100-10-10 | 30,359,215 | 108,918,148 |
Summary
-
Based on the BenchmarkVersionVector results, the Version Vector clock system shows improved performance compared to Lamport across different client loads. It exhibits reduced total operation time, memory allocations, and number of allocations per operation as the number of clients increases. Additionally, the Version Vector system maintains consistent sizes for change pack, snapshot, and maintains stable times for push-pull operations.
-
In the BenchmarkSyncConcurrency test, the Version Vector clock system consistently outperforms Lamport in terms of total operation time and memory allocations across various client scenarios. The Version Vector system shows better scalability and efficiency, handling concurrency more effectively with lower memory consumption and faster operation times.
Detailed Test Results
BenchmarkDeactivate
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| deactivate_with_100_total_50_attached/ (ns/op) | 92.18 ms | 87.83 ms | 🟢 -4.71% |
| deactivate_with_100_total_50_attached/ (B/op) | 11.69 MB | 11.52 MB | 🟢 -1.45% |
| deactivate_with_100_total_50_attached/ (allocs/op) | 137,785 allocs | 136,780 allocs | 🟢 -0.73% |
| deactivate_with_100_total_100_attached/ (ns/op) | 184.21 ms | 187.95 ms | 🔴 +2.03% |
| deactivate_with_100_total_100_attached/ (B/op) | 21.27 MB | 20.67 MB | 🟢 -2.83% |
| deactivate_with_100_total_100_attached/ (allocs/op) | 279,094 allocs | 275,245 allocs | 🟢 -1.38% |
BenchmarkDeletionConcurrency
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| concurrent_text_delete_range_100/ (ns/op) | 582.71 ms | 483.86 ms | 🟢 -16.96% |
| concurrent_text_delete_range_100/ (B/op) | 61.09 MB | 60.76 MB | 🟢 -0.53% |
| concurrent_text_delete_range_100/ (allocs/op) | 679,423 allocs | 620,660 allocs | 🟢 -8.65% |
| concurrent_text_delete_range_1000/ (ns/op) | 4.73 s | 3.95 s | 🟢 -16.52% |
| concurrent_text_delete_range_1000/ (B/op) | 394.95 MB | 346.37 MB | 🟢 -12.30% |
| concurrent_text_delete_range_1000/ (allocs/op) | 6,385,948 allocs | 5,881,993 allocs | 🟢 -7.89% |
| concurrent_tree_delete_range_100/ (ns/op) | 583.25 ms | 491.51 ms | 🟢 -15.73% |
| concurrent_tree_delete_range_100/ (B/op) | 67.83 MB | 62.54 MB | 🟢 -7.80% |
| concurrent_tree_delete_range_100/ (allocs/op) | 712,794 allocs | 655,098 allocs | 🟢 -8.09% |
| concurrent_tree_delete_range_1000/ (ns/op) | 5.18 s | 4.39 s | 🟢 -15.31% |
| concurrent_tree_delete_range_1000/ (B/op) | 887.56 MB | 839.80 MB | 🟢 -5.38% |
| concurrent_tree_delete_range_1000/ (allocs/op) | 6,718,623 allocs | 6,256,072 allocs | 🟢 -6.88% |
| concurrent_text_edit_delete_all_100/ (ns/op) | 505.80 ms | 416.58 ms | 🟢 -17.64% |
| concurrent_text_edit_delete_all_100/ (B/op) | 52.26 MB | 46.79 MB | 🟢 -10.47% |
| concurrent_text_edit_delete_all_100/ (allocs/op) | 561,014 allocs | 513,275 allocs | 🟢 -8.51% |
| concurrent_text_edit_delete_all_1000/ (ns/op) | 3.94 s | 3.28 s | 🟢 -16.74% |
| concurrent_text_edit_delete_all_1000/ (B/op) | 338.41 MB | 307.23 MB | 🟢 -9.22% |
| concurrent_text_edit_delete_all_1000/ (allocs/op) | 5,195,762 allocs | 4,813,183 allocs | 🟢 -7.36% |
| concurrent_tree_edit_delete_all_100/ (ns/op) | 511.88 ms | 427.88 ms | 🟢 -16.41% |
| concurrent_tree_edit_delete_all_100/ (B/op) | 56.89 MB | 55.93 MB | 🟢 -1.69% |
| concurrent_tree_edit_delete_all_100/ (allocs/op) | 612,376 allocs | 566,919 allocs | 🟢 -7.42% |
| concurrent_tree_edit_delete_all_1000/ (ns/op) | 4.35 s | 3.65 s | 🟢 -16.25% |
| concurrent_tree_edit_delete_all_1000/ (B/op) | 706.87 MB | 673.06 MB | 🟢 -4.78% |
| concurrent_tree_edit_delete_all_1000/ (allocs/op) | 5,670,916 allocs | 5,283,092 allocs | 🟢 -6.84% |
BenchmarkDocument
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| constructor_test/ (ns/op) | 1327.00 ns | 1264.00 ns | 🟢 -4.75% |
| constructor_test/ (B/op) | 1.27 KB | 1.27 KB | ⚪ 0% |
| constructor_test/ (allocs/op) | 22 allocs | 22 allocs | ⚪ 0% |
| status_test/ (ns/op) | 942.90 ns | 901.50 ns | 🟢 -4.39% |
| status_test/ (B/op) | 1.24 KB | 1.24 KB | ⚪ 0% |
| status_test/ (allocs/op) | 20 allocs | 20 allocs | ⚪ 0% |
| equals_test/ (ns/op) | 7532.00 ns | 7291.00 ns | 🟢 -3.20% |
| equals_test/ (B/op) | 7.40 KB | 7.40 KB | ⚪ 0% |
| equals_test/ (allocs/op) | 124 allocs | 124 allocs | ⚪ 0% |
| nested_update_test/ (ns/op) | 17219.00 ns | 16509.00 ns | 🟢 -4.12% |
| nested_update_test/ (B/op) | 12.57 KB | 12.57 KB | ⚪ 0% |
| nested_update_test/ (allocs/op) | 267 allocs | 267 allocs | ⚪ 0% |
| delete_test/ (ns/op) | 22948.00 ns | 22111.00 ns | 🟢 -3.65% |
| delete_test/ (B/op) | 16.07 KB | 16.07 KB | ⚪ 0% |
| delete_test/ (allocs/op) | 345 allocs | 345 allocs | ⚪ 0% |
| object_test/ (ns/op) | 8587.00 ns | 8314.00 ns | 🟢 -3.18% |
| object_test/ (B/op) | 7.14 KB | 7.14 KB | ⚪ 0% |
| object_test/ (allocs/op) | 119 allocs | 119 allocs | ⚪ 0% |
| array_test/ (ns/op) | 28518.00 ns | 27485.00 ns | 🟢 -3.62% |
| array_test/ (B/op) | 12.35 KB | 12.35 KB | ⚪ 0% |
| array_test/ (allocs/op) | 278 allocs | 278 allocs | ⚪ 0% |
| text_test/ (ns/op) | 31994.00 ns | 31030.00 ns | 🟢 -3.01% |
| text_test/ (B/op) | 15.00 KB | 15.00 KB | ⚪ 0% |
| text_test/ (allocs/op) | 496 allocs | 496 allocs | ⚪ 0% |
| text_composition_test/ (ns/op) | 30617.00 ns | 30275.00 ns | 🟢 -1.12% |
| text_composition_test/ (B/op) | 16.65 KB | 16.65 KB | ⚪ 0% |
| text_composition_test/ (allocs/op) | 488 allocs | 488 allocs | ⚪ 0% |
| rich_text_test/ (ns/op) | 85333.00 ns | 82579.00 ns | 🟢 -3.23% |
| rich_text_test/ (B/op) | 38.13 KB | 38.12 KB | ⚪ 0% |
| rich_text_test/ (allocs/op) | 1,172 allocs | 1,172 allocs | ⚪ 0% |
| counter_test/ (ns/op) | 17301.00 ns | 16542.00 ns | 🟢 -4.39% |
| counter_test/ (B/op) | 11.98 KB | 11.98 KB | ⚪ 0% |
| counter_test/ (allocs/op) | 243 allocs | 243 allocs | ⚪ 0% |
| text_edit_gc_100/ (ns/op) | 1.44 ms | 1.38 ms | 🟢 -4.48% |
| text_edit_gc_100/ (B/op) | 803.50 KB | 803.49 KB | ⚪ 0% |
| text_edit_gc_100/ (allocs/op) | 16,876 allocs | 16,876 allocs | ⚪ 0% |
| text_edit_gc_1000/ (ns/op) | 55.65 ms | 54.55 ms | 🟢 -1.97% |
| text_edit_gc_1000/ (B/op) | 46.24 MB | 46.24 MB | ⚪ 0% |
| text_edit_gc_1000/ (allocs/op) | 181,568 allocs | 181,562 allocs | ⚪ 0% |
| text_split_gc_100/ (ns/op) | 2.18 ms | 2.11 ms | 🟢 -3.48% |
| text_split_gc_100/ (B/op) | 1.53 MB | 1.53 MB | ⚪ 0% |
| text_split_gc_100/ (allocs/op) | 15,545 allocs | 15,545 allocs | ⚪ 0% |
| text_split_gc_1000/ (ns/op) | 137.80 ms | 132.98 ms | 🟢 -3.50% |
| text_split_gc_1000/ (B/op) | 137.25 MB | 137.25 MB | ⚪ 0% |
| text_split_gc_1000/ (allocs/op) | 181,014 allocs | 181,012 allocs | ⚪ 0% |
| text_100/ (ns/op) | 231812.00 ns | 225548.00 ns | 🟢 -2.70% |
| text_100/ (B/op) | 112.97 KB | 112.97 KB | ⚪ 0% |
| text_100/ (allocs/op) | 4,980 allocs | 4,980 allocs | ⚪ 0% |
| text_1000/ (ns/op) | 2.45 ms | 2.53 ms | 🔴 +3.63% |
| text_1000/ (B/op) | 1.08 MB | 1.08 MB | ⚪ 0% |
| text_1000/ (allocs/op) | 49,083 allocs | 49,083 allocs | ⚪ 0% |
| array_1000/ (ns/op) | 1.29 ms | 1.27 ms | 🟢 -1.61% |
| array_1000/ (B/op) | 1.09 MB | 1.09 MB | ⚪ 0% |
| array_1000/ (allocs/op) | 13,819 allocs | 13,819 allocs | ⚪ 0% |
| array_10000/ (ns/op) | 13.84 ms | 13.68 ms | 🟢 -1.14% |
| array_10000/ (B/op) | 10.15 MB | 10.15 MB | ⚪ 0% |
| array_10000/ (allocs/op) | 140,064 allocs | 140,064 allocs | ⚪ 0% |
| array_gc_100/ (ns/op) | 135709.00 ns | 129478.00 ns | 🟢 -4.59% |
| array_gc_100/ (B/op) | 99.30 KB | 99.30 KB | ⚪ 0% |
| array_gc_100/ (allocs/op) | 1,464 allocs | 1,464 allocs | ⚪ 0% |
| array_gc_1000/ (ns/op) | 1.49 ms | 1.44 ms | 🟢 -3.22% |
| array_gc_1000/ (B/op) | 1.14 MB | 1.14 MB | ⚪ 0% |
| array_gc_1000/ (allocs/op) | 14,863 allocs | 14,863 allocs | ⚪ 0% |
| counter_1000/ (ns/op) | 195418.00 ns | 188823.00 ns | 🟢 -3.37% |
| counter_1000/ (B/op) | 194.11 KB | 194.11 KB | ⚪ 0% |
| counter_1000/ (allocs/op) | 5,768 allocs | 5,768 allocs | ⚪ 0% |
| counter_10000/ (ns/op) | 2.10 ms | 2.06 ms | 🟢 -1.76% |
| counter_10000/ (B/op) | 2.23 MB | 2.23 MB | ⚪ 0% |
| counter_10000/ (allocs/op) | 59,775 allocs | 59,775 allocs | ⚪ 0% |
| object_1000/ (ns/op) | 1.59 ms | 1.54 ms | 🟢 -3.03% |
| object_1000/ (B/op) | 1.41 MB | 1.41 MB | ⚪ 0% |
| object_1000/ (allocs/op) | 11,826 allocs | 11,826 allocs | ⚪ 0% |
| object_10000/ (ns/op) | 16.56 ms | 16.73 ms | 🔴 +1.01% |
| object_10000/ (B/op) | 12.54 MB | 12.54 MB | ⚪ 0% |
| object_10000/ (allocs/op) | 120,190 allocs | 120,190 allocs | ⚪ 0% |
| tree_100/ (ns/op) | 671800.00 ns | 655431.00 ns | 🟢 -2.44% |
| tree_100/ (B/op) | 529.38 KB | 529.38 KB | ⚪ 0% |
| tree_100/ (allocs/op) | 5,017 allocs | 5,017 allocs | ⚪ 0% |
| tree_1000/ (ns/op) | 42.38 ms | 40.98 ms | 🟢 -3.30% |
| tree_1000/ (B/op) | 43.79 MB | 43.79 MB | ⚪ 0% |
| tree_1000/ (allocs/op) | 49,142 allocs | 49,142 allocs | ⚪ 0% |
| tree_10000/ (ns/op) | 4.45 s | 4.48 s | 🔴 +0.63% |
| tree_10000/ (B/op) | 4.30 GB | 4.30 GB | ⚪ 0% |
| tree_10000/ (allocs/op) | 491,050 allocs | 491,051 allocs | ⚪ 0% |
| tree_edit_gc_100/ (ns/op) | 2.94 ms | 3.01 ms | 🔴 +2.54% |
| tree_edit_gc_100/ (B/op) | 2.41 MB | 2.41 MB | ⚪ 0% |
| tree_edit_gc_100/ (allocs/op) | 22,762 allocs | 22,762 allocs | ⚪ 0% |
| tree_edit_gc_1000/ (ns/op) | 242.16 ms | 239.13 ms | 🟢 -1.25% |
| tree_edit_gc_1000/ (B/op) | 215.03 MB | 215.03 MB | ⚪ 0% |
| tree_edit_gc_1000/ (allocs/op) | 1,127,170 allocs | 1,127,172 allocs | ⚪ 0% |
| tree_split_gc_100/ (ns/op) | 2.54 ms | 2.48 ms | 🟢 -2.31% |
| tree_split_gc_100/ (B/op) | 1.68 MB | 1.68 MB | ⚪ 0% |
| tree_split_gc_100/ (allocs/op) | 20,737 allocs | 20,737 allocs | ⚪ 0% |
| tree_split_gc_1000/ (ns/op) | 198.64 ms | 193.47 ms | 🟢 -2.60% |
| tree_split_gc_1000/ (B/op) | 157.34 MB | 157.34 MB | ⚪ 0% |
| tree_split_gc_1000/ (allocs/op) | 1,119,708 allocs | 1,119,709 allocs | ⚪ 0% |
BenchmarkDocumentDeletion
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| single_text_delete_all_10000/ (ns/op) | 17.32 ms | 17.25 ms | 🟢 -0.38% |
| single_text_delete_all_10000/ (B/op) | 10.23 MB | 10.23 MB | ⚪ 0% |
| single_text_delete_all_10000/ (allocs/op) | 75,358 allocs | 75,358 allocs | ⚪ 0% |
| single_text_delete_all_100000/ (ns/op) | 292.50 ms | 300.98 ms | 🔴 +2.90% |
| single_text_delete_all_100000/ (B/op) | 100.70 MB | 100.69 MB | 🟢 -0.01% |
| single_text_delete_all_100000/ (allocs/op) | 752,204 allocs | 752,204 allocs | ⚪ 0% |
| single_tree_delete_all_1000/ (ns/op) | 43.92 ms | 44.04 ms | 🔴 +0.26% |
| single_tree_delete_all_1000/ (B/op) | 44.69 MB | 44.69 MB | ⚪ 0% |
| single_tree_delete_all_1000/ (allocs/op) | 63,176 allocs | 63,176 allocs | ⚪ 0% |
| single_text_delete_range_100/ (ns/op) | 427904.00 ns | 420723.00 ns | 🟢 -1.68% |
| single_text_delete_range_100/ (B/op) | 239.02 KB | 239.02 KB | ⚪ 0% |
| single_text_delete_range_100/ (allocs/op) | 7,106 allocs | 7,106 allocs | ⚪ 0% |
| single_text_delete_range_1000/ (ns/op) | 8.53 ms | 8.59 ms | 🔴 +0.72% |
| single_text_delete_range_1000/ (B/op) | 6.35 MB | 6.35 MB | ⚪ 0% |
| single_text_delete_range_1000/ (allocs/op) | 73,724 allocs | 73,724 allocs | ⚪ 0% |
| single_tree_delete_range_100/ (ns/op) | 897222.00 ns | 903251.00 ns | 🔴 +0.67% |
| single_tree_delete_range_100/ (B/op) | 710.09 KB | 710.09 KB | ⚪ 0% |
| single_tree_delete_range_100/ (allocs/op) | 7,805 allocs | 7,805 allocs | ⚪ 0% |
| single_tree_delete_range_1000/ (ns/op) | 56.64 ms | 56.22 ms | 🟢 -0.73% |
| single_tree_delete_range_1000/ (B/op) | 54.64 MB | 54.64 MB | ⚪ 0% |
| single_tree_delete_range_1000/ (allocs/op) | 167,607 allocs | 167,607 allocs | ⚪ 0% |
BenchmarkGetDocuments
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| without_root_presence_10/ (ns/op) | 1.13 ms | 1.10 ms | 🟢 -2.67% |
| without_root_presence_10/ (B/op) | 115.24 KB | 113.24 KB | 🟢 -1.73% |
| without_root_presence_10/ (allocs/op) | 1,104 allocs | 1,098 allocs | 🟢 -0.54% |
| with_root_presence_10/ (ns/op) | 4.09 ms | 4.12 ms | 🔴 +0.74% |
| with_root_presence_10/ (B/op) | 600.58 KB | 599.65 KB | 🟢 -0.15% |
| with_root_presence_10/ (allocs/op) | 5,827 allocs | 5,821 allocs | 🟢 -0.10% |
| without_root_presence_100/ (ns/op) | 2.40 ms | 2.39 ms | 🟢 -0.43% |
| without_root_presence_100/ (B/op) | 770.56 KB | 774.73 KB | 🔴 +0.54% |
| without_root_presence_100/ (allocs/op) | 6,146 allocs | 6,135 allocs | 🟢 -0.18% |
| with_root_presence_100/ (ns/op) | 42.63 ms | 42.64 ms | 🔴 +0.01% |
| with_root_presence_100/ (B/op) | 7.28 MB | 7.18 MB | 🟢 -1.36% |
| with_root_presence_100/ (allocs/op) | 68,790 allocs | 68,651 allocs | 🟢 -0.20% |
| without_root_presence_1000/ (ns/op) | 15.18 ms | 15.42 ms | 🔴 +1.58% |
| without_root_presence_1000/ (B/op) | 7.51 MB | 7.62 MB | 🔴 +1.43% |
| without_root_presence_1000/ (allocs/op) | 56,107 allocs | 56,054 allocs | 🟢 -0.09% |
| with_root_presence_1000/ (ns/op) | 408.47 ms | 408.60 ms | 🔴 +0.03% |
| with_root_presence_1000/ (B/op) | 72.27 MB | 72.06 MB | 🟢 -0.29% |
| with_root_presence_1000/ (allocs/op) | 686,167 allocs | 682,856 allocs | 🟢 -0.48% |
BenchmarkRPC
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| client_to_server/ (ns/op) | 245.10 ms | 214.30 ms | 🟢 -12.56% |
| client_to_server/ (B/op) | 30.11 MB | 27.96 MB | 🟢 -7.16% |
| client_to_server/ (allocs/op) | 353,621 allocs | 331,469 allocs | 🟢 -6.26% |
| client_to_client_via_server/ (ns/op) | 1.17 s | 155.78 ms | 🟢 -86.69% |
| client_to_client_via_server/ (B/op) | 26.39 MB | 39.44 MB | 🔴 +49.43% |
| client_to_client_via_server/ (allocs/op) | 236,365 allocs | 481,418 allocs | 🔴 +103.68% |
| attach_large_document/ (ns/op) | 1.55 s | 1.56 s | 🔴 +0.38% |
| attach_large_document/ (B/op) | 1.90 GB | 1.90 GB | 🔴 +0.08% |
| attach_large_document/ (allocs/op) | 98,011 allocs | 159,035 allocs | 🔴 +62.26% |
| adminCli_to_server/ (ns/op) | 1.34 s | 1.33 s | 🟢 -0.30% |
| adminCli_to_server/ (B/op) | 1.21 GB | 1.14 GB | 🟢 -5.44% |
| adminCli_to_server/ (allocs/op) | 682,260 allocs | 677,421 allocs | 🟢 -0.71% |
BenchmarkLocker
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| (ns/op) | 97.57 ns | 99.07 ns | 🔴 +1.54% |
| (B/op) | 32.00 B | 32.00 B | ⚪ 0% |
| (allocs/op) | 1 allocs | 1 allocs | ⚪ 0% |
BenchmarkLockerParallel
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| (ns/op) | 62.94 ns | 63.09 ns | 🔴 +0.24% |
| (B/op) | 0.00 B | 0.00 B | ⚪ 0% |
| (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
BenchmarkLockerMoreKeys
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| (ns/op) | 191.90 ns | 190.40 ns | 🟢 -0.78% |
| (B/op) | 31.00 B | 31.00 B | ⚪ 0% |
| (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
BenchmarkRWLocker
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| RWLock_rate_2/ (ns/op) | 64.03 ns | 63.76 ns | 🟢 -0.42% |
| RWLock_rate_2/ (B/op) | 0.00 B | 0.00 B | ⚪ 0% |
| RWLock_rate_2/ (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
| RWLock_rate_10/ (ns/op) | 59.18 ns | 59.64 ns | 🔴 +0.78% |
| RWLock_rate_10/ (B/op) | 0.00 B | 0.00 B | ⚪ 0% |
| RWLock_rate_10/ (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
| RWLock_rate_100/ (ns/op) | 85.04 ns | 85.12 ns | 🔴 +0.09% |
| RWLock_rate_100/ (B/op) | 4.00 B | 4.00 B | ⚪ 0% |
| RWLock_rate_100/ (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
| RWLock_rate_1000/ (ns/op) | 113.20 ns | 113.70 ns | 🔴 +0.44% |
| RWLock_rate_1000/ (B/op) | 11.00 B | 10.00 B | 🟢 -9.09% |
| RWLock_rate_1000/ (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
BenchmarkChannelAttachDetach
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| attach-detach-10/ (ns/op) | 20.45 ms | 12.06 ms | 🟢 -41.02% |
| attach-detach-10/ (B/op) | 2.87 MB | 2.42 MB | 🟢 -15.47% |
| attach-detach-10/ (allocs/op) | 19,534 allocs | 13,708 allocs | 🟢 -29.82% |
| attach-detach-50/ (ns/op) | 101.20 ms | 59.02 ms | 🟢 -41.67% |
| attach-detach-50/ (B/op) | 14.25 MB | 12.02 MB | 🟢 -15.67% |
| attach-detach-50/ (allocs/op) | 96,979 allocs | 67,663 allocs | 🟢 -30.23% |
| attach-detach-250/ (ns/op) | 512.91 ms | 285.29 ms | 🟢 -44.38% |
| attach-detach-250/ (B/op) | 76.09 MB | 62.53 MB | 🟢 -17.82% |
| attach-detach-250/ (allocs/op) | 485,706 allocs | 338,875 allocs | 🟢 -30.23% |
BenchmarkChannelHierarchicalPresenceCount
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| flat-100_includeSubPath_false/ (ns/op) | 257863.00 ns | 260783.00 ns | 🔴 +1.13% |
| flat-100_includeSubPath_false/ (B/op) | 55.36 KB | 55.30 KB | 🟢 -0.11% |
| flat-100_includeSubPath_false/ (allocs/op) | 2,106 allocs | 2,105 allocs | 🟢 -0.05% |
| flat-100_includeSubPath_true/ (ns/op) | 8.78 ms | 8.87 ms | 🔴 +1.10% |
| flat-100_includeSubPath_true/ (B/op) | 2.69 MB | 2.69 MB | 🟢 -0.12% |
| flat-100_includeSubPath_true/ (allocs/op) | 73,838 allocs | 73,799 allocs | 🟢 -0.05% |
| 2-level-1x100=100_includeSubPath_false/ (ns/op) | 451078.00 ns | 447064.00 ns | 🟢 -0.89% |
| 2-level-1x100=100_includeSubPath_false/ (B/op) | 100.26 KB | 100.16 KB | 🟢 -0.10% |
| 2-level-1x100=100_includeSubPath_false/ (allocs/op) | 3,511 allocs | 3,509 allocs | 🟢 -0.06% |
| 2-level-1x100=100_includeSubPath_true/ (ns/op) | 31.71 ms | 31.62 ms | 🟢 -0.27% |
| 2-level-1x100=100_includeSubPath_true/ (B/op) | 8.16 MB | 8.15 MB | 🟢 -0.17% |
| 2-level-1x100=100_includeSubPath_true/ (allocs/op) | 216,658 allocs | 216,489 allocs | 🟢 -0.08% |
| 2-level-10x10=100_includeSubPath_false/ (ns/op) | 450520.00 ns | 440723.00 ns | 🟢 -2.17% |
| 2-level-10x10=100_includeSubPath_false/ (B/op) | 100.34 KB | 100.17 KB | 🟢 -0.18% |
| 2-level-10x10=100_includeSubPath_false/ (allocs/op) | 3,511 allocs | 3,509 allocs | 🟢 -0.06% |
| 2-level-10x10=100_includeSubPath_true/ (ns/op) | 21.89 ms | 21.87 ms | 🟢 -0.10% |
| 2-level-10x10=100_includeSubPath_true/ (B/op) | 6.21 MB | 6.20 MB | 🟢 -0.08% |
| 2-level-10x10=100_includeSubPath_true/ (allocs/op) | 153,334 allocs | 153,273 allocs | 🟢 -0.04% |
| 3-level-1x1x1000=1000_includeSubPath_false/ (ns/op) | 6.77 ms | 6.74 ms | 🟢 -0.45% |
| 3-level-1x1x1000=1000_includeSubPath_false/ (B/op) | 1.52 MB | 1.52 MB | 🟢 -0.11% |
| 3-level-1x1x1000=1000_includeSubPath_false/ (allocs/op) | 49,169 allocs | 49,147 allocs | 🟢 -0.04% |
| 3-level-1x1x1000=1000_includeSubPath_true/ (ns/op) | 5.76 s | 5.81 s | 🔴 +0.76% |
| 3-level-1x1x1000=1000_includeSubPath_true/ (B/op) | 1.44 GB | 1.44 GB | 🟢 -0.12% |
| 3-level-1x1x1000=1000_includeSubPath_true/ (allocs/op) | 35,238,378 allocs | 35,217,415 allocs | 🟢 -0.06% |
| 3-level-1x10x100=1000_includeSubPath_false/ (ns/op) | 6.66 ms | 6.60 ms | 🟢 -0.99% |
| 3-level-1x10x100=1000_includeSubPath_false/ (B/op) | 1.53 MB | 1.52 MB | 🟢 -0.16% |
| 3-level-1x10x100=1000_includeSubPath_false/ (allocs/op) | 49,180 allocs | 49,147 allocs | 🟢 -0.07% |
| 3-level-1x10x100=1000_includeSubPath_true/ (ns/op) | 4.71 s | 4.90 s | 🔴 +4.11% |
| 3-level-1x10x100=1000_includeSubPath_true/ (B/op) | 1.20 GB | 1.20 GB | 🟢 -0.10% |
| 3-level-1x10x100=1000_includeSubPath_true/ (allocs/op) | 28,909,110 allocs | 28,896,454 allocs | 🟢 -0.04% |
| 3-level-10x10x10=1000_includeSubPath_false/ (ns/op) | 6.64 ms | 6.64 ms | 🔴 +0.13% |
| 3-level-10x10x10=1000_includeSubPath_false/ (B/op) | 1.52 MB | 1.52 MB | 🟢 -0.09% |
| 3-level-10x10x10=1000_includeSubPath_false/ (allocs/op) | 49,165 allocs | 49,144 allocs | 🟢 -0.04% |
| 3-level-10x10x10=1000_includeSubPath_true/ (ns/op) | 3.58 s | 3.59 s | 🔴 +0.21% |
| 3-level-10x10x10=1000_includeSubPath_true/ (B/op) | 939.89 MB | 938.89 MB | 🟢 -0.11% |
| 3-level-10x10x10=1000_includeSubPath_true/ (allocs/op) | 21,950,459 allocs | 21,937,831 allocs | 🟢 -0.06% |
BenchmarkPresenceConcurrency
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| 0-100-10/ (ns/op) | 572.76 ms | 518.92 ms | 🟢 -9.40% |
| 0-100-10/ (B/op) | 247.62 MB | 238.85 MB | 🟢 -3.54% |
| 0-100-10/ (allocs/op) | 2,939,100 allocs | 2,841,715 allocs | 🟢 -3.31% |
| 100-100-10/ (ns/op) | 618.62 ms | 562.81 ms | 🟢 -9.02% |
| 100-100-10/ (B/op) | 266.06 MB | 259.52 MB | 🟢 -2.46% |
| 100-100-10/ (allocs/op) | 3,266,917 allocs | 3,202,983 allocs | 🟢 -1.96% |
| 300-100-10/ (ns/op) | 677.58 ms | 627.95 ms | 🟢 -7.33% |
| 300-100-10/ (B/op) | 318.10 MB | 312.08 MB | 🟢 -1.89% |
| 300-100-10/ (allocs/op) | 4,024,263 allocs | 3,951,259 allocs | 🟢 -1.81% |
BenchmarkChange
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| Push_10_Changes/ (ns/op) | 3.91 ms | 3.86 ms | 🟢 -1.28% |
| Push_10_Changes/ (B/op) | 163.66 KB | 165.11 KB | 🔴 +0.88% |
| Push_10_Changes/ (allocs/op) | 2,108 allocs | 2,125 allocs | 🔴 +0.81% |
| Push_100_Changes/ (ns/op) | 16.81 ms | 16.52 ms | 🟢 -1.72% |
| Push_100_Changes/ (B/op) | 874.40 KB | 874.11 KB | 🟢 -0.03% |
| Push_100_Changes/ (allocs/op) | 10,433 allocs | 10,419 allocs | 🟢 -0.13% |
| Push_1000_Changes/ (ns/op) | 145.16 ms | 142.46 ms | 🟢 -1.86% |
| Push_1000_Changes/ (B/op) | 8.39 MB | 8.42 MB | 🔴 +0.45% |
| Push_1000_Changes/ (allocs/op) | 96,137 allocs | 96,074 allocs | 🟢 -0.07% |
| Pull_10_Changes/ (ns/op) | 1.77 ms | 1.74 ms | 🟢 -1.69% |
| Pull_10_Changes/ (B/op) | 66.99 KB | 67.08 KB | 🔴 +0.14% |
| Pull_10_Changes/ (allocs/op) | 978 allocs | 980 allocs | 🔴 +0.20% |
| Pull_100_Changes/ (ns/op) | 1.80 ms | 1.80 ms | 🟢 -0.06% |
| Pull_100_Changes/ (B/op) | 77.39 KB | 77.13 KB | 🟢 -0.34% |
| Pull_100_Changes/ (allocs/op) | 1,002 allocs | 999 allocs | 🟢 -0.30% |
| Pull_1000_Changes/ (ns/op) | 2.04 ms | 2.02 ms | 🟢 -1.30% |
| Pull_1000_Changes/ (B/op) | 180.12 KB | 180.10 KB | 🟢 -0.01% |
| Pull_1000_Changes/ (allocs/op) | 1,092 allocs | 1,092 allocs | ⚪ 0% |
BenchmarkSnapshot
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| Push_3KB_snapshot/ (ns/op) | 17.30 ms | 17.15 ms | 🟢 -0.85% |
| Push_3KB_snapshot/ (B/op) | 1.07 MB | 1.04 MB | 🟢 -2.74% |
| Push_3KB_snapshot/ (allocs/op) | 13,429 allocs | 12,980 allocs | 🟢 -3.34% |
| Push_30KB_snapshot/ (ns/op) | 149.86 ms | 148.41 ms | 🟢 -0.97% |
| Push_30KB_snapshot/ (B/op) | 12.09 MB | 12.16 MB | 🔴 +0.62% |
| Push_30KB_snapshot/ (allocs/op) | 159,118 allocs | 159,054 allocs | 🟢 -0.04% |
| Pull_3KB_snapshot/ (ns/op) | 2.88 ms | 2.78 ms | 🟢 -3.46% |
| Pull_3KB_snapshot/ (B/op) | 612.13 KB | 600.52 KB | 🟢 -1.90% |
| Pull_3KB_snapshot/ (allocs/op) | 11,059 allocs | 10,926 allocs | 🟢 -1.20% |
| Pull_30KB_snapshot/ (ns/op) | 7.93 ms | 7.84 ms | 🟢 -1.16% |
| Pull_30KB_snapshot/ (B/op) | 5.38 MB | 5.37 MB | 🟢 -0.27% |
| Pull_30KB_snapshot/ (allocs/op) | 99,108 allocs | 98,956 allocs | 🟢 -0.15% |
BenchmarkSplayTree
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| stress_test_100000/ (ns/op) | 0.05 ns | 0.05 ns | 🟢 -3.42% |
| stress_test_100000/ (B/op) | 0.00 B | 0.00 B | ⚪ 0% |
| stress_test_100000/ (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
| stress_test_200000/ (ns/op) | 0.10 ns | 0.11 ns | 🔴 +10.06% |
| stress_test_200000/ (B/op) | 0.00 B | 0.00 B | ⚪ 0% |
| stress_test_200000/ (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
| stress_test_300000/ (ns/op) | 0.14 ns | 0.13 ns | 🟢 -4.46% |
| stress_test_300000/ (B/op) | 0.00 B | 0.00 B | ⚪ 0% |
| stress_test_300000/ (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
| random_access_100000/ (ns/op) | 0.01 ns | 0.01 ns | 🔴 +4.94% |
| random_access_100000/ (B/op) | 0.00 B | 0.00 B | ⚪ 0% |
| random_access_100000/ (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
| random_access_200000/ (ns/op) | 0.02 ns | 0.02 ns | 🟢 -2.70% |
| random_access_200000/ (B/op) | 0.00 B | 0.00 B | ⚪ 0% |
| random_access_200000/ (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
| random_access_300000/ (ns/op) | 0.04 ns | 0.04 ns | 🔴 +3.11% |
| random_access_300000/ (B/op) | 0.00 B | 0.00 B | ⚪ 0% |
| random_access_300000/ (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
| editing_trace_bench/ (ns/op) | 0.00 ns | 0.00 ns | 🔴 +13.58% |
| editing_trace_bench/ (B/op) | 0.00 B | 0.00 B | ⚪ 0% |
| editing_trace_bench/ (allocs/op) | 0 allocs | 0 allocs | ⚪ 0% |
BenchmarkSyncConcurrency
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| 1-100-10/ (ns/op) | 7.74 s | 7.59 s | 🟢 -1.94% |
| 1-100-10/ (B/op) | 4.16 GB | 4.14 GB | 🟢 -0.47% |
| 1-100-10/ (allocs/op) | 106,304,327 allocs | 106,022,123 allocs | 🟢 -0.27% |
| 100-100-10/ (ns/op) | 8.51 s | 8.42 s | 🟢 -1.13% |
| 100-100-10/ (B/op) | 4.22 GB | 4.20 GB | 🟢 -0.45% |
| 100-100-10/ (allocs/op) | 107,008,065 allocs | 106,770,997 allocs | 🟢 -0.22% |
| 300_100-10/ (ns/op) | 10.22 s | 10.14 s | 🟢 -0.75% |
| 300_100-10/ (B/op) | 4.45 GB | 4.39 GB | 🟢 -1.42% |
| 300_100-10/ (allocs/op) | 109,573,685 allocs | 108,918,148 allocs | 🟢 -0.60% |
BenchmarkTextEditing
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| (ns/op) | 5.59 s | 5.75 s | 🔴 +2.80% |
| (B/op) | 3.87 GB | 3.87 GB | ⚪ 0% |
| (allocs/op) | 19,689,275 allocs | 19,692,241 allocs | 🔴 +0.02% |
BenchmarkTree
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| 10000_vertices_to_protobuf/ (ns/op) | 4.89 ms | 5.60 ms | 🔴 +14.60% |
| 10000_vertices_to_protobuf/ (B/op) | 6.68 MB | 6.68 MB | ⚪ 0% |
| 10000_vertices_to_protobuf/ (allocs/op) | 90,124 allocs | 90,138 allocs | 🔴 +0.02% |
| 10000_vertices_from_protobuf/ (ns/op) | 251.02 ms | 274.75 ms | 🔴 +9.45% |
| 10000_vertices_from_protobuf/ (B/op) | 442.57 MB | 442.58 MB | ⚪ 0% |
| 10000_vertices_from_protobuf/ (allocs/op) | 335,080 allocs | 335,573 allocs | 🔴 +0.15% |
| 20000_vertices_to_protobuf/ (ns/op) | 10.16 ms | 11.18 ms | 🔴 +9.96% |
| 20000_vertices_to_protobuf/ (B/op) | 13.53 MB | 13.53 MB | ⚪ 0% |
| 20000_vertices_to_protobuf/ (allocs/op) | 180,234 allocs | 180,254 allocs | 🔴 +0.01% |
| 20000_vertices_from_protobuf/ (ns/op) | 959.08 ms | 1.03 s | 🔴 +7.31% |
| 20000_vertices_from_protobuf/ (B/op) | 1.70 GB | 1.70 GB | ⚪ 0% |
| 20000_vertices_from_protobuf/ (allocs/op) | 679,304 allocs | 680,709 allocs | 🔴 +0.21% |
| 30000_vertices_to_protobuf/ (ns/op) | 15.59 ms | 16.89 ms | 🔴 +8.39% |
| 30000_vertices_to_protobuf/ (B/op) | 19.94 MB | 19.94 MB | ⚪ 0% |
| 30000_vertices_to_protobuf/ (allocs/op) | 270,343 allocs | 270,370 allocs | ⚪ 0% |
| 30000_vertices_from_protobuf/ (ns/op) | 2.08 s | 2.20 s | 🔴 +6.08% |
| 30000_vertices_from_protobuf/ (B/op) | 3.75 GB | 3.75 GB | ⚪ 0% |
| 30000_vertices_from_protobuf/ (allocs/op) | 1,031,730 allocs | 1,034,282 allocs | 🔴 +0.25% |
BenchmarkVersionVector
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| clients_10/ (ns/op) | 98.06 ms | 86.77 ms | 🟢 -11.51% |
| clients_10/ (1_changepack(bytes)) | 186.00 B | 186.00 B | ⚪ 0% |
| clients_10/ (2_snapshot(bytes)) | 399.00 B | 399.00 B | ⚪ 0% |
| clients_10/ (3_pushpull(ms)) | 3.00 ms | 3.00 ms | ⚪ 0% |
| clients_10/ (4_attach(ms)) | 3.00 ms | 3.00 ms | ⚪ 0% |
| clients_10/ (5_changepack_after_detach(bytes)) | 231.00 B | 231.00 B | ⚪ 0% |
| clients_10/ (6_snapshot_after_detach(bytes)) | 156.00 B | 156.00 B | ⚪ 0% |
| clients_10/ (7_pushpull_after_detach(ms)) | 3.00 ms | 3.00 ms | ⚪ 0% |
| clients_10/ (B/op) | 7.50 MB | 6.91 MB | 🟢 -7.81% |
| clients_10/ (allocs/op) | 65,683 allocs | 57,238 allocs | 🟢 -12.86% |
| clients_100/ (ns/op) | 807.70 ms | 713.13 ms | 🟢 -11.71% |
| clients_100/ (1_changepack(bytes)) | 185.00 B | 185.00 B | ⚪ 0% |
| clients_100/ (2_snapshot(bytes)) | 3.10 KB | 3.10 KB | ⚪ 0% |
| clients_100/ (3_pushpull(ms)) | 4.00 ms | 3.00 ms | 🟢 -25.00% |
| clients_100/ (4_attach(ms)) | 4.00 ms | 3.00 ms | 🟢 -25.00% |
| clients_100/ (5_changepack_after_detach(bytes)) | 231.00 B | 231.00 B | ⚪ 0% |
| clients_100/ (6_snapshot_after_detach(bytes)) | 156.00 B | 156.00 B | ⚪ 0% |
| clients_100/ (7_pushpull_after_detach(ms)) | 3.00 ms | 3.00 ms | ⚪ 0% |
| clients_100/ (B/op) | 70.50 MB | 58.76 MB | 🟢 -16.64% |
| clients_100/ (allocs/op) | 644,802 allocs | 577,744 allocs | 🟢 -10.40% |
| clients_1000/ (ns/op) | 9.84 s | 9.13 s | 🟢 -7.23% |
| clients_1000/ (1_changepack(bytes)) | 186.00 B | 186.00 B | ⚪ 0% |
| clients_1000/ (2_snapshot(bytes)) | 30.10 KB | 30.10 KB | ⚪ 0% |
| clients_1000/ (3_pushpull(ms)) | 3.00 ms | 3.00 ms | ⚪ 0% |
| clients_1000/ (4_attach(ms)) | 7.00 ms | 6.00 ms | 🟢 -14.29% |
| clients_1000/ (5_changepack_after_detach(bytes)) | 231.00 B | 231.00 B | ⚪ 0% |
| clients_1000/ (6_snapshot_after_detach(bytes)) | 156.00 B | 156.00 B | ⚪ 0% |
| clients_1000/ (7_pushpull_after_detach(ms)) | 3.00 ms | 9.00 ms | 🔴 +200.00% |
| clients_1000/ (B/op) | 1.44 GB | 1.39 GB | 🟢 -3.58% |
| clients_1000/ (allocs/op) | 18,369,152 allocs | 17,708,362 allocs | 🟢 -3.60% |
BenchmarkWebhook
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| Send_10_Webhooks_to_10_Endpoints/ (ns/op) | 12.23 ms | 12.48 ms | 🔴 +2.00% |
| Send_10_Webhooks_to_10_Endpoints/ (B/op) | 777.98 KB | 778.07 KB | 🔴 +0.01% |
| Send_10_Webhooks_to_10_Endpoints/ (allocs/op) | 10,067 allocs | 10,073 allocs | 🔴 +0.06% |
| Send_100_Webhooks_to_10_Endpoints/ (ns/op) | 122.47 ms | 123.02 ms | 🔴 +0.46% |
| Send_100_Webhooks_to_10_Endpoints/ (B/op) | 7.78 MB | 7.78 MB | ⚪ 0% |
| Send_100_Webhooks_to_10_Endpoints/ (allocs/op) | 100,701 allocs | 100,718 allocs | 🔴 +0.02% |
| Send_10_Webhooks_to_100_Endpoints/ (ns/op) | 127.91 ms | 133.91 ms | 🔴 +4.69% |
| Send_10_Webhooks_to_100_Endpoints/ (B/op) | 7.99 MB | 7.99 MB | ⚪ 0% |
| Send_10_Webhooks_to_100_Endpoints/ (allocs/op) | 102,243 allocs | 102,367 allocs | 🔴 +0.12% |
| Send_100_Webhooks_to_100_Endpoints/ (ns/op) | 1.26 s | 1.31 s | 🔴 +4.11% |
| Send_100_Webhooks_to_100_Endpoints/ (B/op) | 79.39 MB | 79.42 MB | 🔴 +0.03% |
| Send_100_Webhooks_to_100_Endpoints/ (allocs/op) | 1,018,760 allocs | 1,019,983 allocs | 🔴 +0.12% |
| Send_10_Webhooks_to_1000_Endpoints/ (ns/op) | 2.85 s | 2.92 s | 🔴 +2.44% |
| Send_10_Webhooks_to_1000_Endpoints/ (B/op) | 208.06 MB | 208.09 MB | 🔴 +0.02% |
| Send_10_Webhooks_to_1000_Endpoints/ (allocs/op) | 1,749,938 allocs | 1,751,354 allocs | 🔴 +0.08% |
BenchmarkWebhookWithLimit
| Benchmark suite | Previous | Current | Change |
|---|---|---|---|
| Send_10_Webhooks_to_10_Endpoints_with_limit/ (ns/op) | 3.91 ms | 3.95 ms | 🔴 +0.90% |
| Send_10_Webhooks_to_10_Endpoints_with_limit/ (B/op) | 305.11 KB | 305.07 KB | 🟢 -0.01% |
| Send_10_Webhooks_to_10_Endpoints_with_limit/ (allocs/op) | 2,939 allocs | 2,940 allocs | 🔴 +0.03% |
| Send_100_Webhooks_to_10_Endpoints_with_limit/ (ns/op) | 4.21 ms | 4.27 ms | 🔴 +1.53% |
| Send_100_Webhooks_to_10_Endpoints_with_limit/ (B/op) | 456.49 KB | 456.40 KB | 🟢 -0.02% |
| Send_100_Webhooks_to_10_Endpoints_with_limit/ (allocs/op) | 4,746 allocs | 4,748 allocs | 🔴 +0.04% |
| Send_10_Webhooks_to_100_Endpoints_with_limit/ (ns/op) | 39.01 ms | 40.62 ms | 🔴 +4.12% |
| Send_10_Webhooks_to_100_Endpoints_with_limit/ (B/op) | 3.06 MB | 3.06 MB | 🔴 +0.02% |
| Send_10_Webhooks_to_100_Endpoints_with_limit/ (allocs/op) | 29,394 allocs | 29,432 allocs | 🔴 +0.13% |
| Send_100_Webhooks_to_100_Endpoints_with_limit/ (ns/op) | 42.45 ms | 44.53 ms | 🔴 +4.89% |
| Send_100_Webhooks_to_100_Endpoints_with_limit/ (B/op) | 4.64 MB | 4.64 MB | 🔴 +0.04% |
| Send_100_Webhooks_to_100_Endpoints_with_limit/ (allocs/op) | 47,473 allocs | 47,535 allocs | 🔴 +0.13% |
| Send_10_Webhooks_to_1000_Endpoints_with_limit/ (ns/op) | 395.92 ms | 409.52 ms | 🔴 +3.44% |
| Send_10_Webhooks_to_1000_Endpoints_with_limit/ (B/op) | 44.50 MB | 44.51 MB | 🔴 +0.02% |
| Send_10_Webhooks_to_1000_Endpoints_with_limit/ (allocs/op) | 383,770 allocs | 384,127 allocs | 🔴 +0.09% |
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.
k6 Load Test 📊
This is a comparison result between the previous(e816a17) and the current commit(2ec8ce2).
Change
| Metric | Previous | Current | Change |
|---|---|---|---|
| transaction_time.avg | 6519.61 | 6416.51 | 🟢 -1.58% |
| http_req_duration.avg | 49.43 | 38.92 | 🟢 -21.27% |
| http_req_duration.p(95) | 224.98 | 184.04 | 🟢 -18.20% |
| iteration_duration.avg | 6519.66 | 6416.58 | 🟢 -1.58% |
| data_received.count | 1,162,556,628 | 1,191,285,402 | 🔴 +2.47% |
| data_sent.count | 62,337,206 | 63,428,843 | 🔴 +1.75% |
Result
script: test/k6/presence.ts
scenarios: (100.00%) 1 scenario, 500 max VUs, 3m0s max duration (incl. graceful stop):
* default: Up to 500 looping VUs for 2m30s over 3 stages (gracefulRampDown: 30s, gracefulStop: 30s)
█ THRESHOLDS
active_clients_time
✓ 'p(95)<500' p(95)=106ms
attach_documents_time
✓ 'p(95)<10000' p(95)=373ms
deactivate_clients_time
✓ 'p(95)<10000' p(95)=94ms
http_req_duration
✓ 'p(95)<10000' p(95)=184.04ms
pushpulls_time
✓ 'p(95)<1000' p(95)=199ms
transaction_success_rate
✓ 'rate>0.99' rate=100.00%
transaction_time
✓ 'p(95)<30000' p(95)=7.11s
█ TOTAL RESULTS
checks_total.......: 134832 873.770355/s
checks_succeeded...: 100.00% 134832 out of 134832
checks_failed......: 0.00% 0 out of 134832
✓ status is 200
✓ response has valid body
CUSTOM
active_clients....................: 8427 54.610647/s
active_clients_success_rate.......: 100.00% 8427 out of 8427
active_clients_time...............: avg=22.57ms min=0s med=3ms max=577ms p(90)=73ms p(95)=106ms
attach_documents..................: 8427 54.610647/s
attach_documents_success_rate.....: 100.00% 8427 out of 8427
attach_documents_time.............: avg=87.53ms min=3ms med=15ms max=824ms p(90)=284ms p(95)=373ms
deactivate_clients................: 8427 54.610647/s
deactivate_clients_success_rate...: 100.00% 8427 out of 8427
deactivate_clients_time...........: avg=19.8ms min=0s med=2ms max=497ms p(90)=61ms p(95)=94ms
pushpulls.........................: 42135 273.053236/s
pushpulls_success_rate............: 100.00% 42135 out of 42135
pushpulls_time....................: avg=45.46ms min=1ms med=12ms max=842ms p(90)=131ms p(95)=199ms
transaction_success_rate..........: 100.00% 8427 out of 8427
transaction_time..................: avg=6.41s min=6.01s med=6.35s max=8.43s p(90)=6.94s p(95)=7.11s
HTTP
http_req_duration.................: avg=38.91ms min=182.87µs med=6.19ms max=822.81ms p(90)=116.35ms p(95)=184.04ms
{ expected_response:true }......: avg=38.91ms min=182.87µs med=6.19ms max=822.81ms p(90)=116.35ms p(95)=184.04ms
http_req_failed...................: 0.00% 0 out of 67416
http_reqs.........................: 67416 436.885178/s
EXECUTION
iteration_duration................: avg=6.41s min=6.01s med=6.35s max=8.43s p(90)=6.94s p(95)=7.11s
iterations........................: 8427 54.610647/s
vus...............................: 8 min=8 max=500
vus_max...........................: 500 min=500 max=500
NETWORK
data_received.....................: 1.2 GB 7.7 MB/s
data_sent.........................: 63 MB 411 kB/s
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1600 +/- ##
==========================================
+ Coverage 32.74% 32.78% +0.04%
==========================================
Files 195 196 +1
Lines 25707 25781 +74
==========================================
+ Hits 8417 8452 +35
- Misses 16516 16552 +36
- Partials 774 777 +3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
Actionable comments posted: 1
🧹 Nitpick comments (1)
server/backend/database/mongo/project_cache.go (1)
83-102: Consider hardening the API‑key index type assertion
GetByAPIKeyassumes that values inapiKeyToIDare alwaystypes.IDand will panic if anything else is ever stored there (e.g., via future refactors/tests).You can make this more defensive without changing behavior by type‑checking and cleaning up unexpected entries:
func (pc *ProjectCache) GetByAPIKey(apiKey string) (*database.ProjectInfo, bool) { - idVal, ok := pc.apiKeyToID.Load(apiKey) - if !ok { - return nil, false - } - - id := idVal.(types.ID) + idVal, ok := pc.apiKeyToID.Load(apiKey) + if !ok { + return nil, false + } + + id, ok := idVal.(types.ID) + if !ok { + // Defensive cleanup if the map was misused. + pc.apiKeyToID.Delete(apiKey) + return nil, false + }This keeps the fast path unchanged while preventing a hard panic if the map is ever misused.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
api/yorkie/v1/cluster.proto(0 hunks)pkg/cache/lru_with_expires.go(1 hunks)server/backend/database/mongo/client.go(10 hunks)server/backend/database/mongo/project_cache.go(1 hunks)server/rpc/admin_server.go(2 hunks)
💤 Files with no reviewable changes (1)
- api/yorkie/v1/cluster.proto
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-01T10:41:17.815Z
Learnt from: hackerwins
Repo: yorkie-team/yorkie PR: 1472
File: server/backend/database/mongo/client.go:141-145
Timestamp: 2025-09-01T10:41:17.815Z
Learning: The hashicorp/golang-lru/v2 Cache type is thread-safe and does not require external locking for operations like Purge(), Add(), Get(), or Remove().
Applied to files:
server/backend/database/mongo/client.go
🧬 Code graph analysis (4)
server/rpc/admin_server.go (2)
api/types/id.go (1)
ID(37-37)pkg/document/crdt/primitive.go (1)
String(40-40)
pkg/cache/lru_with_expires.go (1)
pkg/cache/lru_with_stats.go (1)
NewLRU(34-45)
server/backend/database/mongo/project_cache.go (3)
pkg/cache/lru_with_expires.go (2)
LRUWithExpires(31-35)NewLRUWithExpires(38-55)server/backend/database/project_info.go (1)
ProjectInfo(55-143)pkg/cache/stats.go (1)
Stats(8-11)
server/backend/database/mongo/client.go (2)
server/backend/database/mongo/project_cache.go (2)
ProjectCache(32-38)NewProjectCache(41-65)api/types/id.go (1)
ID(37-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: build
- GitHub Check: complex-test
- GitHub Check: bench
- GitHub Check: load-test
🔇 Additional comments (9)
pkg/cache/lru_with_expires.go (1)
38-49: Eviction callback plumbing is correct and backward‑compatibleThe optional variadic callback is wired cleanly into
expirable.NewLRU, and defaulting tonilwhen not provided preserves existing behavior for all current callers.server/backend/database/mongo/project_cache.go (1)
32-65: ProjectCache design with primary ID cache + API‑key index looks solidUsing a single
LRUWithExpires[types.ID, *database.ProjectInfo]as the primary store and async.Mapas the API‑key → ID index keeps memory use low and ensures eviction is driven by the primary key. The eviction callback that removesinfo.PublicKeyfromapiKeyToIDkeeps both indices consistent without additional bookkeeping in callers.server/backend/database/mongo/client.go (6)
50-61: ProjectCache wiring inClientandDialis consistent with existing cache patternsInitializing
ProjectCacheviaNewProjectCache, registering it withcacheManager, and storing it onClientmirrors how the other caches are handled. CallingPurgefromClosekeeps lifecycle management uniform, and the cache manager will still log stats as before.Also applies to: 105-113, 147-158
565-586: Project cache usage inFindProjectInfoByPublicKeylooks correct
- On cache hit, returning
cached.DeepCopy()preserves immutability of the cachedProjectInfo.- On miss, reading from Mongo and then calling
c.projectCache.Add(info)lets the ProjectCache handle the deep copy and index updates; returning the freshly decodedinfois consistent with patterns used in other caches (e.g., client cache).This cleanly benefits from the dual‑key ProjectCache without leaking its internal representation.
629-650: ID-based lookup path correctly leverages ProjectCache
FindProjectInfoByIDnow:
- Checks
projectCache.GetByID(id)first and returns a deep copy on hit.- Falls back to Mongo on miss and then calls
projectCache.Add(info)to seed the cache.This ensures both ID and API‑key lookups share a single underlying cache entry and stay consistent.
652-691: Write path invalidation by ID inUpdateProjectInfomatches the new cache designAfter successfully updating the project document, calling:
c.projectCache.Remove(info.ID)invalidates the ID‑primary ProjectCache entry (and, via the eviction callback, its API‑key index entry), ensuring subsequent reads don’t observe stale cached data. This also aligns with the ID‑based invalidation broadcasts in the RPC layer.
693-729: Pre-rotation invalidation inRotateProjectKeysis consistent with ID-based cachingDecoding
prevInfoand then invoking:c.projectCache.Remove(prevInfo.ID)before updating the keys ensures that any cache entries keyed by the old API key are dropped (through the ProjectCache’s internal cleanup logic). Combined with the ID‑based cluster cache invalidation, this avoids serving stale keys from cache on both the local and remote nodes.
185-193: AllInvalidateCache(CacheTypeProject, ...)callers currently pass valid project IDsCurrent callers in
admin_server.goproperly passproject.ID.String()andprev.ID.String(), ensuring only well-formed IDs reach the cache invalidation logic. The ID validation inmongo/client.gois correct and safe given the current call patterns.server/rpc/admin_server.go (1)
239-245: Switching cache invalidation to project IDs aligns with the new ProjectCacheUsing
project.ID.String()andprev.ID.String()forBroadcastCacheInvalidationmatches the updated Mongo client logic, which now invalidates the project cache by ID rather than API key. The backend correctly validates the ID format inmongo.Client.InvalidateCache(), ensuring all nodes' caches remain consistent.Both
CacheTypeProjectinvalidation call sites in the codebase (UpdateProject and RotateProjectKeys) correctly pass project IDs, maintaining consistency with the ID-primary ProjectCache design.
e5a2725 to
bf82e65
Compare
hackerwins
left a comment
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.
Thanks for your contribution.
What this PR does / why we need it:
Enhanced the project caching mechanism with a dual-lookup strategy
that uses project ID as the primary key and API key as a secondary key
to achieve faster and more reliable lookups.
Which issue(s) this PR fixes:
Fixes #
Special notes for your reviewer:
Does this PR introduce a user-facing change?:
Additional documentation:
Checklist:
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.