Skip to content

0.8.0

Compare
Choose a tag to compare
@jchristgit jchristgit released this 01 Jun 07:36
· 351 commits to master since this release
v0.8.0
b6a91ff

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.