Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

running postgrest-loadtest with artificial latency #2682

Merged
merged 2 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ let
allOverlays.postgresql-legacy
allOverlays.postgresql-future
(allOverlays.haskell-packages { inherit compiler; })
allOverlays.slocat
];

# Evaluated expression of the Nixpkgs repository.
Expand Down Expand Up @@ -121,6 +122,9 @@ rec {
cabalTools =
pkgs.callPackage nix/tools/cabalTools.nix { inherit devCabalOptions postgrest; };

withTools =
pkgs.callPackage nix/tools/withTools.nix { inherit cabalTools devCabalOptions postgresqlVersions postgrest; };

# Development tools.
devTools =
pkgs.callPackage nix/tools/devTools.nix { inherit tests style devCabalOptions hsie withTools; };
Expand Down Expand Up @@ -153,9 +157,6 @@ rec {
inherit (pkgs.haskell.packages."${compiler}") hpc-codecov;
inherit (pkgs.haskell.packages."${compiler}") weeder;
};

withTools =
pkgs.callPackage nix/tools/withTools.nix { inherit devCabalOptions postgresqlVersions postgrest; };
} // pkgs.lib.optionalAttrs pkgs.stdenv.isLinux rec {
# Static executable.
inherit postgrestStatic;
Expand Down
6 changes: 6 additions & 0 deletions nix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,12 @@ postgrest-loadtest
# You can loadtest comparing to a different branch
postgrest-loadtest-against master

# You can simulate latency client/postgrest and postgrest/database
PGRST_DELAY=5ms PGDELAY=5ms postgrest-loadtest

# You can build postgrest directly with cabal for faster iteration
PGRST_BUILD_CABAL=1 postgrest-loadtest

