Skip to content

Commit

Permalink
update contributing
Browse files Browse the repository at this point in the history
  • Loading branch information
switchupcb committed Dec 3, 2022
1 parent f203b1e commit d3d85ae
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 39 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
[![Go Doc](https://img.shields.io/badge/godoc-reference-5272B4.svg?style=for-the-badge&logo=appveyor&logo=appveyor)](https://pkg.go.dev/github.com/switchupcb/disgo)
[![License](https://img.shields.io/github/license/switchupcb/disgo.svg?style=for-the-badge)](https://github.com/switchupcb/disgo/blob/main/LICENSE)

**This repository is ALMOST STABLE. For more information, read the [roadmap](/_contribution/CONTRIBUTING.md#roadmap).**

**Disgo** is a [Discord API](https://discord.com/developers/docs/reference) Wrapper designed to be flexible, performant, secure, and thread-safe. Disgo aims to provide every feature in the Discord API along with optional rate limiting, structured logging, shard management, and caching. Use the only Go module to provide a **100% one-to-one implementation** of the Discord API.

_This repository is STABLE. For more information, read the [roadmap](/_contribution/CONTRIBUTING.md#roadmap)._

## A Next Generation Discord API Wrapper

High quality code merits easy development. Disgo uses developer operations to stay up-to-date with the ever-changing Discord API. Code generation is used to provide a clean implementation for every request and event. Data race detection is used with _an integration test that covers the entire Discord API_ in order to ensure that Disgo is safe for concurrent usage. In addition, **Disgo provides the following exclusive features**.
Expand All @@ -30,13 +30,13 @@ _Disgo uses [NO reflection or type assertion](_contribution/concepts/EVENTS.md#h

This breakdown provides you with a **full understanding** on how to use the API.

| Abstraction | Usecase | Example |
| :----------- | :----------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------ |
| **Resource** | A [Discord API Resource](https://discord.com/developers/docs/resources/application). | Guild Object. User Object. |
| **Event** | A [Discord API Event](https://discord.com/developers/docs/topics/gateway#commands-and-events-gateway-events). | A message is created. A user joins a channel. |
| **Client** | The Discord Bot [Application](https://discord.com/developers/docs/resources/application) that you program. One Bot = One Client. | Configure the bot settings. Set the token. |
| **Request** | Uses the Discord HTTP REST API to make one-time requests for information. | Create an application command. Request guild information. |
| **Session** | Uses Discord WebSockets [(Gateways)](https://discord.com/developers/docs/topics/gateway) to receive ongoing **events** that contain information. | Send a message when a command used or a user joins a voice channel. |
| Abstraction | Usecase | Example |
| :----------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------ |
| **Resource** | A [Discord API Resource](https://discord.com/developers/docs/resources/application). | Guild Object. User Object. |
| **Event** | A [Discord API Event](https://discord.com/developers/docs/topics/gateway#commands-and-events-gateway-events). | A message is created. A user joins a channel. |
| **Client** | The Discord Bot [Application](https://discord.com/developers/docs/resources/application) that you program. One Bot = One Client. | Configure the bot settings. Set the token. |
| **Request** | Uses the Discord HTTP REST API to make one-time _requests_ for information. | Create an application command. Request guild information. |
| **Session** | Uses a Discord WebSocket Connection [(Gateway)](https://discord.com/developers/docs/topics/gateway) to receive _events_ that contain information. | Send a message when a command used or a user joins a voice channel. |

You create a **Client** that calls for **Resources** using **Requests** and handles **Events** from **Sessions** using event handlers. For more information, please read [What is a Request?](/_contribution/concepts/REQUESTS.md) and [What is an Event?](/_contribution/concepts/EVENTS.md)

Expand All @@ -46,7 +46,7 @@ A flag is a [flag](https://discord.com/developers/docs/resources/application#app

### Logging

Read [What is a Log](/_contribution/concepts/LOG.md) for a simple yet full understanding of logging with Disgo. Disgo provides leveled logging of the API Wrapper via the `disgo.Logger` global variable _(which is disabled by default)_. Enable it using `zerolog.SetGlobalLevel(zerolog.LEVEL)`.
Read [What is a Log](/_contribution/concepts/LOG.md) for a simple yet full understanding of logging. Disgo provides structured, leveled logging of the API Wrapper via the `disgo.Logger` global variable _(disabled by default)_. Enable the logger using `zerolog.SetGlobalLevel(zerolog.LEVEL)`.

### Sharding

Expand Down
13 changes: 6 additions & 7 deletions _contribution/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,12 @@ Use `go test` to run the tests in the current directory. Use `go test ./<dir>` t

# Roadmap

Disgo is **ALMOST STABLE**. Here are the steps required in order to complete it.
Disgo is **STABLE**. Here are the steps required in order to complete it.

1. **Finish Full Coverage Test** _[STABLE]_.
2. Bundle Disgo (with `fieldalignment`) _[v10.0.0]_.
1. Bundle Disgo (with `fieldalignment`) _[v10.0.0]_.

In addition, the following features are being worked on.
The following additional features are being implemented.

1. Voice Connections: [Decision (UDP)](/_contribution/libraries/), [Audio Processing using Opus](https://discord.com/developers/docs/topics/voice-connections#encrypting-and-sending-voice)
2. Implement [Sharding](https://github.com/switchupcb/disgo/issues/26).
3. Implement [Cache](https://github.com/switchupcb/disgo/issues/39).
1. Voice Connections ([UDP Decision](/_contribution/libraries/), [Audio Processing using Opus](https://discord.com/developers/docs/topics/voice-connections#encrypting-and-sending-voice))
2. [Sharding](https://github.com/switchupcb/disgo/issues/26)
3. [Cache](https://github.com/switchupcb/disgo/issues/39)
4 changes: 2 additions & 2 deletions _contribution/concepts/CACHE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ Disgo provides an **optional** cache along with a **cache interface** for your D

## Why Do We Cache?

Using **Requests** and **Sessions** allow us to retrieve data from Discord, but it becomes redundant to receive the same data over and over again. For example, retrieving _the amount of users in a guild_ requires a network request to be sent _to_ and returned _from_ Discord. Without a cache, retrieving _the exact same information_ requires yet another network request; even when guild's condition remains unchanged. A cache is an alternative to sending redundant requests — that take time to complete — to Discord. A cache stores data so that future requests for that data can be served immediately.
Using **Requests** and **Sessions** allow you to retrieve data from Discord, but it becomes redundant to receive the same data over and over again. For example, retrieving _the amount of users in a guild_ requires a network request to be sent _to_ and returned _from_ Discord. Without a cache, retrieving _the exact same information_ requires yet another network request; even when guild's condition remains unchanged. A cache is an alternative to sending redundant requests — that take time to complete — to Discord: A cache stores data so that future requests for that data can be served immediately.

## When to Use a Cache?

Caches are useful for storing costly requests or calculations relevant to the lifetime of the application. In other words, A cache is not meant to be used for long-term storage. **If you need data to persist when your bot restarts, use a database.**
Caches are useful for storing costly requests or calculations relevant to the lifetime of the application. In other words, a cache is **NOT** meant to be used for long-term storage. **If you need data to persist when your bot restarts, use a database.**

## How Does a Cache Work?

Expand Down
2 changes: 1 addition & 1 deletion _contribution/libraries/LOGGING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Logging

Logging is used to provide information throughout the application. Disgo uses [**Zerolog**](https://github.com/rs/zerolog) for performant zero-allocation logging.
Logging is used to provide information throughout the application. Disgo uses `zerolog` for performant zero-allocation logging.

## Other Benchmarks

Expand Down
2 changes: 1 addition & 1 deletion _contribution/libraries/URL.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# URL

URL encoded query strings are involved in a number of Discord API HTTP requests. Disgo uses `gorilla/schema` to encode and decode URL Query String (Parameters). This may change to a custom library or custom functions in the future to avoid the use of reflection.
URL encoded query strings are involved in a number of Discord API HTTP requests. Disgo uses `gorilla/schema` to encode and decode URL Query String (Parameters).
36 changes: 18 additions & 18 deletions shard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,51 @@

The Disgo Shard Manager is a Go module that automatically handles sharding for your Discord Bot. The Disgo Shard Manager works by scaling your WebSocket Sessions through a `disgo.Client.Sessions` array. The `Client` calls `GET /gateway/bot` to retrieve the recommended number of shards to use upon joining a `dynamic number` of guilds. These shards are assigned to a **Session** until the [max concurrency](https://discord.com/developers/docs/topics/gateway#sharding-max-concurrency) limit is reached. For information on the concept of a shard, read [What is a Discord Shard?](/_contribution/concepts/SHARD.md)

## Implementation
# Implementation

### Terminology
## Terminology

#### What is an application?
### What is an application?

An application refers to a built binary that is executed on your computer. You run applications through the terminal (i.e `run.exe`) or via visual shortcuts. In the context of this explanation, an application refers to the code that your Discord Bot uses to run on a **server**.

#### What is a server?
### What is a server?

A server is a computer (with a specialized use-case). You run applications on computers. A discord bot application is hosted _(run)_ on a server.

#### What is a guild?
### What is a guild?

Guilds in Discord represent an isolated collection of users and channels, and are often referred to as "servers" in the User Interface (UI). However, these "servers" are **NOT** the same as the **servers** described above. A Discord guild is a concept, while a **server** is a physical machine.

### Method
## Method

Sharding on Discord is a two-step process that involves implementing shard-logic in your application and sharding your infrastructure. The **Disgo Shard Manager** handles the first step for you, so **how do we shard our infrastructure?** Discord only allows you to shard by guild, so - barring a load-balanced architecture - you must handle _every_ important Discord Event in every Discord Bot application with a single codebase. As a result, the only way to shard the infrastructure of your Discord Bot application _— without requiring additional code —_ is to host multiple copies of it _(each handling a fraction of your total load)_. This is known as **active-active load balancing**.
Sharding on Discord is a two-step process that involves implementing shard-logic in your application and sharding your infrastructure. The **Disgo Shard Manager** handles the first step for you, so **how do you shard your infrastructure?** Discord only allows you to shard by guild, so barring a load-balanced architecture you must handle _every_ important Discord Event in every Discord Bot application within a single codebase. As a result, the only way to shard the infrastructure of your Discord Bot application _— without requiring additional code —_ is to host multiple copies of it _(each handling a fraction of your total load)_. This is known as **active-active load balancing**.

_The Disgo Shard Manager implements this method._
_The Disgo Shard Manager implements this method. Read the following explanation for an alternative._

#### Explanation
### Explanation

A WebSocket Session contains **shards** that contain **individual guilds**. Ignoring specific events for one shard would ignore those same events from multiple guilds the shard contains _(since you can't specify a guild's shard)_. Following this logic, ignoring a **session's events** ignores **multiple shards' events** which ignores **multiple guilds' events**. Since Discord requires you to shard by guild, we **CANNOT** shard the infrastructure of our Discord Bot by creating multiple applications that handle a single event without an alternative infrastructure.
A WebSocket Session contains **shards** that contain **individual guilds**. Ignoring specific events for one shard would ignore those same events from multiple guilds the shard contains _(since you can't specify a guild's shard)_. Following this logic, ignoring a **session's events** ignores **multiple shards' events** which ignores **multiple guilds' events**. Since Discord requires you to shard by guild, you **CANNOT** shard the infrastructure of our Discord Bot by creating multiple applications that handle a single event without an alternative infrastructure.

#### Alternative
### Alternative

A load balancer allows us to "shard" our bot by event. This entails creating **one application** _(the load balancer)_ that accepts every event your bot receives _(and thus every shard)_, and having that **same application** forward those events to micro-applications _(which run on other servers)_. Placing every "shard" in a single application requires that same application to maintain every session. As a result, your load balancer's only purpose — in this alternative method — should be to balance the load by routing events to other applications. When the load balancer _(that handles every session)_ goes down, so does your bot.

### QA
## QA

#### When do I need to shard?
### When do I need to shard?

Discord requires you to shard once you've reached a certain number of guilds.

#### What do I need to do?
### What do I need to do?

Discord requires that you implement sharding logic in your bot, which is what this module - the **Disgo Shard Manager** - does.
Discord requires that you implement sharding logic in your bot, which is what this module the **Disgo Shard Manager** does.

#### Is that all?
### Is that all?

Technically, **yes**. The purpose of Discord's sharding requirement is to minimize the amount of data they send per WebSocket Session on their end. There is nothing stopping you from using one server that creates multiple sessions and handles them in one application.
Technically, **yes**. The purpose of Discord's sharding requirement is to minimize the amount of data that Discord sends per WebSocket Session. There is nothing stopping you from running one server that creates multiple sessions and handles them in one application.

#### What are the implications of using one server?
### What are the implications of using one server?

Servers are computers with **CPU**, **RAM**, and **Storage**. The reason that you typically run one application on a server is because you expect that application to use **all** of the server's resources _(i.e 100% CPU, 100% RAM, etc)_. Placing multiple applications on one server is only useful if your application does **NOT** use all of the server's resources, cores, etc. This would imply that your application is handling a low amount of data or experiencing a bottleneck _(i.e waiting on a network request)_. If a server with two cores — without any form of multithreading — has an application using _<100% CPU_ on one core, then you would be able to add an additional application _(that uses the other core)_ to the server without a performance hit.

Expand Down

0 comments on commit d3d85ae

Please sign in to comment.