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

chore(electric): Upgrade to Erlang/OTP 27.0 and Elixir 1.17 #1224

Merged
merged 4 commits into from
Jun 13, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/components_electric_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ on:
- "!components/electric/**README.md"

env:
OTP_VERSION: "25.3.2.8"
ELIXIR_VERSION: "1.16.1-otp-25"
OTP_VERSION: "27.0"
ELIXIR_VERSION: "1.17.0-otp-27"

concurrency:
group: components-electric-${{ github.ref }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ on:
- "docs/**"

env:
OTP_VERSION: "25.3.2.8"
ELIXIR_VERSION: "1.16.1-otp-25"
OTP_VERSION: "27.0"
ELIXIR_VERSION: "1.17.0-otp-27"

concurrency:
group: e2e-${{ github.ref }}
Expand Down Expand Up @@ -199,4 +199,4 @@ jobs:
-F "run_env[branch]=$GITHUB_REF" \
-F "run_env[commit_sha]=$GITHUB_SHA" \
-F "run_env[url]=https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" \
https://analytics-api.buildkite.com/v1/uploads
https://analytics-api.buildkite.com/v1/uploads
8 changes: 4 additions & 4 deletions .github/workflows/satellite_proto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ on:
branches:
- main
paths:
- 'protocol/**'
- "protocol/**"
pull_request:
paths:
- 'protocol/**'
- "protocol/**"
workflow_dispatch:

env:
OTP_VERSION: "25.3.2.8"
ELIXIR_VERSION: "1.16.1-otp-25"
OTP_VERSION: "27.0"
ELIXIR_VERSION: "1.17.0-otp-27"

jobs:
verify_proto:
Expand Down
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
elixir 1.16.1-otp-25
erlang 25.3.2.8
elixir 1.17.0-otp-27
erlang 27.0
# keep synchronised with version pinned in .github/workflows/satellite_proto.yml
protoc 26.1
6 changes: 3 additions & 3 deletions components/electric/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ARG ELIXIR_VERSION=1.16.1
ARG OTP_VERSION=25.3.2.8
ARG DEBIAN_VERSION=bullseye-20231009-slim
ARG ELIXIR_VERSION=1.17.0
ARG OTP_VERSION=27.0
ARG DEBIAN_VERSION=bookworm-20240513-slim

ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}"
Expand Down
16 changes: 11 additions & 5 deletions components/electric/lib/electric/replication/eval/parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ defmodule Electric.Replication.Eval.Parser do
})

%{location: loc} = node ->
{:error, loc, "#{internal_node_to_error(node)} is not castable to bool"}
{:error, {loc, "#{internal_node_to_error(node)} is not castable to bool"}}
end
end
end
Expand Down Expand Up @@ -641,18 +641,19 @@ defmodule Electric.Replication.Eval.Parser do
{:error, {func.location, "Failed to apply function to constant arguments"}}
end

defp unwrap_node_string(%PgQuery.Node{node: {:string, %PgQuery.String{sval: val}}}), do: val

defp identifier(ref) do
case Enum.map(ref, &wrap_identifier/1) do
["pg_catalog", func] -> func
identifier -> Enum.join(identifier, ".")
end
end

defp wrap_identifier(ref) do
ref = if is_struct(ref, PgQuery.Node), do: unwrap_node_string(ref), else: ref
defp wrap_identifier(%PgQuery.Node{} = node),
do: node |> unwrap_node_string() |> wrap_identifier()

defp wrap_identifier(%PgQuery.String{sval: val}), do: wrap_identifier(val)

defp wrap_identifier(ref) when is_binary(ref) do
if String.match?(ref, ~r/^[[:lower:]_][[:lower:][:digit:]_]*$/u) do
ref
else
Expand All @@ -672,4 +673,9 @@ defmodule Electric.Replication.Eval.Parser do
defp find_refs(%Func{args: args}, acc), do: Enum.reduce(args, acc, &find_refs/2)

