Skip to content

Releases: Kraigie/nostrum

0.10.1 - Explosive Mania

05 Feb 19:39
v0.10.1
e197d9f
Compare
Choose a tag to compare

nostrum 0.10.1 fixes a number of bugs and contains some improvements
that once again fortifies its stand as the best Discord library on the
globe.

I would like to thank MiniAppleTheApple for the improvements to
nostrum's components, Kyle Boe for the massive API module decomposition,
the channel field updates for forum channels and further bugfixes in our
components, The Major for the optimizations on nostrum's UserCache and
work on benchmarking and fixing bugs around nostrum's caches, including
helping the QLC removal process, a process solely needed because Craig
Dazey decided a few years ago to give me contributor rights, a change he
still regrets occasionally. Thank you also to Brandt Hill who never
ceases to submit fixes for nostrum's voice functionality, ensuring that
our transmissions are top of the shelf.

Furthermore, nostrum's QLC functionality was removed again. While it is
a cool idea in theory, unfortunately the issue is that QLC is not able
to properly optimize queries we run in some usecases, and runs queries
very inefficiently in other cases. Instead, we reverted back to the
previous caching behavior logic, which needs more work to implement but
results in better performance as each function can be written
independently. Potentially, Ecto might be interesting for the cache as
also used in coxir, which is part of the "nostrum 2025" plan under the
section "Incorporating Adam, Merging Coxir And Adopting His Lovely Dog".

Deprecations

  • The Nostrum.Api module was split up into multiple smaller modules.
    You can still use Nostrum.Api, but you are encouraged to slowly move
    to more specific modules. See the Nostrum.Api module, PR #641 and
    commit 503c87f22bdb671b90880133d1fd6c78a874b097 for more
    information.
    • You might receive a lot of deprecation warnings about this. Sorry,
      but the Nostrum.Api module has become a decent mess.
    • Bang functions in the module were also deprecated.
    • Thanks to Kyle Boe for the herculean effort.

Enhancements

  • nostrum now supports the following new components:
    • Nostrum.Struct.Component.ChannelSelect
    • Nostrum.Struct.Component.MentionableSelect
    • Nostrum.Struct.Component.RoleSelect
    • Nostrum.Struct.Component.UserSelect
  • Nostrum.Struct.Component gained the following fields:
    • channel_types
    • default_values, together with the
      Nostrum.Struct.Component.DefaultValue module.
  • Action rows now accept the new component types.
  • Nostrum.Struct.Channel gained the following fields:
    • default_sort_order (for GUILD_FORUM channels)
    • default_forum_layout (also for GUILD_FORUM channels)
  • nostrum now uses the voice gateway version 8 instead of 4. In a series
    of pull requests that still baffle me to this day, Brandt Hill also
    updated our crypto code to make sure that your bot's voice
    transmissions are rock solid secure.
  • nostrum now fans out ratelimiter requests across all running
    ratelimiters, which are registered under a process group. See
    Nostrum.Api.RatelimiterGroup for details. The Multi-Node section of
    Nostrum.Api.Ratelimiter has also been updated accordingly.
  • UserCache.get was optimized to not run through QLC, which results in
    better performance.
  • Nostrum.Cache.MemberCache now documents the required config for the
    cache to work. Thanks to Joe Sweeney.
  • Tasks started from consumers that crash will now have their errors
    logged as opposed to crashing the consumer. Thanks to The Major for
    the implementation, and Leastrio for a small bugfix related to the
    logging call.

Bugfixes

  • The endpoint for webhook_message_edit was wrong. Thanks to foldcat
    for the fix.
  • Abnormally closed requests will now properly display the sender of the
    requests in the ratelimiter.
  • Nostrum.Cache.GuildCache.ETS will no longer crash when updating a
    missing guild.
  • The ffmpeg output format has been fixed.
  • Some requests were missing Content-Type headers, these will be sent
    now.
  • Mysterious voice packet emissions will be logged together with the
    closest NATO base that might have emitted them for further
    introspection and analysis by the upcoming Nostrum.SIGINT package
    instead of crashing the voice session. Thanks to Brandt Hill for the
    fix.
  • A typo in Nostrum.Consumer.message_poll_vote_remove has been fixed.
    Thanks to Carlos Souza.
  • The standard error of ports started by Nostrum.Voice.Ports is no
    longer sent to standard out.

