|
| 1 | +let |
| 2 | + region = "us-east-2"; |
| 3 | + accessKeyId = "default"; |
| 4 | +in { |
| 5 | + network.storage.legacy = { |
| 6 | + databasefile = ".deployments.nixops"; |
| 7 | + }; |
| 8 | + |
| 9 | + network.description = "pg_net load testing setup"; |
| 10 | + |
| 11 | + resources = { |
| 12 | + ec2KeyPairs.netKP = { inherit region accessKeyId; }; |
| 13 | + vpc.netVpc = { |
| 14 | + inherit region accessKeyId; |
| 15 | + enableDnsSupport = true; |
| 16 | + enableDnsHostnames = true; |
| 17 | + cidrBlock = "10.0.0.0/24"; |
| 18 | + }; |
| 19 | + vpcSubnets.netSubnet = {resources, ...}: { |
| 20 | + inherit region accessKeyId; |
| 21 | + zone = "${region}a"; |
| 22 | + vpcId = resources.vpc.netVpc; |
| 23 | + cidrBlock = "10.0.0.0/24"; |
| 24 | + mapPublicIpOnLaunch = true; |
| 25 | + }; |
| 26 | + vpcInternetGateways.netIG = { resources, ... }: { |
| 27 | + inherit region accessKeyId; |
| 28 | + vpcId = resources.vpc.netVpc; |
| 29 | + }; |
| 30 | + vpcRouteTables.netRT = { resources, ... }: { |
| 31 | + inherit region accessKeyId; |
| 32 | + vpcId = resources.vpc.netVpc; |
| 33 | + }; |
| 34 | + vpcRoutes.netIGRoute = { resources, ... }: { |
| 35 | + inherit region accessKeyId; |
| 36 | + routeTableId = resources.vpcRouteTables.netRT; |
| 37 | + destinationCidrBlock = "0.0.0.0/0"; |
| 38 | + gatewayId = resources.vpcInternetGateways.netIG; |
| 39 | + }; |
| 40 | + vpcRouteTableAssociations.netTblAssoc = { resources, ... }: { |
| 41 | + inherit region accessKeyId; |
| 42 | + subnetId = resources.vpcSubnets.netSubnet; |
| 43 | + routeTableId = resources.vpcRouteTables.netRT; |
| 44 | + }; |
| 45 | + ec2SecurityGroups.netSecGroup = {resources, ...}: { |
| 46 | + inherit region accessKeyId; |
| 47 | + vpcId = resources.vpc.netVpc; |
| 48 | + rules = [ |
| 49 | + { fromPort = 80; toPort = 80; sourceIp = "0.0.0.0/0"; } |
| 50 | + { fromPort = 22; toPort = 22; sourceIp = "0.0.0.0/0"; } |
| 51 | + { fromPort = 0; toPort = 65535; sourceIp = resources.vpcSubnets.netSubnet.cidrBlock; } |
| 52 | + ]; |
| 53 | + }; |
| 54 | + }; |
| 55 | + |
| 56 | + server = { config, pkgs, resources, ... }: { |
| 57 | + deployment = { |
| 58 | + targetEnv = "ec2"; |
| 59 | + ec2 = { |
| 60 | + inherit region accessKeyId; |
| 61 | + instanceType = "t3a.micro"; |
| 62 | + associatePublicIpAddress = true; |
| 63 | + keyPair = resources.ec2KeyPairs.netKP; |
| 64 | + subnetId = resources.vpcSubnets.netSubnet; |
| 65 | + securityGroupIds = [resources.ec2SecurityGroups.netSecGroup.name]; |
| 66 | + }; |
| 67 | + }; |
| 68 | + |
| 69 | + services.nginx = { |
| 70 | + enable = true; |
| 71 | + package = (pkgs.callPackage ./nginxCustom.nix {}).customNginx; |
| 72 | + config = '' |
| 73 | + worker_processes auto; |
| 74 | + events { |
| 75 | + worker_connections 1024; |
| 76 | + } |
| 77 | + http { |
| 78 | + server { |
| 79 | + listen 0.0.0.0:80 ; |
| 80 | + listen [::]:80 ; |
| 81 | + server_name localhost; |
| 82 | + ${builtins.readFile nginx/conf/custom.conf} |
| 83 | + } |
| 84 | + } |
| 85 | + ''; |
| 86 | + }; |
| 87 | + networking.firewall.allowedTCPPorts = [ 80 ]; |
| 88 | + }; |
| 89 | + |
| 90 | + client = { config, pkgs, nodes, resources, ... }: { |
| 91 | + deployment = { |
| 92 | + targetEnv = "ec2"; |
| 93 | + ec2 = { |
| 94 | + inherit region accessKeyId; |
| 95 | + instanceType = "t3a.micro"; |
| 96 | + associatePublicIpAddress = true; |
| 97 | + ebsInitialRootDiskSize = 6; |
| 98 | + keyPair = resources.ec2KeyPairs.netKP; |
| 99 | + subnetId = resources.vpcSubnets.netSubnet; |
| 100 | + securityGroupIds = [resources.ec2SecurityGroups.netSecGroup.name]; |
| 101 | + }; |
| 102 | + }; |
| 103 | + |
| 104 | + services.postgresql = { |
| 105 | + enable = true; |
| 106 | + package = pkgs.postgresql_15.withPackages (p: [ |
| 107 | + (pkgs.callPackage ./pg_net.nix { postgresql = pkgs.postgresql_15;}) |
| 108 | + ]); |
| 109 | + authentication = pkgs.lib.mkOverride 10 '' |
| 110 | + local all all trust |
| 111 | + ''; |
| 112 | + settings = { |
| 113 | + shared_preload_libraries = "pg_net"; |
| 114 | + }; |
| 115 | + initialScript = pkgs.writeText "init-sql-script" '' |
| 116 | + create extension pg_net; |
| 117 | +
|
| 118 | + alter system set pg_net.batch_size to 32000; |
| 119 | +
|
| 120 | + select net.worker_restart(); |
| 121 | +
|
| 122 | + create view pg_net_stats as |
| 123 | + select |
| 124 | + count(*) filter (where error_msg is null) as request_successes, |
| 125 | + count(*) filter (where error_msg is not null) as request_failures, |
| 126 | + (select error_msg from net._http_response where error_msg is not null order by id desc limit 1) as last_failure_error |
| 127 | + from net._http_response; |
| 128 | + ''; |
| 129 | + }; |
| 130 | + |
| 131 | + networking.hosts = { |
| 132 | + "${nodes.server.config.networking.privateIPv4}" = [ "server" ]; |
| 133 | + }; |
| 134 | + |
| 135 | + environment.systemPackages = [ |
| 136 | + pkgs.vegeta |
| 137 | + ( |
| 138 | + pkgs.writeShellScriptBin "vegeta-bench" '' |
| 139 | + # rate=0 means maximum rate subject to max-workers |
| 140 | + echo "GET http://server/pathological?status=200" | vegeta attack -rate=0 -duration=1s -max-workers=1 | tee results.bin | vegeta report |
| 141 | + '' |
| 142 | + ) |
| 143 | + ( |
| 144 | + pkgs.writeShellScriptBin "vegeta-bench-max-requests" '' |
| 145 | + # rate=0 means maximum rate subject to max-workers |
| 146 | + echo "GET http://server/pathological?status=200" | vegeta attack -rate=0 -duration=10s -max-workers=50 | tee results.bin | vegeta report |
| 147 | + '' |
| 148 | + ) |
| 149 | + ( |
| 150 | + pkgs.writeShellScriptBin "net-bench" '' |
| 151 | + psql -U postgres -c "truncate net._http_response;" |
| 152 | + psql -U postgres -c "select net.http_get('http://server/pathological?status=200') from generate_series(1, 400);" > /dev/null |
| 153 | + sleep 2 |
| 154 | + psql -U postgres -c "select * from pg_net_stats;" |
| 155 | + '' |
| 156 | + ) |
| 157 | + ]; |
| 158 | + }; |
| 159 | + |
| 160 | +} |
0 commit comments