# Produce a markdown report to be used on CI
postgrest-loadtest-report
```
Expand Down
1 change: 1 addition & 0 deletions nix/overlays/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
postgresql-default = import ./postgresql-default.nix;
postgresql-legacy = import ./postgresql-legacy.nix;
postgresql-future = import ./postgresql-future.nix;
slocat = import ./slocat.nix;
}
13 changes: 13 additions & 0 deletions nix/overlays/slocat.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
final: prev:
{
slocat = prev.buildGoModule {
name = "slocat";
src = prev.fetchFromGitHub {
owner = "robx";
repo = "slocat";
rev = "52e7512c6029fd00483e41ccce260a3b4b9b3b64";
sha256 = "sha256-qn6luuh5wqREu3s8RfuMCP5PKdS2WdwPrujRYTpfzQ8=";
};
vendorSha256 = "sha256-pQpattmS9VmO3ZIQUFn66az8GSmB4IvYhTTCFn6SUmo=";
};
}
2 changes: 1 addition & 1 deletion nix/tools/cabalTools.nix
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ let
checkedShellScript
{
name = "postgrest-run";
docs = "Run PostgREST after buidling it interactively with cabal-install";
docs = "Run PostgREST after building it interactively with cabal-install";
args = [ "ARG_LEFTOVERS([PostgREST arguments])" ];
inRootDir = true;
withEnv = postgrest.env;
Expand Down
2 changes: 2 additions & 0 deletions nix/tools/loadtest.nix
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ let

# shellcheck disable=SC2145
${withTools.withPg} --fixtures "$_arg_testdir"/fixtures.sql \
${withTools.withSlowPg} \
${withTools.withPgrst} \
${withTools.withSlowPgrst} \
sh -c "cd \"$_arg_testdir\" && ${runner} -targets targets.http -output \"$abs_output\" \"''${_arg_leftovers[@]}\""
${vegeta}/bin/vegeta report -type=text "$_arg_output"
'';
Expand Down
102 changes: 93 additions & 9 deletions nix/tools/withTools.nix
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
{ bash-completion
, buildToolbox
, cabal-install
, cabalTools
, checkedShellScript
, curl
, devCabalOptions
, git
, lib
, postgresqlVersions
, postgrest
, slocat
, writeText
}:
let
Expand Down Expand Up @@ -137,6 +139,81 @@ let

withPg = builtins.head withPgVersions;

withSlowPg =
checkedShellScript
{
name = "postgrest-with-slow-pg";
docs = "Run the given command with simulated high latency postgresql";
args =
[
"ARG_POSITIONAL_SINGLE([command], [Command to run])"
"ARG_LEFTOVERS([command arguments])"
"ARG_USE_ENV([PGHOST], [], [PG host (socket name)])"
"ARG_USE_ENV([PGDELAY], [0ms], [extra PG latency (duration)])"
];
positionalCompletion = "_command";
inRootDir = true;
redirectTixFiles = false;
withTmpDir = true;
}
''
delay="''${PGDELAY:-0ms}"
echo "delaying data to/from postgres by $delay"

REALPGHOST="$PGHOST"
export PGHOST="$tmpdir/socket"
mkdir -p "$PGHOST"

${slocat}/bin/slocat -delay "$delay" -src "$PGHOST/.s.PGSQL.5432" -dst "$REALPGHOST/.s.PGSQL.5432" &
SLOCAT_PID=$!
# shellcheck disable=SC2317
stop_slocat() {
kill "$SLOCAT_PID" || true
wait "$SLOCAT_PID" || true
}
trap stop_slocat EXIT
sleep 1 # should wait for socket file to appear instead

("$_arg_command" "''${_arg_leftovers[@]}")
'';

withSlowPgrst =
checkedShellScript
{
name = "postgrest-with-slow-postgrest";
docs = "Run the given command with simulated high latency postgrest";
args =
[
"ARG_POSITIONAL_SINGLE([command], [Command to run])"
"ARG_LEFTOVERS([command arguments])"
"ARG_USE_ENV([PGRST_SERVER_UNIX_SOCKET], [], [PostgREST host (socket name)])"
"ARG_USE_ENV([PGRST_DELAY], [0ms], [extra PostgREST latency (duration)])"
];
positionalCompletion = "_command";
inRootDir = true;
redirectTixFiles = false;
withTmpDir = true;
}
''
delay="''${PGRST_DELAY:-0ms}"
echo "delaying data to/from PostgREST by $delay"

REAL_PGRST_SERVER_UNIX_SOCKET="$PGRST_SERVER_UNIX_SOCKET"
export PGRST_SERVER_UNIX_SOCKET="$tmpdir/postgrest.socket"

${slocat}/bin/slocat -delay "$delay" -src "$PGRST_SERVER_UNIX_SOCKET" -dst "$REAL_PGRST_SERVER_UNIX_SOCKET" &
SLOCAT_PID=$!
# shellcheck disable=SC2317
stop_slocat() {
kill "$SLOCAT_PID" || true
wait "$SLOCAT_PID" || true
}
trap stop_slocat EXIT
sleep 1 # should wait for socket file to appear instead

("$_arg_command" "''${_arg_leftovers[@]}")
'';

withGit =
let
name = "postgrest-with-git";
Expand Down Expand Up @@ -257,16 +334,23 @@ let
export PGRST_SERVER_UNIX_SOCKET="$tmpdir"/postgrest.socket

rm -f result
echo -n "Building postgrest... "
nix-build -A postgrestPackage > "$tmpdir"/build.log 2>&1 || {
echo "failed, output:"
cat "$tmpdir"/build.log
exit 1
}
if [ -z "''${PGRST_BUILD_CABAL:-}" ]; then
echo -n "Building postgrest (nix)... "
nix-build -A postgrestPackage > "$tmpdir"/build.log 2>&1 || {
echo "failed, output:"
cat "$tmpdir"/build.log
exit 1
}
PGRST_CMD=./result/bin/postgrest
else
echo -n "Building postgrest (cabal)... "
postgrest-build
PGRST_CMD=postgrest-run
fi
Comment on lines +337 to +349
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is PGRST_BUILD_CABAL really the right term? nix-build does nothing different - it builds with cabal, too.

The difference seems to be in:

  • Which dependencies are used, so in which nix environment is the command run? This branch or main?
  • Is cabal's build cache re-used? The nix command probably does not, but postgrest-build does, right?

I think PGRST_BUILD_CABAL is misleading. It's actually going back to using the current nix environment, so the dependency problem would still be present with that setting, correct?

Overall, I think the fix in 0c5d2e5 was just not an improvement and we should revert it.

The suggestion I made in #2308 (comment) seems better. The loadtest-against / with-git infrastructure was designed to always use the current's branch nix environment on purpose. This does not cover some edge-cases, like the one you found - but it gives us some nice other properties, namely that we can update our tooling (nix commands for loadtest etc..) - and still run the new tools on older branches. This was necessary when I once ran loadtest through some months/years of commits to see patterns: #1812 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't particularly care what happens to this change as such -- I needed it to do my work here.

(It's unfortunate that our nix tooling is as rigid and obstructive as it is, it would be much preferable if changes such as this weren't needed. Ideally, it were possible to iterate quickly with local changes to the build scripts, but that's not where we're at.)

echo "done."

echo -n "Starting postgrest... "
./result/bin/postgrest ${legacyConfig} > "$tmpdir"/run.log 2>&1 &
$PGRST_CMD ${legacyConfig} > "$tmpdir"/run.log 2>&1 &
pid=$!
Comment on lines +353 to 354
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before the change to nix-build we had some more magic here to get the correct pid for cleanup, see your first commit around this area: 0c5d2e5

Aren't we back to getting the cabal pid, or even worse the bash pid from postgrest-run, which will prevent stopping postgrest properly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When PGRST_BUILD_CABAL isn't set, nothing changes. Otherwise, it's cabal's job to deal with its children, which it should do properly in recent releases (not entirely sure whether nixpkgs has caught up there).

# shellcheck disable=SC2317
cleanup() {
Expand All @@ -288,7 +372,7 @@ in
buildToolbox
{
name = "postgrest-with";
tools = [ withPgAll withGit withPgrst ] ++ withPgVersions;
tools = [ withPgAll withGit withPgrst withSlowPg withSlowPgrst ] ++ withPgVersions;
# make withTools available for other nix files
extra = { inherit withGit withPg withPgAll withPgrst; };
extra = { inherit withGit withPg withPgAll withPgrst withSlowPg withSlowPgrst; };
}