Skip to content

Commit d2332be

Browse files
committed
Node.js: Add serverAssisted to ClientSideCache for Phase 2 server-assisted caching
Signed-off-by: affonsov <67347924+affonsov@users.noreply.github.com>
1 parent c0cd34d commit d2332be

8 files changed

Lines changed: 108 additions & 0 deletions

File tree

java/client/src/test/java/glide/api/models/configuration/BaseClientConfigurationTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
package glide.api.models.configuration;
33

44
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertFalse;
56
import static org.junit.jupiter.api.Assertions.assertNull;
67
import static org.junit.jupiter.api.Assertions.assertThrows;
8+
import static org.junit.jupiter.api.Assertions.assertTrue;
79

810
import org.junit.jupiter.api.Test;
911
import org.junit.jupiter.params.ParameterizedTest;
@@ -150,4 +152,14 @@ public void testNodeDiscoveryModeDiscoverAll() {
150152
.build();
151153
assertEquals(NodeDiscoveryMode.DISCOVER_ALL, config.getNodeDiscoveryMode());
152154
}
155+
156+
@Test
157+
void testServerAssistedCacheConfig() {
158+
ClientSideCache cache =
159+
ClientSideCache.builder().maxCacheKb(1024).entryTtlMs(0).serverAssisted(true).build();
160+
assertTrue(cache.isServerAssisted());
161+
162+
ClientSideCache cacheDefault = ClientSideCache.builder().maxCacheKb(1024).entryTtlMs(0).build();
163+
assertFalse(cacheDefault.isServerAssisted());
164+
}
153165
}

node/src/BaseClient.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ import {
9696
createBitField,
9797
createBitOp,
9898
createBitPos,
99+
createClientTrackingInfo,
99100
createCopy,
100101
createDecr,
101102
createDecrBy,
@@ -9246,6 +9247,17 @@ export class BaseClient {
92469247
return this.createWritePromise(createSort(key, options, destination));
92479248
}
92489249

9250+
/**
9251+
* Returns information about the current client connection's tracking state.
9252+
*
9253+
* @see {@link https://valkey.io/commands/client-trackinginfo/|valkey.io} for details.
9254+
*
9255+
* @returns A map of tracking info.
9256+
*/
9257+
public async clientTrackingInfo(): Promise<Record<string, unknown>> {
9258+
return this.createWritePromise(createClientTrackingInfo());
9259+
}
9260+
92499261
/**
92509262
* @internal
92519263
*/
@@ -9329,6 +9341,7 @@ export class BaseClient {
93299341
entryTtlMs: cache.entryTtlMs,
93309342
evictionPolicy: cache.evictionPolicy,
93319343
enableMetrics: cache.enableMetrics,
9344+
serverAssisted: cache.serverAssisted,
93329345
});
93339346
}
93349347

node/src/Batch.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ import {
8888
createBitPos,
8989
createClientGetName,
9090
createClientId,
91+
createClientTrackingInfo,
9192
createConfigGet,
9293
createConfigResetStat,
9394
createConfigRewrite,
@@ -530,6 +531,15 @@ export class BaseBatch<T extends BaseBatch<T>> {
530531
return this.addAndReturn(createClientGetName());
531532
}
532533

534+
/** Returns information about the current client connection's tracking state.
535+
* @see {@link https://valkey.io/commands/client-trackinginfo/|valkey.io} for details.
536+
*
537+
* Command Response - A map of tracking info.
538+
*/
539+
public clientTrackingInfo(): T {
540+
return this.addAndReturn(createClientTrackingInfo());
541+
}
542+
533543
/**
534544
* Rewrites the configuration file with the current configuration.
535545
*

node/src/ClientSideCache.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ export interface ClientSideCacheConfig {
3333
* Defaults to false if not specified.
3434
*/
3535
enableMetrics?: boolean;
36+
37+
/**
38+
* Whether to use server-assisted (invalidation-based) caching mode.
39+
* Defaults to false if not specified.
40+
*/
41+
serverAssisted?: boolean;
3642
}
3743

3844
/**
@@ -48,6 +54,11 @@ export interface ClientSideCacheOptions {
4854
* Whether to enable metrics collection for this cache.
4955
*/
5056
enableMetrics?: boolean;
57+
58+
/**
59+
* Whether to use server-assisted (invalidation-based) caching mode.
60+
*/
61+
serverAssisted?: boolean;
5162
}
5263

5364
/**
@@ -99,6 +110,11 @@ export class ClientSideCache {
99110
*/
100111
readonly enableMetrics: boolean;
101112

