Skip to content

Commit

Permalink
Node: enable routing by node address.
Browse files Browse the repository at this point in the history
  • Loading branch information
nihohit committed Feb 22, 2024
1 parent c3f55e4 commit 5bf685c
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 24 deletions.
53 changes: 30 additions & 23 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
#### Changes

- Node: Allow routing Cluster requests by address. ([#1021](https://github.com/aws/glide-for-redis/pull/1021))

## 0.2.0 (2024-02-11)

#### Changes
* Python, Node: Added ZCARD command ([#871](https://github.com/aws/glide-for-redis/pull/871), [#885](https://github.com/aws/glide-for-redis/pull/885))
* Python, Node: Added ZADD and ZADDINCR commands ([#814](https://github.com/aws/glide-for-redis/pull/814), [#830](https://github.com/aws/glide-for-redis/pull/830))
* Python, Node: Added ZREM command ([#834](https://github.com/aws/glide-for-redis/pull/834), [#831](https://github.com/aws/glide-for-redis/pull/831))
* Python, Node: Added ZSCORE command ([#877](https://github.com/aws/glide-for-redis/pull/877), [#889](https://github.com/aws/glide-for-redis/pull/889))
* Use jemalloc as default allocator. ([#847](https://github.com/aws/glide-for-redis/pull/847))
* Python, Node: Added RPOPCOUNT and LPOPCOUNT to transaction ([#874](https://github.com/aws/glide-for-redis/pull/874))
* Standalone client: Improve connection errors. ([#854](https://github.com/aws/glide-for-redis/pull/854))
* Python, Node: When recieving LPOP/RPOP with count, convert result to Array. ([#811](https://github.com/aws/glide-for-redis/pull/811))
* Python, Node: Added TYPE command ([#945](https://github.com/aws/glide-for-redis/pull/945), [#980](https://github.com/aws/glide-for-redis/pull/980))
* Python, Node: Added HLEN command ([#944](https://github.com/aws/glide-for-redis/pull/944), [#981](https://github.com/aws/glide-for-redis/pull/981))
* Node: Added ZCOUNT command ([#909](https://github.com/aws/glide-for-redis/pull/909))
* Python: Added ECHO command ([#953](https://github.com/aws/glide-for-redis/pull/953))
* Python, Node: Added ZPOPMIN command ([#975](https://github.com/aws/glide-for-redis/pull/975), [#1008](https://github.com/aws/glide-for-redis/pull/1008))
* Node: Added STRLEN command ([#993](https://github.com/aws/glide-for-redis/pull/993))
* Node: Added LINDEX command ([#999](https://github.com/aws/glide-for-redis/pull/999))
* Python, Node: Added ZPOPMAX command ([#996](https://github.com/aws/glide-for-redis/pull/996), [#1009](https://github.com/aws/glide-for-redis/pull/1009))

- Python, Node: Added ZCARD command ([#871](https://github.com/aws/glide-for-redis/pull/871), [#885](https://github.com/aws/glide-for-redis/pull/885))
- Python, Node: Added ZADD and ZADDINCR commands ([#814](https://github.com/aws/glide-for-redis/pull/814), [#830](https://github.com/aws/glide-for-redis/pull/830))
- Python, Node: Added ZREM command ([#834](https://github.com/aws/glide-for-redis/pull/834), [#831](https://github.com/aws/glide-for-redis/pull/831))
- Python, Node: Added ZSCORE command ([#877](https://github.com/aws/glide-for-redis/pull/877), [#889](https://github.com/aws/glide-for-redis/pull/889))
- Use jemalloc as default allocator. ([#847](https://github.com/aws/glide-for-redis/pull/847))
- Python, Node: Added RPOPCOUNT and LPOPCOUNT to transaction ([#874](https://github.com/aws/glide-for-redis/pull/874))
- Standalone client: Improve connection errors. ([#854](https://github.com/aws/glide-for-redis/pull/854))
- Python, Node: When recieving LPOP/RPOP with count, convert result to Array. ([#811](https://github.com/aws/glide-for-redis/pull/811))
- Python, Node: Added TYPE command ([#945](https://github.com/aws/glide-for-redis/pull/945), [#980](https://github.com/aws/glide-for-redis/pull/980))
- Python, Node: Added HLEN command ([#944](https://github.com/aws/glide-for-redis/pull/944), [#981](https://github.com/aws/glide-for-redis/pull/981))
- Node: Added ZCOUNT command ([#909](https://github.com/aws/glide-for-redis/pull/909))
- Python: Added ECHO command ([#953](https://github.com/aws/glide-for-redis/pull/953))
- Python, Node: Added ZPOPMIN command ([#975](https://github.com/aws/glide-for-redis/pull/975), [#1008](https://github.com/aws/glide-for-redis/pull/1008))
- Node: Added STRLEN command ([#993](https://github.com/aws/glide-for-redis/pull/993))
- Node: Added LINDEX command ([#999](https://github.com/aws/glide-for-redis/pull/999))
- Python, Node: Added ZPOPMAX command ([#996](https://github.com/aws/glide-for-redis/pull/996), [#1009](https://github.com/aws/glide-for-redis/pull/1009))

#### Features
* Python, Node: Added support in Lua Scripts ([#775](https://github.com/aws/glide-for-redis/pull/775), [#860](https://github.com/aws/glide-for-redis/pull/860))
* Python, Node: Allow chaining function calls on transaction. ([#902](https://github.com/aws/glide-for-redis/pull/902)), ([#987](https://github.com/aws/glide-for-redis/pull/987))

- Python, Node: Added support in Lua Scripts ([#775](https://github.com/aws/glide-for-redis/pull/775), [#860](https://github.com/aws/glide-for-redis/pull/860))
- Python, Node: Allow chaining function calls on transaction. ([#902](https://github.com/aws/glide-for-redis/pull/902)), ([#987](https://github.com/aws/glide-for-redis/pull/987))

#### Fixes
* Core: Fixed `Connection Refused` error not to close the client ([#872](https://github.com/aws/glide-for-redis/pull/872))
* Socket listener: fix identifier for closed reader error. ([#853](https://github.com/aws/glide-for-redis/pull/853))
* Node: Fix issues with type import & exports ([#767](https://github.com/aws/glide-for-redis/pull/767))
* Core: Added handling to "?" and NULL hostnames in CLUSTER SLOTS ([#104](https://github.com/amazon-contributing/redis-rs/pull/104))
* Core: Cluster connection now reconnects after full disconnect. ([#100](https://github.com/amazon-contributing/redis-rs/pull/100))

- Core: Fixed `Connection Refused` error not to close the client ([#872](https://github.com/aws/glide-for-redis/pull/872))
- Socket listener: fix identifier for closed reader error. ([#853](https://github.com/aws/glide-for-redis/pull/853))
- Node: Fix issues with type import & exports ([#767](https://github.com/aws/glide-for-redis/pull/767))
- Core: Added handling to "?" and NULL hostnames in CLUSTER SLOTS ([#104](https://github.com/amazon-contributing/redis-rs/pull/104))
- Core: Cluster connection now reconnects after full disconnect. ([#100](https://github.com/amazon-contributing/redis-rs/pull/100))

## 0.1.0 (2024-01-17)

Expand Down
33 changes: 32 additions & 1 deletion node/src/RedisClusterClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@ export type SlotKeyTypes = {
key: string;
};

/// Route command to specific node.
export type RouteByAddress = {
type: "routeByAddress";
/**
* DNS name of the host.
*/
host: string;
/**
* The port to access on the node. If port is not provided, `host` is assumed to be in the format `{hostname}:{port}`.
*/
port?: number;
};

export type Routes =
| SingleNodeRoute
/**
Expand All @@ -75,7 +88,8 @@ export type SingleNodeRoute =
/**
* Route request to the node that contains the slot that the given key matches.
*/
| SlotKeyTypes;
| SlotKeyTypes
| RouteByAddress;

function toProtobufRoute(
route: Routes | undefined
Expand Down Expand Up @@ -124,6 +138,23 @@ function toProtobufRoute(
slotId: route.id,
}),
});
} else if (route.type === "routeByAddress") {
let port = route.port;
let host = route.host;
if (port === undefined) {
const split = host.split(":");
if (split.length !== 2) {
throw new Error(
"No port provided, expected host to be formatted as `{hostname}:{port}`. Received " +
host
);
}
host = split[0];
port = Number(split[1]);
}
return redis_request.Routes.create({
byAddressRoute: { host, port },
});
}
}

Expand Down
65 changes: 65 additions & 0 deletions node/tests/RedisClusterClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,71 @@ describe("RedisClusterClient", () => {
TIMEOUT
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
`route by address reaches correct node_%p`,
async (protocol) => {
const client = await RedisClusterClient.createClient(
getOptions(cluster.ports(), protocol)
);
const result = (await client.customCommand(
["cluster", "nodes"],
"randomNode"
)) as string;

// check that routing without explicit port works
const host =
result
.split("\n")
.find((line) => line.includes("myself"))
?.split(" ")[1]
.split("@")[0] ?? "";

const secondResult = (await client.customCommand(
["cluster", "nodes"],
{
type: "routeByAddress",
host,
}
)) as string;

expect(result).toEqual(secondResult);

const [host2, port] = host?.split(":");

// check that routing with explicit port works
const thirdResult = (await client.customCommand(
["cluster", "nodes"],
{
type: "routeByAddress",
host: host2,
port: Number(port),
}
)) as string;

expect(result).toEqual(thirdResult);

client.close();
},
TIMEOUT
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
`fail routing by address if no port is provided_%p`,
async (protocol) => {
const client = await RedisClusterClient.createClient(
getOptions(cluster.ports(), protocol)
);
expect(() =>
client.info(undefined, {
type: "routeByAddress",
host: "foo",
})
).toThrowError();
client.close();
},
TIMEOUT
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
`config get and config set transactions test_%p`,
async (protocol) => {
Expand Down

0 comments on commit 5bf685c

Please sign in to comment.