WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 3 additions & 1 deletion CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
0.2.1 (February 24, 2025):
1.0.0 (February 25, 2025):
- Fixed the SDK language version to correctly reflect the package version when it's installed from hex.pm.
- BREAKING CHANGES:
- Renamed the `:socket_path` option to `:address` in `Split.Supervisor.start_link/1`.

0.2.0 (February 14, 2025):
- Added new variations of the get treatment functions to support evaluating flags in given flag set/s: `Split.get_treatments_by_flag_set/3`, `Split.get_treatments_by_flag_sets/3`, `Split.get_treatments_with_config_by_flag_set/3`, and `Split.get_treatments_with_config_by_flag_sets/3`.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Below is a simple example that describes the instantiation and most basic usage

```elixir
# Start the SDK supervisor
Split.Supervisor.start_link(socket_path: "/var/run/splitd.sock")
Split.Supervisor.start_link(address: "/var/run/splitd.sock")

# Get treatment for a user
case Split.get_treatment(user_id, feature_flag_name) do
Expand Down
6 changes: 3 additions & 3 deletions lib/split.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ defmodule Split do
def start(_type, _args) do
children = [
# ... other children ...
{Split, [socket_path: "/var/run/split.sock"]}
{Split, [address: "/var/run/split.sock"]}
]

opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Expand All @@ -32,7 +32,7 @@ defmodule Split do

`Split` takes a number of keyword arguments as options when starting. The following options are available:

- `:socket_path`: **OPTIONAL** The path to the splitd socket file. Default is `"/var/run/splitd.sock"`.
- `:address`: **OPTIONAL** The path to the splitd socket file. Default is `"/var/run/splitd.sock"`.
- `:pool_size`: **OPTIONAL** The size of the pool of connections to the splitd daemon. Default is the number of online schedulers in the Erlang VM (See: https://www.erlang.org/doc/apps/erts/erl_cmd.html).
- `:connect_timeout`: **OPTIONAL** The timeout in milliseconds to connect to the splitd daemon. Default is `1000`.

Expand All @@ -52,7 +52,7 @@ defmodule Split do

@typedoc "An option that can be provided when starting `Split`. See [options](#module-options) for more information."
@type option ::
{:socket_path, String.t()}
{:address, String.t()}
| {:pool_size, non_neg_integer()}
| {:connect_timeout, non_neg_integer()}

Expand Down
4 changes: 2 additions & 2 deletions lib/split/rpc/message.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Split.RPC.Message do
use Split.RPC.Opcodes

@protocol_version 0x01
@client_id "Splitd_Elixir-0.2.1-rc.0"
@client_id "Splitd_Elixir-1.0.0"

@type opcode :: unquote(Enum.reduce(@opcodes, &{:|, [], [&1, &2]}))
@type protocol_version :: unquote(@protocol_version)
Expand Down Expand Up @@ -37,7 +37,7 @@ defmodule Split.RPC.Message do
## Examples

iex> Message.register()
%Message{v: 1, o: 0, a: ["123", "Splitd_Elixir-0.2.1-rc.0", 1]}
%Message{v: 1, o: 0, a: ["123", "Splitd_Elixir-1.0.0", 1]}
"""
@spec register() :: t()
def register, do: %__MODULE__{o: @register_opcode, a: ["123", @client_id, 1]}
Expand Down
14 changes: 7 additions & 7 deletions lib/split/sockets/conn.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ defmodule Split.Sockets.Conn do

@type t :: %__MODULE__{
socket: port() | nil,
socket_path: String.t(),
address: String.t(),
opts: keyword()
}

defstruct [
:socket,
:socket_path,
:address,
:opts
]

Expand All @@ -31,20 +31,20 @@ defmodule Split.Sockets.Conn do
@default_rcv_timeout 1000

@spec new(String.t(), keyword()) :: t
def new(socket_path, opts \\ []) do
def new(address, opts \\ []) do
%__MODULE__{
socket: nil,
socket_path: socket_path,
address: address,
opts: opts
}
end

@spec connect(t) :: {:ok, t()} | {:error, t(), term()}
def connect(%__MODULE__{socket: nil, socket_path: socket_path, opts: opts} = conn) do
def connect(%__MODULE__{socket: nil, address: address, opts: opts} = conn) do
connect_timeout = Keyword.get(opts, :connect_timeout, @default_connect_timeout)

Telemetry.span(:connect, %{socket_path: socket_path, pool_name: opts[:pool_name]}, fn ->
case :gen_tcp.connect({:local, socket_path}, 0, @connect_opts, connect_timeout) do
Telemetry.span(:connect, %{address: address, pool_name: opts[:pool_name]}, fn ->
case :gen_tcp.connect({:local, address}, 0, @connect_opts, connect_timeout) do
{:ok, socket} ->
conn = %{conn | socket: socket}

Expand Down
12 changes: 6 additions & 6 deletions lib/split/sockets/pool.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ defmodule Split.Sockets.Pool do
end

def start_link(opts) do
socket_path = Keyword.get(opts, :socket_path, "/var/run/splitd.sock")
address = Keyword.get(opts, :address, "/var/run/splitd.sock")
pool_name = Keyword.get(opts, :pool_name, __MODULE__)
pool_size = Keyword.get(opts, :pool_size, System.schedulers_online())

opts =
opts
|> Keyword.put_new(:socket_path, socket_path)
|> Keyword.put_new(:address, address)
|> Keyword.put_new(:pool_size, pool_size)
|> Keyword.put_new(:pool_name, pool_name)

Expand Down Expand Up @@ -100,11 +100,11 @@ defmodule Split.Sockets.Pool do

@impl NimblePool
def init_pool(opts) do
socket_path = Keyword.get(opts, :socket_path)
address = Keyword.get(opts, :address)

unless File.exists?(socket_path) do
unless File.exists?(address) do
Logger.error("""
The Split Daemon (splitd) socket was not found at #{socket_path}.
The Split Daemon (splitd) socket was not found at address #{address}.

This is likely because the Splitd daemon is not running.
""")
Expand All @@ -117,7 +117,7 @@ defmodule Split.Sockets.Pool do

@impl NimblePool
def init_worker({opts, _metrics_ref} = pool_state) do
{:ok, Conn.new(Keyword.get(opts, :socket_path), opts), pool_state}
{:ok, Conn.new(Keyword.get(opts, :address), opts), pool_state}
end

@impl NimblePool
Expand Down
4 changes: 2 additions & 2 deletions lib/split/telemetry.ex
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ defmodule Split.Telemetry do

#### Metadata

* `socket_path` - The path to the socket file.
* `address` - The path to the socket file.
* `pool_name` - The name of the pool being used.

### Connect Stop
Expand All @@ -114,7 +114,7 @@ defmodule Split.Telemetry do

#### Metadata

* `socket_path` - The path to the socket file.
* `address` - The path to the socket file.
* `pool_name` - The name of the pool being used.
* `error` - The error message if the connection fails.

Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule SplitThinElixir.MixProject do
def project do
[
app: :split,
version: "0.2.1-rc.0",
version: "1.0.0",
elixir: "~> 1.14",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
Expand Down
40 changes: 20 additions & 20 deletions test/sockets/conn_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,34 @@ defmodule Split.Sockets.ConnTest do
describe "telemetry events" do
setup context do
test_id = :erlang.phash2(context.test)
socket_path = "/tmp/test-splitd-#{test_id}.sock"
address = "/tmp/test-splitd-#{test_id}.sock"
process_name = :"test-#{test_id}"

start_supervised!(
{Split.Test.MockSplitdServer, socket_path: socket_path, name: process_name},
{Split.Test.MockSplitdServer, address: address, name: process_name},
id: process_name,
restart: :transient
)

Split.Test.MockSplitdServer.wait_until_listening(socket_path)
Split.Test.MockSplitdServer.wait_until_listening(address)

{:ok, socket_path: socket_path, splitd_name: process_name}
{:ok, address: address, splitd_name: process_name}
end

test "emits telemetry events for successful connection", %{socket_path: socket_path} do
test "emits telemetry events for successful connection", %{address: address} do
ref =
:telemetry_test.attach_event_handlers(self(), [
[:split, :connect, :start],
[:split, :connect, :stop]
])

Conn.new(socket_path) |> Conn.connect()
Conn.new(address) |> Conn.connect()

assert_received {[:split, :connect, :start], ^ref, _, %{socket_path: ^socket_path}}
assert_received {[:split, :connect, :start], ^ref, _, %{address: ^address}}
assert_received {[:split, :connect, :stop], ^ref, _, %{}}
end

test "emits telemetry events for registration message on connect", %{socket_path: socket_path} do
test "emits telemetry events for registration message on connect", %{address: address} do
ref =
:telemetry_test.attach_event_handlers(self(), [
[:split, :send, :start],
Expand All @@ -45,7 +45,7 @@ defmodule Split.Sockets.ConnTest do
[:split, :receive, :stop]
])

Conn.new(socket_path) |> Conn.connect()
Conn.new(address) |> Conn.connect()

assert_received {[:split, :send, :start], ^ref, _,
%{request: %Message{v: 1, o: @register_opcode}}}
Expand All @@ -59,7 +59,7 @@ defmodule Split.Sockets.ConnTest do
end

test "emits telemetry events for failed connection", %{
socket_path: socket_path,
address: address,
splitd_name: splitd_name
} do
ref =
Expand All @@ -71,21 +71,21 @@ defmodule Split.Sockets.ConnTest do
# Stop the mocked splitd socket to receive connection errors
:ok = stop_supervised(splitd_name)

assert {:error, _conn, reason} = Conn.new(socket_path) |> Conn.connect()
assert {:error, _conn, reason} = Conn.new(address) |> Conn.connect()

assert_received {[:split, :connect, :start], ^ref, _, %{socket_path: ^socket_path}}
assert_received {[:split, :connect, :start], ^ref, _, %{address: ^address}}

assert_received {[:split, :connect, :stop], ^ref, _, %{error: ^reason}}
end

test "emits telemetry events for successful message sending", %{socket_path: socket_path} do
test "emits telemetry events for successful message sending", %{address: address} do
ref =
:telemetry_test.attach_event_handlers(self(), [
[:split, :send, :start],
[:split, :send, :stop]
])

{:ok, conn} = Conn.new(socket_path) |> Conn.connect()
{:ok, conn} = Conn.new(address) |> Conn.connect()

message = Message.get_treatment(key: "user-id", feature_name: "feature")

Expand All @@ -97,7 +97,7 @@ defmodule Split.Sockets.ConnTest do
end

test "emits telemetry events for failed message sending", %{
socket_path: socket_path,
address: address,
splitd_name: splitd_name
} do
ref =
Expand All @@ -106,7 +106,7 @@ defmodule Split.Sockets.ConnTest do
[:split, :send, :stop]
])

{:ok, conn} = Conn.new(socket_path) |> Conn.connect()
{:ok, conn} = Conn.new(address) |> Conn.connect()

message = Message.get_treatment(key: "user-id", feature_name: "feature")

Expand All @@ -120,14 +120,14 @@ defmodule Split.Sockets.ConnTest do
assert_received {[:split, :send, :stop], ^ref, _, %{error: ^reason}}
end

test "emits telemetry events for successful message receiving", %{socket_path: socket_path} do
test "emits telemetry events for successful message receiving", %{address: address} do
ref =
:telemetry_test.attach_event_handlers(self(), [
[:split, :receive, :start],
[:split, :receive, :stop]
])

{:ok, conn} = Conn.new(socket_path) |> Conn.connect()
{:ok, conn} = Conn.new(address) |> Conn.connect()

message = Message.get_treatment(key: "user-id", feature_name: "feature")

Expand All @@ -138,14 +138,14 @@ defmodule Split.Sockets.ConnTest do
assert_received {[:split, :receive, :stop], ^ref, _, %{response: ^response}}
end

test "emits telemetry events for failed message receiving", %{socket_path: socket_path} do
test "emits telemetry events for failed message receiving", %{address: address} do
ref =
:telemetry_test.attach_event_handlers(self(), [
[:split, :receive, :start],
[:split, :receive, :stop]
])

{:ok, conn} = Conn.new(socket_path) |> Conn.connect()
{:ok, conn} = Conn.new(address) |> Conn.connect()

# receive the registration messages
assert_received {[:split, :receive, :start], ^ref, _, %{}}
Expand Down
10 changes: 4 additions & 6 deletions test/sockets/pool_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ defmodule Split.Sockets.PoolTest do

setup_all context do
test_id = :erlang.phash2(context.module)
socket_path = "/tmp/test-splitd-#{test_id}.sock"
address = "/tmp/test-splitd-#{test_id}.sock"

start_supervised!(
{Split.Test.MockSplitdServer, socket_path: socket_path, name: :"test-#{test_id}"}
)
start_supervised!({Split.Test.MockSplitdServer, address: address, name: :"test-#{test_id}"})

Split.Test.MockSplitdServer.wait_until_listening(socket_path)
Split.Test.MockSplitdServer.wait_until_listening(address)

start_supervised!({Split, socket_path: socket_path, pool_name: __MODULE__, pool_size: 10})
start_supervised!({Split, address: address, pool_name: __MODULE__, pool_size: 10})

:ok
end
Expand Down
10 changes: 4 additions & 6 deletions test/split_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ defmodule SplitThinElixirTest do

setup_all context do
test_id = :erlang.phash2(context.module)
socket_path = "/tmp/test-splitd-#{test_id}.sock"
address = "/tmp/test-splitd-#{test_id}.sock"

start_supervised!(
{Split.Test.MockSplitdServer, socket_path: socket_path, name: :"test-#{test_id}"}
)
start_supervised!({Split.Test.MockSplitdServer, address: address, name: :"test-#{test_id}"})

Split.Test.MockSplitdServer.wait_until_listening(socket_path)
Split.Test.MockSplitdServer.wait_until_listening(address)

start_supervised!({Split, socket_path: socket_path})
start_supervised!({Split, address: address})

:ok
end
Expand Down
14 changes: 7 additions & 7 deletions test/support/mock_splitd_server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ defmodule Split.Test.MockSplitdServer do

@impl Supervisor
def init(opts \\ []) do
socket_path = Keyword.get(opts, :socket_path)
address = Keyword.get(opts, :address)
name = Keyword.get(opts, :name, __MODULE__)
opts = Keyword.put_new(opts, :name, name)

File.rm(socket_path)
File.rm(address)

children = [
{Task.Supervisor, strategy: :one_for_one, name: :"#{name}-task-supervisor"},
Expand All @@ -26,25 +26,25 @@ defmodule Split.Test.MockSplitdServer do
end

def accept(opts) do
socket_path = Keyword.get(opts, :socket_path)
address = Keyword.get(opts, :address)

{:ok, socket} =
:gen_tcp.listen(0,
active: false,
packet: :raw,
reuseaddr: true,
ifaddr: {:local, socket_path}
ifaddr: {:local, address}
)

loop_acceptor(socket, opts)
end

def wait_until_listening(socket_path) do
if File.exists?(socket_path) do
def wait_until_listening(address) do
if File.exists?(address) do
:ok
else
Process.sleep(1)
wait_until_listening(socket_path)
wait_until_listening(address)
end
end

Expand Down
Loading