Internal changes

  • Benchmarks for the GuildCache.{get,update,delete} functions were
    added. Thanks to The Major.
  • Run CI against Elixir 1.18 and build docs on 1.18.

0.10.0 - Orbital Insertion

18 Jul 17:26
@jb3 jb3
v0.10.0
b7b684b
Compare
Choose a tag to compare

Welcome to Nostrum 0.10.0, codenamed "Orbital Insertion".

image

"Orbital Insertion" is a testament to our commitment to continuous improvement
and our vision of providing a robust and reliable Discord library for the Elixir
community. We extend our gratitude to all contributors and users who have
supported us on this journey. Your feedback and collaboration are invaluable.

Breaking Changes

  • Message cache by @Th3-M4jor in #595
    • The introduction of the message cache changes the signature of the message update event callback.

      Previously, as messages were not cached, the signature was handle_event({:MESSAGE_UPDATE, new_msg, _ws_state}), with these changes the signature is now handle_event({:MESSAGE_UPDATE, {old_msg, new_msg}, _ws_state}), where old_msg may be null if the message is not present in the cache.

      If the message is present, the old_msg value will be the previous version of the message as found in cache. Nostrum will handle the updating of the cache such that further cache requests will fetch the new message.

    • Note this is breaking EVEN IF you use a no-op cache.

New Features

  • The aforementioned message cache is newly introduced in #595.
  • We support Discord's new zstd-stream compression version
    • This compression method produces considerably smaller payload sizes at the expense of slightly increased memory usage for lookup tables.
    • See documentation here on how to enable the new compression method. It is not enabled by default as it requires additional dependencies and some compiled modules.
    • Relevant PR: Support zstd-stream gateway compression by @jb3 in #598
  • We have increased the amount of the API that we support, stickers and previously missing guild attributes have been added:
    • Add full support for guild stickers by @jb3 in #584
    • Add new guild attributes by @jb3 in #585
  • Support all voice encryption modes by @BrandtHill in #599
  • feat(shard): manually shard connect and reconnect by @tignear in #596

Quality of Life

  • Remove blob of zlib data from state machine errors by @jb3 in #583
  • Add resume_gateway_url to Nostrum.Struct.Event.Ready by @jb3 in #588
  • Refactor executable checks and add version check for non-forked youtube-dl by @BrandtHill in #594
  • Add flag to disable HTTP 2 by @jb3 in #608

Fixes

  • Fix the error caused by trying to cast a datetime to datetime by @jb3 in #582
  • fix key error in ratelimiter by @Th3-M4jor in #606
  • Handle case of non matching gun conn pids when receiving a gun_down message by @Th3-M4jor in #611
  • Ensure user struct is casted properly before updating ets cache by @Th3-M4jor in #610

Documentation

Miscellaneous

New Contributors

Full Changelog: v0.9.1...v0.10.0

0.9.1 - Trajectory Correction

04 May 18:47
@jb3 jb3
v0.9.1
2799a51
Compare
Choose a tag to compare

Welcome to Nostrum 0.9.1, code-named "Trajectory Correction".

image

We're proud to announce the latest all-American release of Nostrum 0.9.1, a
bugfix bonanza built with the spirit of liberty in mind. Covering bugfixes to
new features to countless documentation improvements, upgrade today to harness
the power of the American dream in your Discord applications.

Breaking Changes

  • Remove Nostrum.Api.get_token by @jchristgit in #569
    • As Nostrum moves to support multiple bots / library usage functionality like
      this is not desirable and as such as are removing features like this.
    • This field is set by the user anyway, so there are other methods to fetch
      this without depending on library functionality.
  • Implement memory optimizations in user struct by @jchristgit in #567
    • Removes automatic parsing of the flags attribute of User structs, but
      the Nostrum.Struct.User.Flags struct still exists to allow users to
      optionally parse this value themselves.
    • This change saves considerable storage in cache as we are now able to store
      the flags as the integer we receive them as from Discord instead of in a
      custom struct with a large number of attributes.
    • This PR also removes the mfa_enabled, verified and email attributes
      that would only be set with OAuth2. We do not expect anyone writing regular
      bots to have any dependence on these properties.