113+
/**
114+
* Whether server-assisted caching mode is enabled.
115+
*/
116+
readonly serverAssisted: boolean;
117+
102118
/**
103119
* Creates a new ClientSideCache instance.
104120
*
@@ -122,6 +138,7 @@ export class ClientSideCache {
122138
this.entryTtlMs = config.entryTtlMs;
123139
this.evictionPolicy = config.evictionPolicy;
124140
this.enableMetrics = config.enableMetrics ?? false;
141+
this.serverAssisted = config.serverAssisted ?? false;
125142
}
126143

127144
/**
@@ -156,6 +173,7 @@ export class ClientSideCache {
156173
entryTtlMs,
157174
evictionPolicy: options?.evictionPolicy,
158175
enableMetrics: options?.enableMetrics,
176+
serverAssisted: options?.serverAssisted,
159177
});
160178
}
161179
}

node/src/Commands.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,13 @@ export function createClientId(): command_request.Command {
428428
return createCommand(RequestType.ClientId, []);
429429
}
430430

431+
/**
432+
* @internal
433+
*/
434+
export function createClientTrackingInfo(): command_request.Command {
435+
return createCommand(RequestType.ClientTrackingInfo, []);
436+
}
437+
431438
/**
432439
* @internal
433440
*/

node/src/GlideClusterClient.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {
3434
LolwutOptions,
3535
createClientGetName,
3636
createClientId,
37+
createClientTrackingInfo,
3738
createConfigGet,
3839
createConfigResetStat,
3940
createConfigRewrite,
@@ -1063,6 +1064,26 @@ export class GlideClusterClient extends BaseClient {
10631064
).then((res) => convertClusterGlideRecord(res, true, options?.route));
10641065
}
10651066

1067+
/**
1068+
* Returns information about the current client connection's tracking state.
1069+
*
1070+
* @see {@link https://valkey.io/commands/client-trackinginfo/|valkey.io} for details.
1071+
*
1072+
* @param options - (Optional) See {@link RouteOption}.
1073+
*
1074+
* @returns A map of tracking info. When specifying a route other than a single node,
1075+
* it returns a dictionary where each address is the key and its corresponding node response is the value.
1076+
*/
1077+
public async clientTrackingInfo(
1078+
options?: RouteOption,
1079+
): Promise<ClusterResponse<Record<string, unknown>>> {
1080+
return this.createWritePromise<
1081+
ClusterGlideRecord<Record<string, unknown>>
1082+
>(createClientTrackingInfo(), options).then((res) =>
1083+
convertClusterGlideRecord(res, true, options?.route),
1084+
);
1085+
}
1086+
10661087
/**
10671088
* Rewrites the configuration file with the current configuration.
10681089
*

node/tests/ClientSideCache.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ const TIMEOUT = 50000;
2929
const CLEANUP_TIMEOUT = 10000;
3030

3131
describe("ClientSideCache", () => {
32+
it("ClientSideCache with serverAssisted", () => {
33+
const cache = new ClientSideCache({
34+
maxCacheKb: 1024,
35+
entryTtlMs: 0,
36+
serverAssisted: true,
37+
});
38+
expect(cache.serverAssisted).toBe(true);
39+
40+
const cacheDefault = new ClientSideCache({
41+
maxCacheKb: 1024,
42+
entryTtlMs: 0,
43+
});
44+
expect(cacheDefault.serverAssisted).toBe(false);
45+
});
46+
3247
let standaloneCluster: ValkeyCluster;
3348
let clusterCluster: ValkeyCluster;
3449

python/tests/sync_tests/test_sync_client_side_cache.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,3 +569,15 @@ def test_sync_cache_entry_ttl_ms_validation(self):
569569
# Negative should raise
570570
with pytest.raises(ValueError, match="entry_ttl_ms must be non-negative"):
571571
ClientSideCache.create(max_cache_kb=1, entry_ttl_ms=-1)
572+
573+
def test_server_assisted_cache_config(self):
574+
"""Verify ClientSideCache server_assisted field is correctly set."""
575+
cache = ClientSideCache(
576+
cache_id="test", max_cache_kb=1, entry_ttl_ms=0, server_assisted=True
577+
)
578+
assert cache.server_assisted is True
579+
580+
cache_default = ClientSideCache(
581+
cache_id="test2", max_cache_kb=1, entry_ttl_ms=0
582+
)
583+
assert cache_default.server_assisted is False

0 commit comments

Comments
 (0)