diff --git a/modules/software-templates/synapse-workers/generic.nix b/modules/software-templates/synapse-workers/generic.nix
new file mode 100644
index 0000000..7fa3967
--- /dev/null
+++ b/modules/software-templates/synapse-workers/generic.nix
@@ -0,0 +1,152 @@
+{
+ workerName,
+ tasks,
+ dbOverrides ? { },
+ count ? 1,
+}:
+{ config, lib, ... }:
+
+#let
+# dbGroup = "medium";
+# workerName = "account_data_stream_writer";
+# tasks = [ "stream_account_data" ];
+## workerRoutes = workerLib.workerRoutes.accountData;
+# count = 1;
+#in
+let
+ workerLib = import ./lib.nix;
+ cfg = config.services.matrix-synapse;
+ enabledResources = lib.attrNames workerRoutes;
+ workers = lib.range 0 count;
+ streamTypes =
+ [ ]
+ ++ lib.optional (lib.elem "stream_account_data" tasks) "account_data"
+ ++ lib.optional (lib.elem "stream_presence" tasks) "presence"
+ ++ lib.optional (lib.elem "stream_push_rules" tasks) "push_rules"
+ ++ lib.optional (lib.elem "stream_to_device" tasks) "to_device"
+ ++ lib.optional (lib.elem "stream_typing" tasks) "typing"
+ ++ lib.optional (lib.elem "stream_receipts" tasks) "receipts"
+ ++ lib.optional (lib.elem "stream_events" tasks) "events";
+
+ # recursive update list of attrs
+# recursiveMerge = list: lib.foldl (a: b: lib.recursiveUpdate a b) (lib.head list) (lib.tail list);
+# workerRoutes = recursiveMerge (lib.map (type: workerLib.workerRoutes.${type}) streamTypes);
+in
+{
+ config = lib.mkIf (cfg.accountDataStreamWriters > 0) {
+ monitoring.synapse.workerNames = if (count == 1) then [ workerName ] else lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ stream_writers = lib.listToAttrs (
+ lib.map (stream: {
+ name = stream;
+ value = lib.map (index: "${workerName}-${toString index}") workers;
+ }) streamTypes
+ );
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = lib.recursiveUpdate (lib.recursiveUpdate config.services.matrix-synapse.settings.database {
+ application_name = "matrix-synapse (${config.services.matrix-synapse.settings.server_name}) - ${if workerName == null then throw "synapse/db.nix: workerName unspecified" else workerName}";
+ }) dbOverrides;
+
+ #region Media
+ max_upload_size = lib.mkIf (lib.elem "media_repo" tasks) "512M";
+ max_avatar_size = lib.mkIf (lib.elem "media_repo" tasks) "512M";
+ max_image_pixels = lib.mkIf (lib.elem "media_repo" tasks) "250M";
+
+ max_pending_media_uploads = lib.mkIf (lib.elem "media_repo" tasks) 512;
+ dynamic_thumbnails = lib.mkIf (lib.elem "media_repo" tasks) true;
+
+ prevent_media_downloads_from = lib.mkIf (lib.elem "media_repo" tasks) [
+ # none, give me all the media
+ ];
+ enable_authenticated_media = lib.mkIf (lib.elem "media_repo" tasks) false;
+
+ url_preview_enabled = lib.mkIf (lib.elem "media_repo" tasks) true;
+ max_spider_size = lib.mkIf (lib.elem "media_repo" tasks) "50M";
+ #endregion
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/generic/auth.nix b/modules/software-templates/synapse-workers/generic/auth.nix
new file mode 100644
index 0000000..47064be
--- /dev/null
+++ b/modules/software-templates/synapse-workers/generic/auth.nix
@@ -0,0 +1,113 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ./lib.nix;
+ dbGroup = "solo";
+ workers = lib.range 0 (cfg.authWorkers - 1);
+ workerName = "auth";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.auth;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.authWorkers > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ media_instance_running_background_jobs = lib.mkIf (lib.elem "media_repo_background" tasks) "${workerName}";
+ enable_media_repo = lib.mkIf (lib.elem "media_repo" tasks) false;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ client_max_body_size 512M;
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/generic/client-reader.nix b/modules/software-templates/synapse-workers/generic/client-reader.nix
new file mode 100644
index 0000000..9072988
--- /dev/null
+++ b/modules/software-templates/synapse-workers/generic/client-reader.nix
@@ -0,0 +1,113 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ./lib.nix;
+ dbGroup = "medium";
+ workers = lib.range 0 (cfg.clientReaders - 1);
+ workerName = "client_reader";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.clientReader;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.clientReaders > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ media_instance_running_background_jobs = lib.mkIf (lib.elem "media_repo_background" tasks) "${workerName}";
+ enable_media_repo = lib.mkIf (lib.elem "media_repo" tasks) false;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ client_max_body_size 512M;
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/generic/event-creator.nix b/modules/software-templates/synapse-workers/generic/event-creator.nix
new file mode 100644
index 0000000..e035405
--- /dev/null
+++ b/modules/software-templates/synapse-workers/generic/event-creator.nix
@@ -0,0 +1,113 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ./lib.nix;
+ dbGroup = "medium";
+ workers = lib.range 0 (cfg.eventCreators - 1);
+ workerName = "event_creator";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.eventCreator;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.eventCreators > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ media_instance_running_background_jobs = lib.mkIf (lib.elem "media_repo_background" tasks) "${workerName}";
+ enable_media_repo = lib.mkIf (lib.elem "media_repo" tasks) false;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ client_max_body_size 512M;
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/generic/federation-inbound.nix b/modules/software-templates/synapse-workers/generic/federation-inbound.nix
new file mode 100644
index 0000000..af18e8e
--- /dev/null
+++ b/modules/software-templates/synapse-workers/generic/federation-inbound.nix
@@ -0,0 +1,113 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ./lib.nix;
+ dbGroup = "medium";
+ workers = lib.range 0 (cfg.federationReaders - 1);
+ workerName = "federation_inbound";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.federationInbound;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.federationInboundWorkers > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ media_instance_running_background_jobs = lib.mkIf (lib.elem "media_repo_background" tasks) "${workerName}";
+ enable_media_repo = lib.mkIf (lib.elem "media_repo" tasks) false;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ client_max_body_size 512M;
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/generic/federation-reader.nix b/modules/software-templates/synapse-workers/generic/federation-reader.nix
new file mode 100644
index 0000000..09e8419
--- /dev/null
+++ b/modules/software-templates/synapse-workers/generic/federation-reader.nix
@@ -0,0 +1,113 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ./lib.nix;
+ dbGroup = "medium";
+ workers = lib.range 0 (cfg.federationReaders - 1);
+ workerName = "federation_reader";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.federationReader;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.federationReaders > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ media_instance_running_background_jobs = lib.mkIf (lib.elem "media_repo_background" tasks) "${workerName}";
+ enable_media_repo = lib.mkIf (lib.elem "media_repo" tasks) false;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ client_max_body_size 512M;
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/generic/federation-sender.nix b/modules/software-templates/synapse-workers/generic/federation-sender.nix
new file mode 100644
index 0000000..bf6cf51
--- /dev/null
+++ b/modules/software-templates/synapse-workers/generic/federation-sender.nix
@@ -0,0 +1,131 @@
+{ config, lib, ... }:
+let
+ cfg = config.services.matrix-synapse;
+ dbGroup = "medium";
+ workers = lib.range 0 (cfg.federationSenders - 1);
+ workerName = "federation_sender";
+ tasks = [ ];
+ workerRoutes = {};
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.federationSenders > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ # Federation sender
+ send_federation = lib.mkIf (lib.elem "federation_sender" tasks) false;
+ federation_sender_instances = lib.mkIf (lib.elem "federation_sender" tasks) [ workerName ];
+ outbound_federation_restricted_to = lib.mkIf (lib.elem "federation_sender" tasks) [ workerName ];
+ worker_replication_secret = "${workerName}_secret";
+
+ # Pusher
+ pusher_instances = lib.optional (lib.elem "pusher" tasks) "${workerName}";
+
+ # Media repo
+ media_instance_running_background_jobs = lib.mkIf (lib.elem "media_repo_background" tasks) "${workerName}";
+ enable_media_repo = lib.mkIf (lib.elem "media_repo" tasks) false;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+
+ # Media repo
+ enable_media_repo = lib.elem "media_repo" tasks;
+ rc_federation = {
+ window_size = 1;
+ sleep_limit = 1000;
+ sleep_delay = 1;
+ reject_limit = 1000;
+ concurrent = 100;
+ };
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ client_max_body_size 512M;
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/generic/media-repo.nix b/modules/software-templates/synapse-workers/generic/media-repo.nix
new file mode 100644
index 0000000..d9db8cf
--- /dev/null
+++ b/modules/software-templates/synapse-workers/generic/media-repo.nix
@@ -0,0 +1,113 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ./lib.nix;
+ dbGroup = "solo";
+ workers = lib.range 0 (cfg.mediaRepoWorkers - 1);
+ workerName = "media_repo";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.mediaRepo;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.mediaRepoWorkers > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ media_instance_running_background_jobs = lib.mkIf (lib.elem "media_repo_background" tasks) "${workerName}";
+ enable_media_repo = lib.mkIf (lib.elem "media_repo" tasks) false;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ client_max_body_size 512M;
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/generic/pusher.nix b/modules/software-templates/synapse-workers/generic/pusher.nix
new file mode 100644
index 0000000..8c6b697
--- /dev/null
+++ b/modules/software-templates/synapse-workers/generic/pusher.nix
@@ -0,0 +1,112 @@
+{ config, lib, ... }:
+let
+ cfg = config.services.matrix-synapse;
+ dbGroup = "small";
+ workers = lib.range 0 (cfg.pushers - 1);
+ workerName = "pusher";
+ tasks = [ ];
+ workerRoutes = {};
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.pushers > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ pusher_instances = lib.mkIf (lib.elem "pusher" tasks) "${workerName}";
+ media_instance_running_background_jobs = lib.mkIf (lib.elem "media_repo_background" tasks) "${workerName}";
+ enable_media_repo = lib.mkIf (lib.elem "media_repo" tasks) false;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ client_max_body_size 512M;
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/generic/sync.nix b/modules/software-templates/synapse-workers/generic/sync.nix
new file mode 100644
index 0000000..eb47e59
--- /dev/null
+++ b/modules/software-templates/synapse-workers/generic/sync.nix
@@ -0,0 +1,113 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ./lib.nix;
+ dbGroup = "medium";
+ workers = lib.range 0 (cfg.syncWorkers - 1);
+ workerName = "sync";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.sync;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.syncWorkers > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ media_instance_running_background_jobs = lib.mkIf (lib.elem "media_repo_background" tasks) "${workerName}";
+ enable_media_repo = lib.mkIf (lib.elem "media_repo" tasks) false;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ client_max_body_size 512M;
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/lib.nix b/modules/software-templates/synapse-workers/lib.nix
new file mode 100644
index 0000000..c99e2ef
--- /dev/null
+++ b/modules/software-templates/synapse-workers/lib.nix
@@ -0,0 +1,147 @@
+{
+ workerRoutes = {
+ sync.client = [
+ "~ ^/_matrix/client/(v2_alpha|r0|v3)/sync$"
+ "~ ^/_matrix/client/(api/v1|v2_alpha|r0|v3)/events$"
+ "~ ^/_matrix/client/(api/v1|r0|v3)/initialSync$"
+ "~ ^/_matrix/client/(api/v1|r0|v3)/rooms/[^/]+/initialSync$"
+ "~ ^/_matrix/client/unstable/org.matrix.simplified_msc3575/sync$"
+ ];
+
+ clientReader.client = [
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/publicRooms$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/joined_members$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/context/.*$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/members$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/state(/|$)"
+ "~ ^/_matrix/client/v1/rooms/.*/hierarchy$"
+ "~ ^/_matrix/client/(v1|unstable)/rooms/.*/relations/"
+ "~ ^/_matrix/client/v1/rooms/.*/threads$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/messages$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/event"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/joined_rooms"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable/.*)/rooms/.*/aliases"
+ "~ ^/_matrix/client/v1/rooms/.*/timestamp_to_event$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/search"
+ "~ ^/_matrix/client/(r0|v3|unstable)/user/.*/filter(/|$)"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/directory/room/.*$"
+ "~ ^/_matrix/client/(r0|v3|unstable)/notifications$"
+ # e2ee
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/keys/query$"
+
+ # unstable
+ "~ ^/_matrix/client/unstable/im.nheko.summary/rooms/.*/summary$"
+
+ # auth
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/login$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/account/3pid$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/account/whoami$"
+ "~ ^/_matrix/client/versions$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/voip/turnServer$"
+ "~ ^/_matrix/client/(r0|v3|unstable)/register$"
+ "~ ^/_matrix/client/(r0|v3|unstable)/register/available$"
+ "~ ^/_matrix/client/(r0|v3|unstable)/auth/.*/fallback/web$"
+ "~ ^/_matrix/client/(r0|v3|unstable)/password_policy$"
+ "~ ^/_matrix/client/(r0|v3|unstable)/capabilities$"
+ ];
+
+ eventCreator.client = [
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/redact"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/send"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/(join|invite|leave|ban|unban|kick)$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/join/"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/knock/"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/profile/"
+ ];
+
+ federationInbound.federation = [
+ "~ ^/_matrix/federation/(v1|v2)/send/"
+ ];
+
+ federationReader.federation = [
+ "~ ^/_matrix/federation/(v1|v2)/event/"
+ "~ ^/_matrix/federation/(v1|v2)/state/"
+ "~ ^/_matrix/federation/(v1|v2)/state_ids/"
+ "~ ^/_matrix/federation/(v1|v2)/backfill/"
+ "~ ^/_matrix/federation/(v1|v2)/get_missing_events/"
+ "~ ^/_matrix/federation/(v1|v2)/publicRooms"
+ "~ ^/_matrix/federation/(v1|v2)/query/"
+ "~ ^/_matrix/federation/(v1|v2)/make_join/"
+ "~ ^/_matrix/federation/(v1|v2)/make_leave/"
+ "~ ^/_matrix/federation/(v1|v2)/send_join/"
+ "~ ^/_matrix/federation/(v1|v2)/send_leave/"
+ "~ ^/_matrix/federation/v1/make_knock/"
+ "~ ^/_matrix/federation/v1/send_knock/"
+ "~ ^/_matrix/federation/(v1|v2)/invite/" # Needs special handling, define manually
+ "~ ^/_matrix/federation/(v1|v2)/query_auth/"
+ "~ ^/_matrix/federation/(v1|v2)/event_auth/"
+ "~ ^/_matrix/federation/v1/timestamp_to_event/"
+ "~ ^/_matrix/federation/(v1|v2)/exchange_third_party_invite/"
+ "~ ^/_matrix/federation/(v1|v2)/user/devices/"
+ "~ ^/_matrix/federation/(v1|v2)/get_groups_publicised$"
+ "~ ^/_matrix/key/v2/query"
+ # extra
+ "~ ^/_matrix/key/v2/server$"
+ ];
+
+ mediaRepo.media = [
+ "~ ^/_matrix/client/v1/media/"
+ "~ ^/_matrix/federation/v1/media/"
+ "~ ^/_synapse/admin/v1/purge_media_cache$"
+ "~ ^/_synapse/admin/v1/room/.*/media.*$"
+ "~ ^/_synapse/admin/v1/user/.*/media.*$"
+ "~ ^/_synapse/admin/v1/users/.*/media$"
+ "~ ^/_synapse/admin/v1/media/.*$"
+ "~ ^/_synapse/admin/v1/quarantine_media/.*$"
+ "~ ^/_matrix/media/"
+ ];
+
+ auth.client = [
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/login$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/account/3pid$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/account/whoami$"
+ "~ ^/_matrix/client/versions$"
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/voip/turnServer$"
+ "~ ^/_matrix/client/(r0|v3|unstable)/register$"
+ "~ ^/_matrix/client/(r0|v3|unstable)/register/available$"
+ "~ ^/_matrix/client/(r0|v3|unstable)/auth/.*/fallback/web$"
+ "~ ^/_matrix/client/(r0|v3|unstable)/password_policy$"
+ "~ ^/_matrix/client/(r0|v3|unstable)/capabilities$"
+ ];
+
+ typing.client = [
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/rooms/.*/typing"
+ ];
+
+ toDevice.client = [
+ "~ ^/_matrix/client/(r0|v3|unstable)/sendToDevice/"
+ ];
+
+ receipts.client = [
+ "~ ^/_matrix/client/(r0|v3|unstable)/rooms/.*/receipt"
+ "~ ^/_matrix/client/(r0|v3|unstable)/rooms/.*/read_markers"
+ ];
+
+ pushRules.client = [
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/pushrules/"
+ ];
+
+ presence.client = [
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/presence/"
+ ];
+
+ accountData.client = [
+ "~ ^/_matrix/client/(r0|v3|unstable)/account_data"
+ "~ ^/_matrix/client/(r0|v3|unstable)/rooms/.*/account_data"
+ "~ ^/_matrix/client/(r0|v3|unstable)/rooms/.*/tags"
+ ];
+
+ userDirectory.client = [
+ "~ ^/_matrix/client/(api/v1|r0|v3|unstable)/user_directory/search$"
+
+ #profile
+ "~ ^/_matrix/client/v3/profile/.*$"
+ "~ ^/_matrix/client/v3/profile/.*/(displayname|avatar_url)$"
+ ];
+ };
+}
diff --git a/modules/software-templates/synapse-workers/module.nix b/modules/software-templates/synapse-workers/module.nix
new file mode 100644
index 0000000..b1d0ced
--- /dev/null
+++ b/modules/software-templates/synapse-workers/module.nix
@@ -0,0 +1,108 @@
+{ config, lib, ... }:
+let
+ cfg = config.services.matrix-synapse;
+ mkIntOption =
+ description:
+ lib.mkOption {
+ type = lib.types.int;
+ default = 0;
+ description = description;
+ };
+in
+{
+ imports = [
+ ];
+ options.services.matrix-synapse = {
+ enableWorkers = lib.mkEnableOption "Enable dedicated workers";
+ enableStreamWriters = lib.mkEnableOption "Enable stream writers";
+ enableAppserviceWorker = lib.mkEnableOption "Enable dedicated appservice worker";
+ enableBackgroundWorker = lib.mkEnableOption "Enable dedicated background task worker";
+ enableUserDirWorker = lib.mkEnableOption "Enable dedicated user directory worker";
+
+ authWorkers = mkIntOption "Number of auth workers";
+ clientReaders = mkIntOption "Number of client readers";
+ eventCreators = mkIntOption "Number of auth workers";
+ federationInboundWorkers = mkIntOption "Number of federation inbound workers";
+ federationReaders = mkIntOption "Number of federation readers";
+ federationSenders = mkIntOption "Number of federation senders";
+ mediaRepoWorkers = mkIntOption "Number of media repo workers";
+ pushers = mkIntOption "Number of pushers";
+ syncWorkers = mkIntOption "Number of sync workers";
+
+ #stream writers
+ eventStreamWriters = mkIntOption "Number of event stream writers";
+ typingStreamWriters = mkIntOption "Number of typing stream writers";
+ toDeviceStreamWriters = mkIntOption "Number of to_device stream writers";
+ accountDataStreamWriters = mkIntOption "Number of account data stream writers";
+ receiptStreamWriters = mkIntOption "Number of read receipt stream writers";
+ presenceStreamWriters = mkIntOption "Number of presence stream writers";
+ pushRuleStreamWriters = mkIntOption "Number of push rule stream writers";
+
+ sharedStreamWriters = mkIntOption "Number of shared stream writers";
+
+ nginxVirtualHostName = lib.mkOption {
+ type = lib.types.str;
+ default = null;
+ description = "The virtual host name for the nginx server";
+ };
+
+ allowedRemoteInviteOrigins = lib.mkOption {
+ type = lib.types.listOf lib.types.str;
+ default = [ ];
+ description = "List of allowed remote invite origins";
+ };
+ };
+
+ config = {
+ assertions =
+ [
+ {
+ assertion = cfg.enableWorkers -> cfg.nginxVirtualHostName != null;
+ message = "nginxVirtualHostName must be set when enableWorkers is true";
+ }
+ ]
+ ++ lib.optionals (cfg.settings ? stream_writers) [
+ # Stream types and count limitations: https://github.com/element-hq/synapse/blob/develop/synapse/config/workers.py#L344
+ {
+ assertion = cfg.settings.stream_writers ? typing -> lib.length cfg.settings.stream_writers.typing <= 1;
+ message = "Only one typing stream writer is supported";
+ }
+ {
+ assertion = cfg.settings.stream_writers ? to_device -> lib.length cfg.settings.stream_writers.to_device <= 1;
+ message = "Only one to_device stream writer is supported";
+ }
+ {
+ assertion = cfg.settings.stream_writers ? account_data -> lib.length cfg.settings.stream_writers.account_data <= 1;
+ message = "Only one account data stream writer is supported";
+ }
+ # This may be outdated in the documentation...?
+ #{
+ # assertion = cfg.receiptStreamWriters <= 1;
+ # message = "Only one receipt stream writer is supported";
+ #}
+ {
+ assertion = cfg.settings.stream_writers ? presence -> lib.length cfg.settings.stream_writers.presence <= 1;
+ message = "Only one presence stream writer is supported";
+ }
+ {
+ assertion = cfg.settings.stream_writers ? push_rules -> lib.length cfg.settings.stream_writers.push_rules <= 1;
+ message = "Only one push rule stream writer is supported";
+ }
+ ];
+
+ # Matrix utility maps
+ services.nginx.appendHttpConfig = ''
+ # Map authorization header to origin name
+ map $http_authorization $mx_origin_name {
+ default "";
+ "~*X-Matrix origin=(?<origin>[^,]+)" $origin;
+ }
+
+ # Map origin name to whether it can invite
+ map $mx_origin_name $mx_can_invite {
+ default 0;
+ ${lib.concatMapStringsSep "\n" (origin: " \"${origin}\" 1;") cfg.allowedRemoteInviteOrigins}
+ }
+ '';
+ };
+}
diff --git a/modules/software-templates/synapse-workers/single/appservice.nix b/modules/software-templates/synapse-workers/single/appservice.nix
new file mode 100644
index 0000000..03a080b
--- /dev/null
+++ b/modules/software-templates/synapse-workers/single/appservice.nix
@@ -0,0 +1,77 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ../lib.nix;
+ dbGroup = "small";
+ workerName = "appservice";
+ tasks = [ "appservice" ];
+ workerRoutes = {};
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (lib.length tasks > 0) {
+ monitoring.synapse.workerNames = [ workerName ];
+ services.matrix-synapse = {
+ settings = {
+ instance_map = {
+ ${workerName} = {
+ path = "/run/matrix-synapse/${workerName}.sock";
+ };
+ };
+
+ run_background_tasks_on = lib.mkIf (lib.elem "background" tasks) workerName;
+ notify_appservices_from_worker = lib.mkIf (lib.elem "appservice" tasks) workerName;
+ update_user_directory_from_worker = lib.mkIf (lib.elem "user_directory" tasks) workerName;
+ };
+
+ workers = {
+ ${workerName} = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+
+ database = (import ../../db.nix { inherit workerName dbGroup; });
+ };
+ };
+ };
+
+ services.nginx = {
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://unix:/run/matrix-synapse/${workerName}-${type}.sock";
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/single/background.nix b/modules/software-templates/synapse-workers/single/background.nix
new file mode 100644
index 0000000..741b88c
--- /dev/null
+++ b/modules/software-templates/synapse-workers/single/background.nix
@@ -0,0 +1,77 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ../lib.nix;
+ dbGroup = "small";
+ workerName = "background";
+ tasks = [ "background" ];
+ workerRoutes = { };
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (lib.length tasks > 0) {
+ monitoring.synapse.workerNames = [ workerName ];
+ services.matrix-synapse = {
+ settings = {
+ instance_map = {
+ ${workerName} = {
+ path = "/run/matrix-synapse/${workerName}.sock";
+ };
+ };
+
+ run_background_tasks_on = lib.mkIf (lib.elem "background" tasks) workerName;
+ notify_appservices_from_worker = lib.mkIf (lib.elem "appservice" tasks) workerName;
+ update_user_directory_from_worker = lib.mkIf (lib.elem "user_directory" tasks) workerName;
+ };
+
+ workers = {
+ ${workerName} = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+
+ database = (import ../../db.nix { inherit workerName dbGroup; });
+ };
+ };
+ };
+
+ services.nginx = {
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://unix:/run/matrix-synapse/${workerName}-${type}.sock";
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/single/user-dir.nix b/modules/software-templates/synapse-workers/single/user-dir.nix
new file mode 100644
index 0000000..97ddf26
--- /dev/null
+++ b/modules/software-templates/synapse-workers/single/user-dir.nix
@@ -0,0 +1,77 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ../lib.nix;
+ dbGroup = "small";
+ workerName = "user_dir";
+ tasks = [ "user_directory" ];
+ workerRoutes = workerLib.workerRoutes.userDirectory;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (lib.length tasks > 0) {
+ monitoring.synapse.workerNames = [ workerName ];
+ services.matrix-synapse = {
+ settings = {
+ instance_map = {
+ ${workerName} = {
+ path = "/run/matrix-synapse/${workerName}.sock";
+ };
+ };
+
+ run_background_tasks_on = lib.mkIf (lib.elem "background" tasks) workerName;
+ notify_appservices_from_worker = lib.mkIf (lib.elem "appservice" tasks) workerName;
+ update_user_directory_from_worker = lib.mkIf (lib.elem "user_directory" tasks) workerName;
+ };
+
+ workers = {
+ ${workerName} = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+
+ database = (import ../../db.nix { inherit workerName dbGroup; });
+ };
+ };
+ };
+
+ services.nginx = {
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://unix:/run/matrix-synapse/${workerName}-${type}.sock";
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/stream-writers/account_data-stream-writer.nix b/modules/software-templates/synapse-workers/stream-writers/account_data-stream-writer.nix
new file mode 100644
index 0000000..3f8363a
--- /dev/null
+++ b/modules/software-templates/synapse-workers/stream-writers/account_data-stream-writer.nix
@@ -0,0 +1,130 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ../lib.nix;
+ dbGroup = "medium";
+# streamWriterType = "account_data";
+ workers = lib.range 0 (cfg.accountDataStreamWriters - 1);
+ workerName = "account_data_stream_writer";
+ tasks = [ "stream_account_data" ];
+ workerRoutes = workerLib.workerRoutes.accountData;
+in
+let
+ enabledResources = lib.attrNames workerRoutes;
+ streamTypes = []
+ ++ lib.optional (lib.elem "stream_account_data" tasks) "account_data"
+ ++ lib.optional (lib.elem "stream_presence" tasks) "presence"
+ ++ lib.optional (lib.elem "stream_push_rules" tasks) "push_rules"
+ ++ lib.optional (lib.elem "stream_to_device" tasks) "to_device"
+ ++ lib.optional (lib.elem "stream_typing" tasks) "typing"
+ ++ lib.optional (lib.elem "stream_receipts" tasks) "receipts"
+ ++ lib.optional (lib.elem "stream_events" tasks) "events";
+in
+{
+ config = lib.mkIf (cfg.accountDataStreamWriters > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ #stream_writers.${streamWriterType} = lib.map (index: "${workerName}-${toString index}") workers;
+# stream_writers = lib.listToA
+ # map `streams` to `workers`
+ stream_writers = lib.listToAttrs (
+ lib.map (stream: {
+ name = stream;
+ value = lib.map (index: "${workerName}-${toString index}") workers;
+ }) streamTypes
+ );
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/stream-writers/event-stream-writer.nix b/modules/software-templates/synapse-workers/stream-writers/event-stream-writer.nix
new file mode 100644
index 0000000..6abce3f
--- /dev/null
+++ b/modules/software-templates/synapse-workers/stream-writers/event-stream-writer.nix
@@ -0,0 +1,111 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ dbGroup = "medium";
+ streamWriterType = "events";
+ workers = lib.range 0 (cfg.eventStreamWriters - 1);
+ workerName = "event_stream_writer";
+ tasks = [ ];
+ workerRoutes = {};
+ enabledResources = [];
+in
+{
+ config = lib.mkIf (cfg.eventStreamWriters > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ stream_writers.${streamWriterType} = lib.map (index: "${workerName}-${toString index}") workers;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/stream-writers/presence-stream-writer.nix b/modules/software-templates/synapse-workers/stream-writers/presence-stream-writer.nix
new file mode 100644
index 0000000..052f037
--- /dev/null
+++ b/modules/software-templates/synapse-workers/stream-writers/presence-stream-writer.nix
@@ -0,0 +1,112 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ../lib.nix;
+ dbGroup = "medium";
+ streamWriterType = "presence";
+ workers = lib.range 0 (cfg.presenceStreamWriters - 1);
+ workerName = "presence_stream_writer";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.presence;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.presenceStreamWriters > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ stream_writers.${streamWriterType} = lib.map (index: "${workerName}-${toString index}") workers;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/stream-writers/push_rule-stream-writer.nix b/modules/software-templates/synapse-workers/stream-writers/push_rule-stream-writer.nix
new file mode 100644
index 0000000..6bba28d
--- /dev/null
+++ b/modules/software-templates/synapse-workers/stream-writers/push_rule-stream-writer.nix
@@ -0,0 +1,112 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ../lib.nix;
+ dbGroup = "medium";
+ streamWriterType = "push_rules";
+ workers = lib.range 0 (cfg.pushRuleStreamWriters - 1);
+ workerName = "push_rule_stream_writer";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.pushRules;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.pushRuleStreamWriters > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ stream_writers.${streamWriterType} = lib.map (index: "${workerName}-${toString index}") workers;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/stream-writers/receipt-stream-writer.nix b/modules/software-templates/synapse-workers/stream-writers/receipt-stream-writer.nix
new file mode 100644
index 0000000..37a5287
--- /dev/null
+++ b/modules/software-templates/synapse-workers/stream-writers/receipt-stream-writer.nix
@@ -0,0 +1,112 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ../lib.nix;
+ dbGroup = "medium";
+ streamWriterType = "receipts";
+ workers = lib.range 0 (cfg.receiptStreamWriters - 1);
+ workerName = "receipts_stream_writer";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.receipts;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.receiptStreamWriters > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ stream_writers.${streamWriterType} = lib.map (index: "${workerName}-${toString index}") workers;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/stream-writers/to_device-stream-writer.nix b/modules/software-templates/synapse-workers/stream-writers/to_device-stream-writer.nix
new file mode 100644
index 0000000..eb01af9
--- /dev/null
+++ b/modules/software-templates/synapse-workers/stream-writers/to_device-stream-writer.nix
@@ -0,0 +1,112 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ../lib.nix;
+ dbGroup = "medium";
+ streamWriterType = "to_device";
+ workers = lib.range 0 (cfg.toDeviceStreamWriters - 1);
+ workerName = "to_device_stream_writer";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.toDevice;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.toDeviceStreamWriters > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ stream_writers.${streamWriterType} = lib.map (index: "${workerName}-${toString index}") workers;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
diff --git a/modules/software-templates/synapse-workers/stream-writers/typing-stream-writer.nix b/modules/software-templates/synapse-workers/stream-writers/typing-stream-writer.nix
new file mode 100644
index 0000000..dadc34a
--- /dev/null
+++ b/modules/software-templates/synapse-workers/stream-writers/typing-stream-writer.nix
@@ -0,0 +1,112 @@
+{ config, lib, ... }:
+
+let
+ cfg = config.services.matrix-synapse;
+ workerLib = import ../lib.nix;
+ dbGroup = "medium";
+ streamWriterType = "typing";
+ workers = lib.range 0 (cfg.typingStreamWriters - 1);
+ workerName = "typing_stream_writer";
+ tasks = [ ];
+ workerRoutes = workerLib.workerRoutes.typing;
+ enabledResources = lib.attrNames workerRoutes;
+in
+{
+ config = lib.mkIf (cfg.typingStreamWriters > 0) {
+ monitoring.synapse.workerNames = lib.map (index: "${workerName}-${toString index}") workers;
+ services.matrix-synapse = {
+ settings = {
+ instance_map = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ };
+ }) workers
+ );
+
+ stream_writers.${streamWriterType} = lib.map (index: "${workerName}-${toString index}") workers;
+ };
+
+ workers = lib.listToAttrs (
+ lib.map (index: {
+ name = "${workerName}-${toString index}";
+ value = {
+ worker_app = "synapse.app.generic_worker";
+ worker_listeners =
+ [
+ {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${toString index}.sock";
+ resources = [
+ {
+ names = [ "replication" ];
+ compress = false;
+ }
+ ];
+ }
+ ]
+ ++ lib.map (type: {
+ type = "http";
+ path = "/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ mode = "666";
+ resources = [
+ {
+ names = [ type ];
+ compress = false;
+ }
+ ];
+ }) enabledResources;
+ database = (
+ import ../../db.nix {
+ inherit dbGroup;
+ workerName = "${workerName}-${toString index}";
+ }
+ );
+ };
+ }) workers
+ );
+ };
+
+ services.nginx = {
+ upstreams = lib.listToAttrs (
+ lib.map (type: {
+ name = "${workerName}-${type}";
+ value = {
+ extraConfig = ''
+ keepalive 32;
+ least_conn;
+ '';
+ servers = lib.listToAttrs (
+ lib.map (index: {
+ name = "unix:/run/matrix-synapse/${workerName}-${type}-${toString index}.sock";
+ value = {
+ max_fails = 0;
+ fail_timeout = "0s";
+ };
+ }) workers
+ );
+ };
+ }) enabledResources
+ );
+
+ virtualHosts."${cfg.nginxVirtualHostName}".locations = lib.listToAttrs (
+ lib.flatten (
+ lib.forEach enabledResources (
+ type:
+ lib.map (route: {
+ name = route;
+ value = {
+ proxyPass = "http://${workerName}-${type}";
+ extraConfig = ''
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ '';
+ };
+ }) workerRoutes.${type}
+ )
+ )
+ );
+ };
+ };
+}
|