Features

  • Add missing fields from member API object by @jb3 in #573
    • Adds the pending, flags and avatar (custom guild avatar) attributes to
      Member struct
    • Also adds a helper method avatar_url/3 to the Member struct for fetching
      guild member custom avatars.
    • Adds a helper module Nostrum.Struct.Guild.Member.Flags for parsing flag
      values related to member onboarding.

Fixes

  • Re-support uploading files from memory by @jb3 in #560
  • Don't attempt to convert integers to atoms in map casting by @jb3 in #572
  • Only attempt resume if the gateway says we can by @jchristgit in #566
  • Drop session on invalid and unresumable session by @jchristgit in #580

Documentation and Debug

  • Add admonition documenting lack of DM channel caching by @jb3 in #561
  • Change command to component in documentation by @Awlexus in #568
  • Improve messages on shard resume by @jchristgit in #565
  • Update state docs with new QLC examples by @jb3 in #574
  • Add sample bot linked in issue #564 by @jchristgit in #575
  • Fix referenced function in example for create_global_application_command by @jchristgit in #577
  • Remove obsolete handle_event clause from example consumer by @jchristgit in #576
  • Log at INFO level when shard connection is up by @jchristgit in #581
  • Add cheat sheets by @jb3 in #559

Miscellaneous

  • Add OTP 27.0-rc3 to our test matrix by @jb3 in #562
    • In preparation of the release of OTP 27, we have added the latest release
      candidate to our test matrix in this PR to spot any potential teething
      issues with the upcoming release.
  • Update GitHub Action versions by @jb3 in #578
    • Stops a handful of node.js errors from appearing under the CI tab of all
      contributions to Nostrum
  • Version 0.9.1 Preparation by @jb3 in #579

Full Changelog: v0.9.0...v0.9.1

v0.9.0 - Return to Flight

20 Apr 22:39
@jb3 jb3
v0.9.0
3d8d548
Compare
Choose a tag to compare

image

Welcome to Nostrum 0.9.0, code-named "Return to Flight"!

This update isn't just another runway hop; it's a potential moon mission for bot functionality. Expect smoother performance than a high-end sports car on a freshly paved racetrack, and features so innovative they'll make even the most jaded bot user do a happy dance. Alchemists, you have my assurance that with Nostrum 0.9.0, "return to flight" isn't just a codename, it's a promise of soaring possibilities.

After a 324 day hiatus since the release of Nostrum 0.8.0, the new latest release ships with new features, performance improvements and much more, all of which are broken down below.

A full changelog of the changes since v0.8.0 and v0.9.0 can be found here.

Highlights

External

  • Support for Discord Polls, documentation here
  • All channels types are now stored in the guild channels cache (not just text and voice)
  • Add NoOp implementations for the rest of the caches

Internal

  • The ratelimiter has been turned into a state machine, yielding the following
    benefits:
    • Requests are now automatically dispatched as soon as possible, and no longer
      block the ratelimiter from running other requests.
    • The client need not concern itself with retrying later anymore, the
      ratelimiter will queue them up and schedule them when it can.
    • Every response is delivered incrementally in chunks, preventing blocking the
      ratelimiter there as well.
    • If the ratelimiter's connection to the API goes down, clients are informed
      that their requests went bust via the {:error, {:connection_died, reason}}
      return.
    • Tracing the ratelimiter's inner doings is now straightforward via
      :sys.trace(Nostrum.Api.Ratelimiter, true).
  • The shard session has been turnt into a state machine, yielding the following
    benefits:
    • Instead of retrying indefinitely on connection issues, the new shard session
      will provide more direct errors on network failure.

