From 8498e3c1e53044df00aeb47eceee3a918da3d989 Mon Sep 17 00:00:00 2001 From: tignear Date: Wed, 15 May 2024 21:46:00 +0900 Subject: [PATCH 01/12] feat(shard): manually shard connect and reconnect --- lib/nostrum/shard.ex | 14 +++++- lib/nostrum/shard/session.ex | 74 ++++++++++++++++++++++++++++++- lib/nostrum/shard/supervisor.ex | 77 +++++++++++++++++++++++++-------- 3 files changed, 146 insertions(+), 19 deletions(-) diff --git a/lib/nostrum/shard.ex b/lib/nostrum/shard.ex index 7f77ad2c7..74e2a15aa 100644 --- a/lib/nostrum/shard.ex +++ b/lib/nostrum/shard.ex @@ -5,10 +5,22 @@ defmodule Nostrum.Shard do alias Nostrum.Shard.Session - def start_link([_, shard_num, _total] = opts) do + def start_link({:connect, [_, shard_num, _total]} = opts) do Supervisor.start_link(__MODULE__, opts, name: :"Nostrum.Shard-#{shard_num}") end + def start_link( + {:reconnect, + %{shard: [_gateway, shard_num, _total], resume_gateway: _resume_gateway, seq: _seq}} = + opts + ) do + Supervisor.start_link(__MODULE__, opts, name: :"Nostrum.Shard-#{shard_num}") + end + + def start_link([_, _shard_num, _total] = opts) do + start_link({:connect, opts}) + end + def init(opts) do children = [ {Session, opts} diff --git a/lib/nostrum/shard/session.ex b/lib/nostrum/shard/session.ex index 3af892bde..f445d5653 100644 --- a/lib/nostrum/shard/session.ex +++ b/lib/nostrum/shard/session.ex @@ -86,17 +86,38 @@ defmodule Nostrum.Shard.Session do :gen_statem.cast(pid, {:request_guild_members, payload}) end + def disconnect(pid) do + :gen_statem.call(pid, {:disconnect, nil}) + end + + def disconnect(pid, timeout) do + :gen_statem.call(pid, {:disconnect, nil}, timeout) + end + def get_ws_state(pid) do :sys.get_state(pid) end # State machine API + def start_link({:connect, [_gateway, _shard_num, _total]} = opts, statem_opts) do + :gen_statem.start_link(__MODULE__, opts, statem_opts) + end + + def start_link( + {:reconnect, + %{shard: [_gateway, _shard_num, _total], resume_gateway: _resume_gateway, seq: _seq}} = + opts, + statem_opts + ) do + :gen_statem.start_link(__MODULE__, opts, statem_opts) + end + def start_link([_gateway, _shard_num, _total] = shard_opts, statem_opts) do :gen_statem.start_link(__MODULE__, shard_opts, statem_opts) end - def init([gateway, shard_num, total]) do + def init({:connect, [gateway, shard_num, total]}) do Logger.metadata(shard: shard_num) state = %WSState{ @@ -110,6 +131,35 @@ defmodule Nostrum.Shard.Session do {:ok, :disconnected, state, connect} end + def init( + {:reconnect, + %{ + shard: [gateway, shard_num, total], + resume_gateway: resume_gateway, + seq: seq, + session: session + }} + ) do + Logger.metadata(shard: shard_num) + + state = %WSState{ + conn_pid: self(), + shard_num: shard_num, + total_shards: total, + gateway: gateway, + resume_gateway: resume_gateway, + session: session, + seq: seq + } + + connect = {:next_event, :internal, :connect} + {:ok, :disconnected, state, connect} + end + + def init([gateway, shard_num, total]) do + init({:connect, [gateway, shard_num, total]}) + end + def callback_mode, do: [:state_functions, :state_enter] def child_spec(opts) do @@ -302,6 +352,28 @@ defmodule Nostrum.Shard.Session do :keep_state_and_data end + def connected({:call, from}, {:disconnect, nil}, %{ + conn: conn, + shard_num: shard_num, + total_shards: total, + gateway: gateway, + resume_gateway: resume_gateway, + seq: seq, + session: session + }) do + :ok = :gun.close(conn) + :ok = :gun.flush(conn) + + {:stop_and_reply, :disconnect, + {:reply, from, + %{ + shard: [gateway, shard_num, total], + resume_gateway: resume_gateway, + session: session, + seq: seq + }}} + end + def connected( :state_timeout, :send_heartbeat = request, diff --git a/lib/nostrum/shard/supervisor.ex b/lib/nostrum/shard/supervisor.ex index c3c9d7b7b..bed66f69d 100644 --- a/lib/nostrum/shard/supervisor.ex +++ b/lib/nostrum/shard/supervisor.ex @@ -34,7 +34,7 @@ defmodule Nostrum.Shard.Supervisor do handle yet, thus growing the message queue and the memory usage. """ - use Supervisor + use DynamicSupervisor alias Nostrum.Error.CacheError alias Nostrum.Shard @@ -66,19 +66,31 @@ defmodule Nostrum.Shard.Supervisor do def start_link(_args) do {url, gateway_shard_count} = Util.gateway() - value = Application.get_env(:nostrum, :num_shards, :auto) - shard_range = cast_shard_range(gateway_shard_count, value) + on_start = + DynamicSupervisor.start_link( + __MODULE__, + nil, + name: __MODULE__ + ) - Supervisor.start_link( - __MODULE__, - [url, shard_range], - name: __MODULE__ - ) + case Application.get_env(:nostrum, :num_shards, :auto) do + :unstable_manual -> + on_start + + value -> + {lowest, highest, total} = cast_shard_range(gateway_shard_count, value) + + shard_range = lowest..highest + + for num <- shard_range, do: connect(url, num - 1, total) + end + + on_start end def update_status(status, game, stream, type) do __MODULE__ - |> Supervisor.which_children() + |> DynamicSupervisor.which_children() |> Enum.filter(fn {_id, _pid, _type, [modules]} -> modules == Nostrum.Shard end) |> Enum.map(fn {_id, pid, _type, _modules} -> Supervisor.which_children(pid) end) |> List.flatten() @@ -102,18 +114,49 @@ defmodule Nostrum.Shard.Supervisor do end @doc false - def init([url, {lowest, highest, total}]) do - shard_range = lowest..highest - children = for num <- shard_range, do: create_worker(url, num - 1, total) - - Supervisor.init(children, strategy: :one_for_one, max_restarts: 3, max_seconds: 60) + def init(_) do + DynamicSupervisor.init(strategy: :one_for_one, max_restarts: 3, max_seconds: 60) end @doc false def create_worker(gateway, shard_num, total) do - Supervisor.child_spec( - {Shard, [gateway, shard_num, total]}, - id: shard_num + {Shard, [gateway, shard_num, total]} + end + + def disconnect(shard_num) do + name = :"Nostrum.Shard-#{shard_num}" + + children = + name + |> Supervisor.which_children() + + resume_info = + children + |> Enum.find(fn {id, _pid, _type, _modules} -> id == Nostrum.Shard.Session end) + |> elem(1) + |> Session.disconnect() + + shard = Process.whereis(name) + DynamicSupervisor.terminate_child(__MODULE__, shard) + + resume_info + end + + def connect(url, num, total) do + DynamicSupervisor.start_child(__MODULE__, create_worker(url, num, total)) + end + + def reconnect( + %{ + shard: [_gateway, _shard_num, _total], + resume_gateway: _resume_gateway, + seq: _seq, + session: _session + } = opts + ) do + DynamicSupervisor.start_child( + __MODULE__, + {Shard, {:reconnect, opts}} ) end end From cd60c218495f9601c4ecbbbf2c224cdb3c19da8a Mon Sep 17 00:00:00 2001 From: tignear Date: Wed, 15 May 2024 21:49:33 +0900 Subject: [PATCH 02/12] fix(shard): fix connect arguments --- lib/nostrum/shard/supervisor.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/nostrum/shard/supervisor.ex b/lib/nostrum/shard/supervisor.ex index bed66f69d..e7c8f6715 100644 --- a/lib/nostrum/shard/supervisor.ex +++ b/lib/nostrum/shard/supervisor.ex @@ -82,7 +82,7 @@ defmodule Nostrum.Shard.Supervisor do shard_range = lowest..highest - for num <- shard_range, do: connect(url, num - 1, total) + for num <- shard_range, do: connect([url, num - 1, total]) end on_start @@ -142,7 +142,7 @@ defmodule Nostrum.Shard.Supervisor do resume_info end - def connect(url, num, total) do + def connect([url, num, total]) do DynamicSupervisor.start_child(__MODULE__, create_worker(url, num, total)) end From 0665c3ae55e8728b2a82f6d3e6472d52a0eae7f0 Mon Sep 17 00:00:00 2001 From: tignear Date: Thu, 16 May 2024 00:03:32 +0900 Subject: [PATCH 03/12] fix(shard): prevent restart when the user executes the disconnect function --- lib/nostrum/shard/session.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/nostrum/shard/session.ex b/lib/nostrum/shard/session.ex index f445d5653..d98f40c0f 100644 --- a/lib/nostrum/shard/session.ex +++ b/lib/nostrum/shard/session.ex @@ -167,7 +167,7 @@ defmodule Nostrum.Shard.Session do id: __MODULE__, start: {__MODULE__, :start_link, [opts, []]}, type: :worker, - restart: :permanent, + restart: :transient, shutdown: 500 } end @@ -364,7 +364,7 @@ defmodule Nostrum.Shard.Session do :ok = :gun.close(conn) :ok = :gun.flush(conn) - {:stop_and_reply, :disconnect, + {:stop_and_reply, :normal, {:reply, from, %{ shard: [gateway, shard_num, total], From 0ed49565e858cfaeda0950fe612d5aad9eb0ea99 Mon Sep 17 00:00:00 2001 From: tignear Date: Thu, 16 May 2024 01:18:54 +0900 Subject: [PATCH 04/12] refactor(shard): Reworked supervisor configuration --- lib/nostrum/shard.ex | 9 +++++++-- lib/nostrum/shard/session.ex | 1 + lib/nostrum/shard/supervisor.ex | 21 +++++---------------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/lib/nostrum/shard.ex b/lib/nostrum/shard.ex index 74e2a15aa..bb5f4721b 100644 --- a/lib/nostrum/shard.ex +++ b/lib/nostrum/shard.ex @@ -1,7 +1,7 @@ defmodule Nostrum.Shard do @moduledoc false - use Supervisor + use Supervisor, restart: :transient alias Nostrum.Shard.Session @@ -28,6 +28,11 @@ defmodule Nostrum.Shard do # TODO: Add per shard cache ] - Supervisor.init(children, strategy: :one_for_all, max_restarts: 3, max_seconds: 60) + Supervisor.init(children, + strategy: :one_for_all, + max_restarts: 3, + max_seconds: 60, + auto_shutdown: :any_significant + ) end end diff --git a/lib/nostrum/shard/session.ex b/lib/nostrum/shard/session.ex index d98f40c0f..faee46201 100644 --- a/lib/nostrum/shard/session.ex +++ b/lib/nostrum/shard/session.ex @@ -168,6 +168,7 @@ defmodule Nostrum.Shard.Session do start: {__MODULE__, :start_link, [opts, []]}, type: :worker, restart: :transient, + significant: true, shutdown: 500 } end diff --git a/lib/nostrum/shard/supervisor.ex b/lib/nostrum/shard/supervisor.ex index e7c8f6715..97ced98e9 100644 --- a/lib/nostrum/shard/supervisor.ex +++ b/lib/nostrum/shard/supervisor.ex @@ -124,22 +124,11 @@ defmodule Nostrum.Shard.Supervisor do end def disconnect(shard_num) do - name = :"Nostrum.Shard-#{shard_num}" - - children = - name - |> Supervisor.which_children() - - resume_info = - children - |> Enum.find(fn {id, _pid, _type, _modules} -> id == Nostrum.Shard.Session end) - |> elem(1) - |> Session.disconnect() - - shard = Process.whereis(name) - DynamicSupervisor.terminate_child(__MODULE__, shard) - - resume_info + :"Nostrum.Shard-#{shard_num}" + |> Supervisor.which_children() + |> Enum.find(fn {id, _pid, _type, _modules} -> id == Nostrum.Shard.Session end) + |> elem(1) + |> Session.disconnect() end def connect([url, num, total]) do From e0d8fc5aeef937ae2f696a8f7b02681f983fd647 Mon Sep 17 00:00:00 2001 From: tignear Date: Sat, 18 May 2024 20:27:46 +0900 Subject: [PATCH 05/12] doc(shard): add document of shard supervisor and sharding options --- guides/intro/intro.md | 3 +++ lib/nostrum/shard/supervisor.ex | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/guides/intro/intro.md b/guides/intro/intro.md index e6d121b29..9901d512b 100644 --- a/guides/intro/intro.md +++ b/guides/intro/intro.md @@ -45,6 +45,9 @@ Apart from the `token` field mentioned above, the following fields are also supp should contain the total amount of shards that your bot is expected to have. Useful for splitting a single bot across multiple servers, but see also [the multi-node documentation](../advanced/multi_node.md). + - `:unstable_manual`: This is not a stable feature. nostrum does not + automatically spawn shards. You should use `Nostrum.Shard.Supervisor.connect/1` + to spawn shards instead. - `gateway_intents` - a list of atoms representing gateway intents for Nostrum to subscribe to from the Discord API. More information can be found in the [gateway intents](./gateway_intents.md) documentation page. diff --git a/lib/nostrum/shard/supervisor.ex b/lib/nostrum/shard/supervisor.ex index 97ced98e9..b3f4399b6 100644 --- a/lib/nostrum/shard/supervisor.ex +++ b/lib/nostrum/shard/supervisor.ex @@ -34,6 +34,25 @@ defmodule Nostrum.Shard.Supervisor do handle yet, thus growing the message queue and the memory usage. """ + @typedoc """ + Shard number. Range is `0..total_shard_count-1`. + """ + @type shard_num :: non_neg_integer() + @typedoc """ + Represents gateway connect information. + [gateway_url, shard_num, total_shard_count] + """ + @type shard_information :: list(any()) + + @typedoc """ + Represents gateway resume information. + """ + @type resume_information :: %{ + shard: shard_information(), + resume_gateway: String.t() | nil, + session: String.t(), + seq: pos_integer() + } use DynamicSupervisor alias Nostrum.Error.CacheError @@ -123,6 +142,11 @@ defmodule Nostrum.Shard.Supervisor do {Shard, [gateway, shard_num, total]} end + @doc """ + Disconnects the shard with the given shard number from the Gateway. + This function returns resume_information given to `Nostrum.Shard.Supervisor.reconnect/1`. + """ + @spec disconnect(shard_num()) :: resume_information() def disconnect(shard_num) do :"Nostrum.Shard-#{shard_num}" |> Supervisor.which_children() @@ -131,10 +155,20 @@ defmodule Nostrum.Shard.Supervisor do |> Session.disconnect() end + @doc """ + Spawns a shard with the specified number and connects it to the discord gateway. + """ + @spec connect(shard_information()) :: DynamicSupervisor.on_start_child() def connect([url, num, total]) do DynamicSupervisor.start_child(__MODULE__, create_worker(url, num, total)) end + @doc """ + Reconnect to the gateway using the given resume information. + In the unlikely event that a shard or session crashes, the connection will resume after a restart, potentially causing events to be delivered more than once. + For more information about resume, please visit [the Discord Developer Portal](https://discord.com/developers/docs/topics/gateway#resuming). + """ + @spec reconnect(resume_information()) :: DynamicSupervisor.on_start_child() def reconnect( %{ shard: [_gateway, _shard_num, _total], From 8c08aa22b30d99c9800b91651c3910fc74101f29 Mon Sep 17 00:00:00 2001 From: tignear Date: Sat, 18 May 2024 20:34:00 +0900 Subject: [PATCH 06/12] doc(shard): resume information -> `resume_information` --- lib/nostrum/shard/supervisor.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/nostrum/shard/supervisor.ex b/lib/nostrum/shard/supervisor.ex index b3f4399b6..83c0bff49 100644 --- a/lib/nostrum/shard/supervisor.ex +++ b/lib/nostrum/shard/supervisor.ex @@ -144,7 +144,7 @@ defmodule Nostrum.Shard.Supervisor do @doc """ Disconnects the shard with the given shard number from the Gateway. - This function returns resume_information given to `Nostrum.Shard.Supervisor.reconnect/1`. + This function returns `resume_information` given to `Nostrum.Shard.Supervisor.reconnect/1`. """ @spec disconnect(shard_num()) :: resume_information() def disconnect(shard_num) do @@ -164,7 +164,7 @@ defmodule Nostrum.Shard.Supervisor do end @doc """ - Reconnect to the gateway using the given resume information. + Reconnect to the gateway using the given `resume_information`. In the unlikely event that a shard or session crashes, the connection will resume after a restart, potentially causing events to be delivered more than once. For more information about resume, please visit [the Discord Developer Portal](https://discord.com/developers/docs/topics/gateway#resuming). """ From f0b2cde8872b04c0eb7734c5118f5b63ceb50e1f Mon Sep 17 00:00:00 2001 From: tignear Date: Wed, 22 May 2024 07:47:38 +0900 Subject: [PATCH 07/12] fix(shard): improving the API for stability --- lib/nostrum/shard.ex | 8 +++++++- lib/nostrum/shard/session.ex | 19 +++++++++++++++---- lib/nostrum/shard/supervisor.ex | 29 ++++++++++++++++------------- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/lib/nostrum/shard.ex b/lib/nostrum/shard.ex index bb5f4721b..ccf8c92e2 100644 --- a/lib/nostrum/shard.ex +++ b/lib/nostrum/shard.ex @@ -11,7 +11,13 @@ defmodule Nostrum.Shard do def start_link( {:reconnect, - %{shard: [_gateway, shard_num, _total], resume_gateway: _resume_gateway, seq: _seq}} = + %{ + shard_num: shard_num, + total_shards: _total_shards, + gateway: _gateway, + resume_gateway: _resume_gateway, + seq: _seq + }} = opts ) do Supervisor.start_link(__MODULE__, opts, name: :"Nostrum.Shard-#{shard_num}") diff --git a/lib/nostrum/shard/session.ex b/lib/nostrum/shard/session.ex index faee46201..4d3ab1829 100644 --- a/lib/nostrum/shard/session.ex +++ b/lib/nostrum/shard/session.ex @@ -106,7 +106,14 @@ defmodule Nostrum.Shard.Session do def start_link( {:reconnect, - %{shard: [_gateway, _shard_num, _total], resume_gateway: _resume_gateway, seq: _seq}} = + %{ + shard_num: _shard_num, + total_shards: _total_shards, + gateway: _gateway, + resume_gateway: _resume_gateway, + seq: _seq, + session: _session + }} = opts, statem_opts ) do @@ -134,7 +141,9 @@ defmodule Nostrum.Shard.Session do def init( {:reconnect, %{ - shard: [gateway, shard_num, total], + shard_num: shard_num, + total_shards: total_shards, + gateway: gateway, resume_gateway: resume_gateway, seq: seq, session: session @@ -145,7 +154,7 @@ defmodule Nostrum.Shard.Session do state = %WSState{ conn_pid: self(), shard_num: shard_num, - total_shards: total, + total_shards: total_shards, gateway: gateway, resume_gateway: resume_gateway, session: session, @@ -368,7 +377,9 @@ defmodule Nostrum.Shard.Session do {:stop_and_reply, :normal, {:reply, from, %{ - shard: [gateway, shard_num, total], + shard_num: shard_num, + total_shards: total, + gateway: gateway, resume_gateway: resume_gateway, session: session, seq: seq diff --git a/lib/nostrum/shard/supervisor.ex b/lib/nostrum/shard/supervisor.ex index 83c0bff49..791c10f33 100644 --- a/lib/nostrum/shard/supervisor.ex +++ b/lib/nostrum/shard/supervisor.ex @@ -35,20 +35,20 @@ defmodule Nostrum.Shard.Supervisor do """ @typedoc """ - Shard number. Range is `0..total_shard_count-1`. + Shard number(`shard_id`). Range is `0..total_shards-1`. """ @type shard_num :: non_neg_integer() @typedoc """ - Represents gateway connect information. - [gateway_url, shard_num, total_shard_count] + Total shard count(`num_shards`). """ - @type shard_information :: list(any()) - + @type total_shards :: pos_integer() @typedoc """ Represents gateway resume information. """ @type resume_information :: %{ - shard: shard_information(), + shard_num: shard_num(), + total_shards: total_shards(), + gateway: String.t(), resume_gateway: String.t() | nil, session: String.t(), seq: pos_integer() @@ -83,7 +83,7 @@ defmodule Nostrum.Shard.Supervisor do end def start_link(_args) do - {url, gateway_shard_count} = Util.gateway() + {_url, gateway_shard_count} = Util.gateway() on_start = DynamicSupervisor.start_link( @@ -101,7 +101,7 @@ defmodule Nostrum.Shard.Supervisor do shard_range = lowest..highest - for num <- shard_range, do: connect([url, num - 1, total]) + for num <- shard_range, do: connect(num - 1, total) end on_start @@ -138,7 +138,8 @@ defmodule Nostrum.Shard.Supervisor do end @doc false - def create_worker(gateway, shard_num, total) do + def create_worker(shard_num, total) do + {gateway, _gateway_shard_count} = Util.gateway() {Shard, [gateway, shard_num, total]} end @@ -158,9 +159,9 @@ defmodule Nostrum.Shard.Supervisor do @doc """ Spawns a shard with the specified number and connects it to the discord gateway. """ - @spec connect(shard_information()) :: DynamicSupervisor.on_start_child() - def connect([url, num, total]) do - DynamicSupervisor.start_child(__MODULE__, create_worker(url, num, total)) + @spec connect(shard_num(), total_shards()) :: DynamicSupervisor.on_start_child() + def connect(shard_num, total_shards) do + DynamicSupervisor.start_child(__MODULE__, create_worker(shard_num, total_shards)) end @doc """ @@ -171,7 +172,9 @@ defmodule Nostrum.Shard.Supervisor do @spec reconnect(resume_information()) :: DynamicSupervisor.on_start_child() def reconnect( %{ - shard: [_gateway, _shard_num, _total], + shard_num: _shard_num, + total_shards: _total_shards, + gateway: _gateway, resume_gateway: _resume_gateway, seq: _seq, session: _session From 3347ca12074c68d81349ddb86884388398c96fb1 Mon Sep 17 00:00:00 2001 From: tignear Date: Wed, 22 May 2024 07:52:45 +0900 Subject: [PATCH 08/12] fix(shard): fixed an issue where Util.num_shards would cause an error --- lib/nostrum/util.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/nostrum/util.ex b/lib/nostrum/util.ex index 92fd235cb..e3c3a5497 100644 --- a/lib/nostrum/util.ex +++ b/lib/nostrum/util.ex @@ -83,6 +83,7 @@ defmodule Nostrum.Util do case num do {_lowest, _highest, total} -> total + :unstable_manual -> 0 nil -> 1 end end From 1d2724208ac1bbfc08e2b62b56a3fca8ec8fee62 Mon Sep 17 00:00:00 2001 From: tignear Date: Wed, 22 May 2024 07:56:18 +0900 Subject: [PATCH 09/12] chore(shard): stabilize manual sharding --- guides/intro/intro.md | 5 ++--- lib/nostrum/shard/supervisor.ex | 2 +- lib/nostrum/util.ex | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/guides/intro/intro.md b/guides/intro/intro.md index 9901d512b..e6e49971a 100644 --- a/guides/intro/intro.md +++ b/guides/intro/intro.md @@ -45,9 +45,8 @@ Apart from the `token` field mentioned above, the following fields are also supp should contain the total amount of shards that your bot is expected to have. Useful for splitting a single bot across multiple servers, but see also [the multi-node documentation](../advanced/multi_node.md). - - `:unstable_manual`: This is not a stable feature. nostrum does not - automatically spawn shards. You should use `Nostrum.Shard.Supervisor.connect/1` - to spawn shards instead. + - `:manual`: nostrum does not automatically spawn shards. You should use + `Nostrum.Shard.Supervisor.connect/1` to spawn shards instead. - `gateway_intents` - a list of atoms representing gateway intents for Nostrum to subscribe to from the Discord API. More information can be found in the [gateway intents](./gateway_intents.md) documentation page. diff --git a/lib/nostrum/shard/supervisor.ex b/lib/nostrum/shard/supervisor.ex index 791c10f33..33d8b24c6 100644 --- a/lib/nostrum/shard/supervisor.ex +++ b/lib/nostrum/shard/supervisor.ex @@ -93,7 +93,7 @@ defmodule Nostrum.Shard.Supervisor do ) case Application.get_env(:nostrum, :num_shards, :auto) do - :unstable_manual -> + :manual -> on_start value -> diff --git a/lib/nostrum/util.ex b/lib/nostrum/util.ex index e3c3a5497..435c27494 100644 --- a/lib/nostrum/util.ex +++ b/lib/nostrum/util.ex @@ -83,7 +83,7 @@ defmodule Nostrum.Util do case num do {_lowest, _highest, total} -> total - :unstable_manual -> 0 + :manual -> 0 nil -> 1 end end From 358e61a456ea8eefe46866ea565470a511f1031c Mon Sep 17 00:00:00 2001 From: tignear Date: Wed, 22 May 2024 08:01:15 +0900 Subject: [PATCH 10/12] fix(shard): fixed lack of argument validation --- lib/nostrum/shard.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/nostrum/shard.ex b/lib/nostrum/shard.ex index ccf8c92e2..fca655188 100644 --- a/lib/nostrum/shard.ex +++ b/lib/nostrum/shard.ex @@ -16,7 +16,8 @@ defmodule Nostrum.Shard do total_shards: _total_shards, gateway: _gateway, resume_gateway: _resume_gateway, - seq: _seq + seq: _seq, + session: _session }} = opts ) do From 31b22507cefe178ea4cff21ad7d5a6bb1668556e Mon Sep 17 00:00:00 2001 From: tignear Date: Wed, 22 May 2024 08:17:17 +0900 Subject: [PATCH 11/12] doc(shard): double delivery of events does not occur --- lib/nostrum/shard/supervisor.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/nostrum/shard/supervisor.ex b/lib/nostrum/shard/supervisor.ex index 33d8b24c6..1a2afc70e 100644 --- a/lib/nostrum/shard/supervisor.ex +++ b/lib/nostrum/shard/supervisor.ex @@ -166,7 +166,6 @@ defmodule Nostrum.Shard.Supervisor do @doc """ Reconnect to the gateway using the given `resume_information`. - In the unlikely event that a shard or session crashes, the connection will resume after a restart, potentially causing events to be delivered more than once. For more information about resume, please visit [the Discord Developer Portal](https://discord.com/developers/docs/topics/gateway#resuming). """ @spec reconnect(resume_information()) :: DynamicSupervisor.on_start_child() From af5103e341f0aa1aab08928f12128110359f7ba5 Mon Sep 17 00:00:00 2001 From: tignear Date: Wed, 22 May 2024 08:20:50 +0900 Subject: [PATCH 12/12] doc(shard): `connect/1` -> `connect/2` --- guides/intro/intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/intro/intro.md b/guides/intro/intro.md index e6e49971a..e3010ab26 100644 --- a/guides/intro/intro.md +++ b/guides/intro/intro.md @@ -46,7 +46,7 @@ Apart from the `token` field mentioned above, the following fields are also supp Useful for splitting a single bot across multiple servers, but see also [the multi-node documentation](../advanced/multi_node.md). - `:manual`: nostrum does not automatically spawn shards. You should use - `Nostrum.Shard.Supervisor.connect/1` to spawn shards instead. + `Nostrum.Shard.Supervisor.connect/2` to spawn shards instead. - `gateway_intents` - a list of atoms representing gateway intents for Nostrum to subscribe to from the Discord API. More information can be found in the [gateway intents](./gateway_intents.md) documentation page.