defp unsnake(string) when is_binary(string), do: :binary.replace(string, "_", " ", [:global])

def unwrap_node_string(%PgQuery.Node{node: {:string, %PgQuery.String{sval: sval}}}), do: sval

def unwrap_node_string(%PgQuery.Node{node: {:a_const, %PgQuery.A_Const{val: {:sval, sval}}}}),
do: unwrap_node_string(sval)
end
30 changes: 9 additions & 21 deletions components/electric/lib/electric/satellite/protocol.ex
Original file line number Diff line number Diff line change
Expand Up @@ -96,27 +96,24 @@ defmodule Electric.Satellite.Protocol do
def handle_rpc_request(%SatAuthReq{id: client_id, token: token}, state)
when auth_passed?(state) and client_id === state.client_id and token != "" do
# Request to renew auth token
with {:ok, auth} <- Electric.Satellite.Auth.validate_token(token, state.auth_provider) do
if auth.user_id != state.auth.user_id do
# cannot change user ID on renewal
Logger.warning("Client authentication failed: can't change user ID on renewal")
{:error, %SatErrorResp{error_type: :INVALID_REQUEST}}
else
case Electric.Satellite.Auth.validate_token(token, state.auth_provider) do
{:ok, auth} when auth.user_id == state.auth.user_id ->
Logger.info("Successfully renewed the token")

# cancel the old expiration timer and schedule a new one
state =
%State{state | auth: auth}
|> reschedule_auth_expiration(auth.expires_at)

{:reply, %SatAuthResp{id: Electric.instance_id()}, state}
end
else
{:error, %Electric.Satellite.Auth.TokenError{message: message}} ->
Logger.warning("Client authentication failed: #{message}")

{:ok, auth} when auth.user_id != state.auth.user_id ->
# cannot change user ID on renewal
Logger.warning("Client authentication failed: can't change user ID on renewal")
{:error, %SatErrorResp{error_type: :INVALID_REQUEST}}

{:error, reason} ->
Logger.error("Client authentication failed: #{inspect(reason)}")
{:error, %Electric.Satellite.Auth.TokenError{message: message}} ->
Logger.warning("Client authentication failed: #{message}")
{:error, %SatErrorResp{error_type: :INVALID_REQUEST}}
end
end
Expand Down Expand Up @@ -153,15 +150,6 @@ defmodule Electric.Satellite.Protocol do

{:error,
start_replication_error(:MALFORMED_LSN, "Could not validate start replication request")}

{:error, reason} ->
Logger.warning("Bad start replication request: #{inspect(reason)}")

{:error,
start_replication_error(
:CODE_UNSPECIFIED,
"Could not validate start replication request"
)}
end
end

Expand Down
6 changes: 3 additions & 3 deletions components/electric/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ defmodule Electric.MixProject do
{:jason, "~> 1.4"},
{:dialyxir, "~> 1.4", only: [:dev], runtime: false},
{:excoveralls, "~> 0.18", only: :test, runtime: false},
{:gproc, "~> 0.9.0"},
{:gproc, "~> 1.0"},
{:protox, "~> 1.7"},
{:gen_stage, "~> 1.2"},
{:telemetry, "~> 1.1", override: true},
{:telemetry_poller, "~> 1.0"},
{:telemetry_metrics, "~> 0.6"},
{:telemetry_metrics, "~> 1.0"},
{:joken, "~> 2.6"},
{:libgraph, "~> 0.16.0"},
{:pathex, "~> 2.5.2"},
{:stream_data, "~> 0.5", only: [:dev, :test]},
{:stream_data, "~> 1.0", only: [:dev, :test]},
{:exqlite, "~> 0.19", only: [:dev, :test]},
{:tzdata, "~> 1.1"},
{:pg_query_ex, github: "electric-sql/pg_query_ex"},
Expand Down