Breaking Changes

  • Removal of the following functions, deprecated in 0.8.0:
    • GuildCache.all/0
    • GuildCache.select_by/1
    • GuildCache.select/2 along GuildCache.select!/2
  • Removal of the non-functional Nostrum.Cache.ChannelCache module (see #555 for details)
  • Removal of support for Elixir 1.13 (#544)

Deprecations

Features

  • nostrum now ships an .appup file to allow upgrading it in environments
    requiring hot code upgrade.
    • The code_change/3-4 callbacks have been introduced to support this.

Documentation & Debug

  • Check OTP version on startup and update deprecated Logger.warn/2 calls by @BrandtHill in #528
  • New icon on documentation pages (introduced in #544)
  • Fix typos in intro.md by @dawedawe in #532
  • Add missing word to state documentation by @jchristgit in #535
  • Document StateMachineTranslator as internal by @jchristgit in #541
  • Document hot code upgrades via nostrum's .appup files.
  • Document optional contribution of appup changes.
  • Remove default handle_event. use Nostrum.Consumer manages this now.
  • New propaganda added to the assets folder

Bug Fixes

Dedications

To my new cats, Benjamin and Olive, Daddy loves you
-- Craig

(Premptively) in loving memory of Jeremiah Boby
-- Johannes

To my many loving fans in the Discord API #general channel
-- Joe

v0.9.0-rc1

20 Apr 00:12
@jb3 jb3
dd0991a
Compare
Choose a tag to compare
v0.9.0-rc1 Pre-release
Pre-release

image

Welcome to the release candidate for Nostrum 0.9, code-named "Return to Flight".

NOTE: There is not an appup instruction for this release, there will be for Nostrum 0.9.

Breaking changes

  • Removal of the non-functional Nostrum.Cache.ChannelCache module (see #555 for details)
  • Removal of support for Elixir 1.13 (#544)

Deprecations

Features

  • Support for Discord Polls
  • All channels types are now stored in the guild channels cache (not just text and voice)
  • Extra handling of user errors for lacking consumers
  • Allow fallback to HTTP/1.1 if Discord needs to disable in future
  • Add NoOp implementations for the rest of the caches

Documentation and debugging

Fixes

New Contributors

Full Changelog: v0.9.0-alpha2...v0.9.0-rc1

0.9.0-alpha2

09 Jun 20:23
v0.9.0-alpha2
88961b1
Compare
Choose a tag to compare
0.9.0-alpha2 Pre-release
Pre-release

Welcome to nostrum 0.9.0, codenamed "T - 5".

Breaking changes

The following functions, deprecated in nostrum 0.8, have been removed:

  • GuildCache.all/0
  • GuildCache.select_by/1
  • GuildCache.select/2 along with GuildCache.select!/2

Deprecations

Features

  • nostrum now ships an .appup file to allow upgrading it in environments
    requiring hot code upgrade.
    • The code_change/3-4 callbacks have been introduced to support this.
  • The ratelimiter has been turnt into a state machine, yielding the following
    benefits:
    • Requests are now automatically dispatched as soon as possible, and no longer
      block the ratelimiter from running other requests.
    • The client need not concern itself with retrying later anymore, the
      ratelimiter will queue them up and schedule them when it can.
    • Every response is delivered incrementally in chunks, preventing blocking the
      ratelimiter there as well.
    • If the ratelimiter's connection to the API goes down, clients are informed
      that their requests went bust via the {:error, {:connection_died, reason}}
      return.
    • Tracing the ratelimiter's inner doings is now straightforward via
      :sys.trace(Nostrum.Api.Ratelimiter, true).
  • The shard session has been turnt into a state machine, yielding the following
    benefits:
    • Instead of retrying indefinitely on connection issues, the new shard session
      will provide more direct errors on network failure.

Fixes

Documentation

  • Document hot code upgrades via nostrum's .appup files.
  • Document optional contribution of appup changes.
  • Remove default handle_event. use Nostrum.Consumer manages this now.

Internal changes

0.9.0-alpha1

01 Jun 10:01
v0.9.0-alpha1
1d58800
Compare
Choose a tag to compare
0.9.0-alpha1 Pre-release
Pre-release

nostrum 0.9.0-alpha1

Welcome to nostrum 0.9.0, codenamed "T - 5".

Breaking changes

The following functions, deprecated in nostrum 0.8, have bene removed:

  • GuildCache.all/0
  • GuildCache.select_by/1
  • GuildCache.select/2

Deprecations

Features

  • nostrum now ships an .appup file to allow upgrading it in environments
    requiring hot code upgrade.
  • The ratelimiter has been turnt into a state machine, yielding the following
    benefits:
    • Requests are now automatically dispatched as soon as possible, and no longer
      block the ratelimiter from running other requests.
    • The client need not concern itself with retrying later anymore, the
      ratelimiter will queue them up and schedule them when it can.
    • Every response is delivered incrementally in chunks, preventing blocking the
      ratelimiter there as well.
    • If the ratelimiter's connection to the API goes down, clients are informed
      that their requests went bust via the {:error, {:connection_died, reason}}
      return.
    • Tracing the ratelimiter's inner doings is now straightforward via
      :sys.trace(Nostrum.Api.Ratelimiter, true).

Fixes

Documentation

  • Document hot code upgrades via nostrum's .appup files.

Internal changes

0.8.0

01 Jun 07:36
v0.8.0
b6a91ff
Compare
Choose a tag to compare

Welcome to nostrum 0.8.0, codenamed "ignition on".

0_8_0_release

This release introduces full support for distributed caching and state, and
simplifies the existing cache behaviours by using a single shared interface for
reading the cache using Erlang's QLC module. Simply put, instead of having to
implement callbacks for every combination of functions that nostrum exposes (and
will expose) to the cache, a pluggable cache only needs to implement the
c:query_handle/0 callback. To fulfill this move, a few smaller breaking
changes have been performed. It is expected that these will be the last bigger
breaking changes done before the proper 1.0 release (at which point we will
follow semantic versioning).

Note that cache distribution was not the only missing piece to allow
distributing nostrum across multiple nodes (albeit the largest one). Gateway
event handling must be updated to prevent duplicate gateway connections,
proper distribution of shards over nodes must be implemented, and some other
improvements in regards to gateway connections with many shards must be
implemented, including support for persistent resume seq tokens.

Breaking changes

  • The current family of functions to read from the MemberCache have been
    replaced.
    • Functions affected:
      • MemberCache.get/1 -> MemberCache.fold/3-4
      • MemberCache.get_with_users/1 -> MemberCache.fold_with_users/3-4
      • MemberCache.by_user/1 -> MemberCache.fold_by_user/3-4
    • These changes were performed to support caches that need to perform some
      form of resource acquisition and release: ETS needs to call safe_fixtable
      for safe traversal and Mnesia needs to wrap calls in :mnesia.activity.
  • The following error returns have been renamed to a more generic version:
    • :channel_not_found -> :not_found
    • :presence_not_found -> :not_found
    • :id_not_found -> :not_found
    • :id_not_found_on_guild_lookup -> :not_found
    • :channel_not_found -> :not_found
  • The ChannelCache will no longer look up channels in the GuildCache if they
    were not found in the channel cache itself. A convenience function to fetch a
    channel from a guild (they are stored together) can be introduced to
    GuildCache if needed.
  • PresenceCache.get(user_id, guild_id) is now PresenceCache.get(guild_id, user_id), the same for PresenceCache.get!/2.
    • The reason behind this is that all "nested" caches use this form already,
      and having the arguments reversed may be confusing.

Deprecations

The following functions have been deprecated and will be removed in either
nostrum 0.9 or 1.0:

  • GuildCache.all/0
  • GuildCache.select_by/1
  • GuildCache.select/2

Features

  • Heavily improved support for querying the cache, via Erlang's QLC. This allows
    you to express strong queries in native Erlang list comprehension syntax
    without having to enumerate the entire cache by yourself, with the added bonus
    that it can automatically, at compile time, optimize your query to use indices
    and other improved traversal mechanisms on the backend you're using. For
    instance, the Mnesia member cache places an index on the guild_id field:
    queries involving this field are automatically optimized at compile time to
    utilize the index to provide for fast lookups. As an example, the following
    query is used in nosedrum as part of the member converter:
    find_by(RequestedGuildId, Name, Discriminator, MemberCache, UserCache) ->
      qlc:q([Member || {{GuildId, MemberId}, Member} <- MemberCache:query_handle(),
                       GuildId =:= RequestedGuildId,
                       {UserId, User} <- UserCache:query_handle(),
                       MemberId =:= UserId,
                       map_get(username, User)  =:= Name,
                       map_get(discriminator, User) =:= Discriminator]).
  • Support specifying a shard range to start.
    • Previously, you could either start a set number of shards, or tell nostrum
      to use the amount that Discord asked you to use.
    • A new third option is introduced, which expects a tuple in the form
      {lowest, highest, total}, where nostrum will start lowest..highest
      shards and inform Discord you have total shards in total.
    • This is useful for bots that have outgrown a single server and need to split
      their shards across multiple servers. However, see the changes below as
      well.
  • Distributed caching.
    • All Nostrum.Cache modules now have an Mnesia-based cache adapter that
      allows you to replicate and distribute the data across hosts, with the full
      power of Mnesia.
    • Larger bots can fragment their cache tables into smaller replicated cache
      tables and can thus distribute their bot without having to implement their
      own distributed caching system.
  • Distributed state.
    • As with distributed caching, Nostrum's internal state now also ships with
      Mnesia-based distributed adapters.
  • Do not require pluggable caches to implement multiple supervisor callbacks.
    Implementing child_spec is sufficient.

Fixes

  • Requeue requests that ran into a "retry later" up to 50 times.
    • This is enough to prevent any legitimate requests from being dropped, whilst
      still guarding against somebody going haywire on the ratelimiter.
  • Prevent a crash when retry_after was 0.

Documentation

  • Create documentation on how to use nostrum in a multi-node cluster.
  • Restructure the Pages tab to be more inline with which features you want to
    use.
  • Move pluggable cache modules down on the API reference list to not take up
    space from the regular cache APIs.
    • As this feature won't be needed by most bots, we don't need it to clutter up
      space for everybody.
  • Embed the consumer example into the Nostrum.Consumer moduledoc.
  • Add an "Internal modules" section on the API documentation for modules that
    are highly unlikely to be used by the regular user, but are still documented
    for completeness.

Internal changes

  • Add caching benchmarks.
  • Add propaganda assets to the VCS tree.

0.8.0-beta1

29 May 17:24
v0.8.0-beta1
7a9c858
Compare
Choose a tag to compare
0.8.0-beta1 Pre-release
Pre-release

nostrum 0.8.0-beta1

Welcome to nostrum 0.8.0, codenamed "ignition on".

This release introduces full support for distributed caching and state, and
simplifies the existing cache behaviours by using a single shared interface for
reading the cache using Erlang's QLC module. Simply put, instead of having to
implement callbacks for every combination of functions that nostrum exposes (and
will expose) to the cache, a pluggable cache only needs to implement the
c:query_handle/0 callback. To fulfill this move, a few smaller breaking
changes have been performed. It is expected that these will be the last bigger
breaking changes done before the proper 1.0 release (at which point we will
follow semantic versioning).

Note that cache distribution was not the only missing piece to allow
distributing nostrum across multiple nodes (albeit the largest one). Gateway
event handling must be updated to prevent duplicate gateway connections,
proper distribution of shards over nodes must be implemented, and some other
improvements in regards to gateway connections with many shards must be
implemented, including support for persistent resume seq tokens.

Breaking changes

  • The current family of functions to read from the MemberCache have been
    replaced.
    • Functions affected:
      • MemberCache.get/1 -> MemberCache.fold/3-4
      • MemberCache.get_with_users/1 -> MemberCache.fold_with_users/3-4
      • MemberCache.by_user/1 -> MemberCache.fold_by_user/3-4
    • These changes were performed to support caches that need to perform some
      form of resource acquisition and release: ETS needs to call safe_fixtable
      for safe traversal and Mnesia needs to wrap calls in :mnesia.activity.
  • The following error returns have been renamed to a more generic version:
    • :channel_not_found -> :not_found
    • :presence_not_found -> :not_found
    • :id_not_found -> :not_found
    • :id_not_found_on_guild_lookup -> :not_found
    • :channel_not_found -> :not_found
  • The ChannelCache will no longer look up channels in the GuildCache if they
    were not found in the channel cache itself. A convenience function to fetch a
    channel from a guild (they are stored together) can be introduced to
    GuildCache if needed.
  • PresenceCache.get(user_id, guild_id) is now PresenceCache.get(guild_id, user_id), the same for PresenceCache.get!/2.
    • The reason behind this is that all "nested" caches use this form already,
      and having the arguments reversed may be confusing.

Deprecations

The following functions have been deprecated and will be removed in either
nostrum 0.9 or 1.0:

  • GuildCache.all/0
  • GuildCache.select_by/1
  • GuildCache.select/2

Features

  • Heavily improved support for querying the cache, via Erlang's QLC. This allows
    you to express strong queries in native Erlang list comprehension syntax
    without having to enumerate the entire cache by yourself, with the added bonus
    that it can automatically, at compile time, optimize your query to use indices
    and other improved traversal mechanisms on the backend you're using. For
    instance, the Mnesia member cache places an index on the guild_id field:
    queries involving this field are automatically optimized at compile time to
    utilize the index to provide for fast lookups. As an example, the following
    query is used in nosedrum as part of the member converter:
    find_by(RequestedGuildId, Name, Discriminator, MemberCache, UserCache) ->
      qlc:q([Member || {{GuildId, MemberId}, Member} <- MemberCache:query_handle(),
                       GuildId =:= RequestedGuildId,
                       {UserId, User} <- UserCache:query_handle(),
                       MemberId =:= UserId,
                       map_get(username, User)  =:= Name,
                       map_get(discriminator, User) =:= Discriminator]).
  • Support specifying a shard range to start.
    • Previously, you could either start a set number of shards, or tell nostrum
      to use the amount that Discord asked you to use.
    • A new third option is introduced, which expects a tuple in the form
      {lowest, highest, total}, where nostrum will start lowest..highest
      shards and inform Discord you have total shards in total.
    • This is useful for bots that have outgrown a single server and need to split
      their shards across multiple servers. However, see the changes below as
      well.
  • Distributed caching.
    • All Nostrum.Cache modules now have an Mnesia-based cache adapter that
      allows you to replicate and distribute the data across hosts, with the full
      power of Mnesia.
    • Larger bots can fragment their cache tables into smaller replicated cache
      tables and can thus distribute their bot without having to implement their
      own distributed caching system.
  • Distributed state.
    • As with distributed caching, Nostrum's internal state now also ships with
      Mnesia-based distributed adapters.
  • Do not require pluggable caches to implement multiple supervisor callbacks.
    Implementing child_spec is sufficient.

Fixes

  • Requeue requests that ran into a "retry later" up to 50 times.
    • This is enough to prevent any legitimate requests from being dropped, whilst
      still guarding against somebody going haywire on the ratelimiter.
  • Prevent a crash when retry_after was 0.

Documentation

  • Create documentation on how to use nostrum in a multi-node cluster.
  • Restructure the Pages tab to be more inline with which features you want to
    use.
  • Move pluggable cache modules down on the API reference list to not take up
    space from the regular cache APIs.
    • As this feature won't be needed by most bots, we don't need it to clutter up
      space for everybody.
  • Embed the consumer example into the Nostrum.Consumer moduledoc.
  • Add an "Internal modules" section on the API documentation for modules that
    are highly unlikely to be used by the regular user, but are still documented
    for completeness.

Internal changes

  • Add caching benchmarks.
  • Add propaganda assets to the VCS tree.

0.8.0-alpha1

27 May 09:50
v0.8.0-alpha1
08dc94f
Compare
Choose a tag to compare
0.8.0-alpha1 Pre-release
Pre-release

nostrum 0.8.0-alpha1

Welcome to nostrum 0.8.0, codenamed "ignition on".

This release introduces full support for distributed caching and state, and
simplifies the existing cache behaviours by using a single shared interface for
reading the cache using Erlang's QLC module. Simply put, instead of having to
implement callbacks for every combination of functions that nostrum exposes (and
will expose) to the cache, a pluggable cache only needs to implement the
c:query_handle/0 callback. To fulfill this move, a few smaller breaking
changes have been performed. It is expected that these will be the last bigger
breaking changes done before the proper 1.0 release (at which point we will
follow semantic versioning).

Note that cache distribution was not the only missing piece to allow
distributing nostrum across multiple nodes (albeit the largest one). Gateway
event handling must be updated to prevent duplicate gateway connections,
proper distribution of shards over nodes must be implemented, and some other
improvements in regards to gateway connections with many shards must be
implemented, including support for persistent resume seq tokens.

Breaking changes

  • The current family of functions to read from the MemberCache have been
    replaced.
    • Functions affected:
      • MemberCache.get/1 -> MemberCache.fold/3-4
      • MemberCache.get_with_users/1 -> MemberCache.fold_with_users/3-4
      • MemberCache.by_user/1 -> MemberCache.fold_by_user/3-4
    • These changes were performed to support caches that need to perform some
      form of resource acquisition and release: ETS needs to call safe_fixtable
      for safe traversal and Mnesia needs to wrap calls in :mnesia.activity.
  • The following error returns have been renamed to a more generic version:
    • :channel_not_found -> :not_found
    • :presence_not_found -> :not_found
    • :id_not_found -> :not_found
    • :id_not_found_on_guild_lookup -> :not_found
    • :channel_not_found -> :not_found
  • The ChannelCache will no longer look up channels in the GuildCache if they
    were not found in the channel cache itself. A convenience function to fetch a
    channel from a guild (they are stored together) can be introduced to
    GuildCache if needed.
  • PresenceCache.get(user_id, guild_id) is now PresenceCache.get(guild_id, user_id), the same for PresenceCache.get!/2.
    • The reason behind this is that all "nested" caches use this form already,
      and having the arguments reversed may be confusing.

Deprecations

The following functions have been deprecated and will be removed in either
nostrum 0.9 or 1.0:

  • GuildCache.all/0
  • GuildCache.select_by/1
  • GuildCache.select/2

Features

  • Heavily improved support for querying the cache, via Erlang's QLC. This allows
    you to express strong queries in native Erlang list comprehension syntax
    without having to enumerate the entire cache by yourself, with the added bonus
    that it can automatically, at compile time, optimize your query to use indices
    and other improved traversal mechanisms on the backend you're using. For
    instance, the Mnesia member cache places an index on the guild_id field:
    queries involving this field are automatically optimized at compile time to
    utilize the index to provide for fast lookups. As an example, the following
    query is used in nosedrum as part of the member converter:
    find_by(RequestedGuildId, Name, Discriminator, MemberCache, UserCache) ->
      qlc:q([Member || {{GuildId, MemberId}, Member} <- MemberCache:query_handle(),
                       GuildId =:= RequestedGuildId,
                       {UserId, User} <- UserCache:query_handle(),
                       MemberId =:= UserId,
                       map_get(username, User)  =:= Name,
                       map_get(discriminator, User) =:= Discriminator]).
  • Support specifying a shard range to start.
    • Previously, you could either start a set number of shards, or tell nostrum
      to use the amount that Discord asked you to use.
    • A new third option is introduced, which expects a tuple in the form
      {lowest, highest, total}, where nostrum will start lowest..highest
      shards and inform Discord you have total shards in total.
    • This is useful for bots that have outgrown a single server and need to split
      their shards across multiple servers. However, see the changes below as
      well.
  • Distributed caching.
    • All Nostrum.Cache modules now have an Mnesia-based cache adapter that
      allows you to replicate and distribute the data across hosts, with the full
      power of Mnesia.
    • Larger bots can fragment their cache tables into smaller replicated cache
      tables and can thus distribute their bot without having to implement their
      own distributed caching system.
  • Distributed state.
    • As with distributed caching, Nostrum's internal state now also ships with
      Mnesia-based distributed adapters.
  • Do not require pluggable caches to implement multiple supervisor callbacks.
    Implementing child_spec is sufficient.

Fixes

  • Requeue requests that ran into a "retry later" up to 50 times.
    • This is enough to prevent any legitimate requests from being dropped, whilst
      still guarding against somebody going haywire on the ratelimiter.
  • Prevent a crash when retry_after was 0.

Documentation

  • Create documentation on how to use nostrum in a multi-node cluster.
  • Restructure the Pages tab to be more inline with which features you want to
    use.
  • Move pluggable cache modules down on the API reference list to not take up
    space from the regular cache APIs.
    • As this feature won't be needed by most bots, we don't need it to clutter up
      space for everybody.
  • Embed the consumer example into the Nostrum.Consumer moduledoc.
  • Add an "Internal modules" section on the API documentation for modules that
    are highly unlikely to be used by the regular user, but are still documented
    for completeness.

Internal changes

  • Add caching benchmarks.
  • Add propaganda assets to the VCS tree.