The bot's gateway connection: presence, requests sent over the gateway, and its shards.
Answers to gateway requests arrive later, as events for
Lingo.Bot.handle_event/2.
Large bots
- Resuming. A shard that crashes or restarts resumes its session
instead of identifying again, so no events are lost and no identify is
spent. To carry sessions over a full restart (a redeploy), give a
Lingo.Gateway.SessionStore. - Identify limits. Shards identify in their
max_concurrencybucket order, and never past the daily limit (going over it resets the token): once it's spent they wait for it to reset. - Resharding without downtime.
reshard/0, orauto_reshard: trueunder:sharding, brings up the new shards next to the running ones, and switches over once all are ready. - Several nodes. Run one bot on connected nodes by giving each the
same
:nameand:count, and its own:ids. The nodes share the identify limits, and gateway requests reach the node that runs the guild's shard;update_presence/2reaches every node. Shard statuses and latencies are this node's, and so are cache reads unless they ask forcluster: true(seeLingo.Cache). - Encoding and compression.
gateway: [encoding: :etf]receives Erlang terms instead of JSON.compression: :zstd(OTP 28 or later) uses less CPU than the default:zlib;:noneturns it off.
Lingo.Telemetry lists the events to watch all this with.
Summary
Functions
Waits until every shard on this node has connected once, for things to do once the bot is up
Every shard's last heartbeat round trip in ms.
A shard's last heartbeat round trip in ms, or nil.
Asks for extra channel info, like voice channel statuses. It arrives as :channel_info.
Asks for a guild's members. They arrive as :guild_members_chunk events
and fill the cache. Options: :query, :limit, :presences,
:user_ids and :nonce.
Asks for the soundboard sounds of some guilds. They arrive as :soundboard_sounds events.
Asks Discord for the recommended shard count and, when it differs, moves
to it without downtime: the new shards connect next to the running ones,
delivering nothing, and take over once all are ready (events at the very
moment of the switch may arrive twice or not at all). The old shards then
close. The new shards' :ready events aren't delivered either, and
await_ready/1 doesn't wait for them.
Reconnects a shard from scratch, identifying again.
The sessions of the shards on this node, as a Lingo.Gateway.SessionStore
saves them.
How many shards the bot runs in total.
The shard a guild's events arrive on.
The connection state of a shard, such as :connected, or :dead.
The connection state of every shard.
Sets the bot's status (:online, :idle, :dnd or :invisible) on every
shard, with an optional text: or activity:.
Functions
@spec await_ready(timeout()) :: :ok | {:error, :timeout}
Waits until every shard on this node has connected once, for things to do once the bot is up:
def handle_continue(:start, state) do
:ok = Lingo.Gateway.await_ready()
...
endReturns :ok right away when they already have, or when the bot runs
without a gateway, and {:error, :timeout} if timeout (ms) runs out.
It doesn't wait again for reconnects or a reshard. Each shard's own
sessions are :ready and :resumed events.
Call it from handle_continue, as above, not from init: a supervisor
starts its children one by one, so waiting in init holds up the rest of
your application until every shard connects, minutes for a large bot. It
covers this node's shards only, and exits if the bot's shard manager
restarts while it waits.
@spec latencies() :: %{required(non_neg_integer()) => non_neg_integer()}
Every shard's last heartbeat round trip in ms.
@spec latency(non_neg_integer()) :: non_neg_integer() | nil
A shard's last heartbeat round trip in ms, or nil.
Asks for extra channel info, like voice channel statuses. It arrives as :channel_info.
Asks for a guild's members. They arrive as :guild_members_chunk events
and fill the cache. Options: :query, :limit, :presences,
:user_ids and :nonce.
@spec request_soundboard_sounds([String.t()]) :: :ok
Asks for the soundboard sounds of some guilds. They arrive as :soundboard_sounds events.
@spec reshard() :: {:ok, %{from: pos_integer(), to: pos_integer()}} | :noop | {:error, :fixed_count | :fixed_ids | :in_progress | :not_started | :identify_limit | Lingo.Error.t()}
Asks Discord for the recommended shard count and, when it differs, moves
to it without downtime: the new shards connect next to the running ones,
delivering nothing, and take over once all are ready (events at the very
moment of the switch may arrive twice or not at all). The old shards then
close. The new shards' :ready events aren't delivered either, and
await_ready/1 doesn't wait for them.
Returns once the reshard has started, with {:ok, %{from: old, to: new}};
the [:lingo, :gateway, :reshard, :stop] telemetry event says when the
new shards took over. A reshard whose shards don't all get ready in time
is abandoned. Otherwise it returns:
:noop- Discord recommends the count already running{:error, :fixed_count}or{:error, :fixed_ids}- the:shardingoption fixes them; a bot split across nodes always does{:error, :in_progress}- a reshard is already under way{:error, :not_started}- the shards haven't started yet{:error, :identify_limit}- the day's identifies wouldn't cover the new shards{:error, %Lingo.Error{}}- asking Discord failed
@spec restart_shard(non_neg_integer()) :: :ok | {:error, term()}
Reconnects a shard from scratch, identifying again.
@spec sessions() :: [Lingo.Gateway.SessionStore.session()]
The sessions of the shards on this node, as a Lingo.Gateway.SessionStore
saves them.
@spec shard_count() :: non_neg_integer()
How many shards the bot runs in total.
@spec shard_for_guild(String.t()) :: non_neg_integer()
The shard a guild's events arrive on.
@spec shard_status(non_neg_integer()) :: atom()
The connection state of a shard, such as :connected, or :dead.
@spec shard_statuses() :: %{required(non_neg_integer()) => atom()}
The connection state of every shard.
Sets the bot's status (:online, :idle, :dnd or :invisible) on every
shard, with an optional text: or activity:.