diff --git a/guides/advanced/manual_sharding.md b/guides/advanced/manual_sharding.md new file mode 100644 index 000000000..4c1d90b56 --- /dev/null +++ b/guides/advanced/manual_sharding.md @@ -0,0 +1,27 @@ +# Manual Sharding + +Advanced users can use methods located in the `Nostrum.Shard.Supervisor` module +to manually connect shards to the gateway as well as initiate manual disconnect +and reconnects (attempting to `RESUME` sessions where possible). + +You can set the `num_shards` option in your `nostrum` application config to +`:manual` to prevent Nostrum from automatically starting shards. You should use +the methods in the shard supervisor such as `Nostrum.Shard.Supervisor.connect/2` +to manually start shards if using this configuration option. + +## Reconnection example + +```elixir +# On Node A +iex> Nostrum.Shard.Supervisor.connect(0, 1) +iex> resume_info = Nostrum.Shard.Supervisor.disconnect(0) +%{shard_num: 0, ...} + +# On another node +iex> Nostrum.Shard.Supervisor.reconnect(resume_info) +``` + +Discord will perform a best effort attempt to resume the gateway from the time +of disconnection, relaying any missed events. Resumption is not guaranteed to +work, in the event it fails Nostrum will reconnect the shard from scratch, +though this may mean some events are missed. diff --git a/guides/intro/intro.md b/guides/intro/intro.md index 5b25b3a26..6c53e8b01 100644 --- a/guides/intro/intro.md +++ b/guides/intro/intro.md @@ -45,8 +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). - - `:manual`: nostrum does not automatically spawn shards. You should use - `Nostrum.Shard.Supervisor.connect/2` to spawn shards instead. + - `:manual`: nostrum does not automatically spawn shards. See the [Manual + Sharding](../advanced/manual_sharding.md) guide for more information. - `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 1a2afc70e..3b610ae67 100644 --- a/lib/nostrum/shard/supervisor.ex +++ b/lib/nostrum/shard/supervisor.ex @@ -145,7 +145,17 @@ 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 `t:resume_information/0` which can be provided + to `reconnect/1` to reconnect a shard to the gateway and (attempt) to + catch up on any missed events. + + ### Examples + + ```elixir + iex> Nostrum.Shard.Supervisor.disconnect(4) + %{shard_num: 4, ...} + ``` """ @spec disconnect(shard_num()) :: resume_information() def disconnect(shard_num) do @@ -165,8 +175,24 @@ defmodule Nostrum.Shard.Supervisor do end @doc """ - Reconnect to the gateway using the given `resume_information`. - For more information about resume, please visit [the Discord Developer Portal](https://discord.com/developers/docs/topics/gateway#resuming). + Reconnect to the gateway using the provided `t:resume_information/0`. + + Resuming is performed by the gateway on a best effort basis, it is not + guaranteed that a resume will work (though Nostrum will handle failed attempts + at a resumption). If a reconnect is successful, any events received during the + reconnection period should be received. If the reconnect fails, events + received between the disconnect and re-authentication may be lost. + + For more information about resuming sessions, visit + [the Discord Developer Portal](https://discord.com/developers/docs/topics/gateway#resuming). + + ### Examples + + ```elixir + iex> resume = Nostrum.Shard.Supervisor.disconnect(4) + %{shard_num: 4, ...} + iex> Nostrum.Shard.Supervisor.reconnect(resume) + ``` """ @spec reconnect(resume_information()) :: DynamicSupervisor.on_start_child() def reconnect( diff --git a/mix.exs b/mix.exs index 12c4b0fac..a178ad24a 100644 --- a/mix.exs +++ b/mix.exs @@ -70,22 +70,10 @@ defmodule Nostrum.Mixfile do end def extras do - [ - "guides/intro/intro.md", - "guides/intro/api.md", - "guides/intro/application_commands.md", - "guides/intro/gateway_intents.md", - "guides/functionality/state.md", - "guides/functionality/event_handling.md", - "guides/functionality/voice.md", - "guides/advanced/pluggable_caching.md", - "guides/advanced/multi_node.md", - "guides/advanced/hot_code_upgrade.md", - "guides/advanced/gateway_compression.md", - "guides/cheat-sheets/api.cheatmd", - "guides/cheat-sheets/qlc.cheatmd", - "guides/cheat-sheets/voice.cheatmd" - ] + # We manually move the `intro.md` document to the top of the list so it + # remains first on the navigation sidebar + ["guides/intro/intro.md"] ++ + (Path.wildcard("guides/**/*.{md,cheatmd}") -- ["guides/intro/intro.md"]) end def groups_for_modules do