f27f3cdc10
Redis shards list must be consistent between Centrifugo nodes. Before this change, NixOS tests were using invalid configurtaion since shards[hash(ch)] may select different Redis shard instance on each Centrifugo node. We don’t currently have any tests that exposed this behavior though.
79 lines
2.3 KiB
Nix
79 lines
2.3 KiB
Nix
let
|
|
redisPort = 6379;
|
|
centrifugoPort = 8080;
|
|
nodes = [
|
|
"centrifugo1"
|
|
"centrifugo2"
|
|
"centrifugo3"
|
|
];
|
|
in
|
|
{ lib, ... }: {
|
|
name = "centrifugo";
|
|
meta.maintainers = [ lib.maintainers.tie ];
|
|
|
|
nodes = lib.listToAttrs (lib.imap0
|
|
(index: name: {
|
|
inherit name;
|
|
value = { config, ... }: {
|
|
services.centrifugo = {
|
|
enable = true;
|
|
settings = {
|
|
inherit name;
|
|
port = centrifugoPort;
|
|
# See https://centrifugal.dev/docs/server/engines#redis-sharding
|
|
engine = "redis";
|
|
# Connect to local Redis shard via Unix socket.
|
|
redis_address =
|
|
let toRedisAddresses = map (name: "${name}:${toString redisPort}"); in
|
|
toRedisAddresses (lib.take index nodes) ++ [
|
|
"unix://${config.services.redis.servers.centrifugo.unixSocket}"
|
|
] ++ toRedisAddresses (lib.drop (index + 1) nodes);
|
|
usage_stats_disable = true;
|
|
api_insecure = true;
|
|
};
|
|
extraGroups = [
|
|
config.services.redis.servers.centrifugo.user
|
|
];
|
|
};
|
|
services.redis.servers.centrifugo = {
|
|
enable = true;
|
|
bind = null; # all interfaces
|
|
port = redisPort;
|
|
openFirewall = true;
|
|
settings.protected-mode = false;
|
|
};
|
|
};
|
|
})
|
|
nodes);
|
|
|
|
testScript = ''
|
|
import json
|
|
|
|
redisPort = ${toString redisPort}
|
|
centrifugoPort = ${toString centrifugoPort}
|
|
|
|
start_all()
|
|
|
|
for machine in machines:
|
|
machine.wait_for_unit("redis-centrifugo.service")
|
|
machine.wait_for_open_port(redisPort)
|
|
|
|
for machine in machines:
|
|
machine.wait_for_unit("centrifugo.service")
|
|
machine.wait_for_open_port(centrifugoPort)
|
|
|
|
# See https://centrifugal.dev/docs/server/server_api#info
|
|
def list_nodes(machine):
|
|
curl = "curl --fail-with-body --silent"
|
|
body = "{}"
|
|
resp = json.loads(machine.succeed(f"{curl} -d '{body}' http://localhost:{centrifugoPort}/api/info"))
|
|
return resp["result"]["nodes"]
|
|
machineNames = {m.name for m in machines}
|
|
for machine in machines:
|
|
nodes = list_nodes(machine)
|
|
assert len(nodes) == len(machines)
|
|
nodeNames = {n['name'] for n in nodes}
|
|
assert machineNames == nodeNames
|
|
'';
|
|
}
|