...

Package diarkis

import "github.com/Diarkis/diarkis"
Overview
Index
Subdirectories

Overview ▾

Package diarkis ▷

Diarkis server SDK allows you to write your own Diarkis server.

Diarkis Server Cluster

Diarkis server is designed to work as a cluster of servers where all servers within the cluster are able to communicate with each other freely. Each server has their server type assigned and servers with the same type are grouped together in the cluster. Default server types are based on each server's network protocol such as HTTP, UDP, and TCP.

The diagram below shows a very simplified Diarkis server cluster structure:

╔══════════════════════════════════════════════════════════════════╗
║ kubernetes                                                       ║
║                    ┌─────────────────────────────────────────┐   ║
║                    │ △ Diarkis Server Cluster                │   ║
║                    │                                         │   ║
║                    │           UDP Servers                   │   ║
║                    │        ╭╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮                 │   ║ Server-to-Client Direct communication
║                    │        ╎  ┏━━━━━━┓┓┓  ╎                 │   ║             ╭────────────────╮╮╮
║                    │        ╎  ┃  UDP ┃┃┃  ╎─────────────────│───║─────────────│ Client Devices │││
║                    │        ╎  ┗━━━━━━┛┛┛  ╎                 │   ║             ╰────────────────╯╯╯
║                    │        ╰╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯                 │   ║
║                    │                ║                        │   ║
║                    │                ║ Internal communication │   ║
║                    │                ║                        │   ║
║                    │          HTTP Servers                   │   ║
║                    │        ╭╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮                 │   ║
║ ┌───────────────┐  │        ╎  ┏━━━━━━┓┓┓  ╎    ┏━━━━━━┓     │   ║
║ │ Load balancer │╌╌│╌╌╌╌╌╌╌╌╎  ┃ HTTP ┃┃┃  ╎    ┃ MARS ┃     │   ║
║ └───────────────┘  │        ╎  ┗━━━━━━┛┛┛  ╎    ┗━━━━━━┛     │   ║
║         ╎          │        ╰╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯                 │   ║
║         ╎          │                ║                        │   ║
║         ╎          │                ║ Internal communication │   ║
║         ╎          │                ║                        │   ║
║         ╎          │           TCP Servers                   │   ║
║         ╎          │        ╭╌╌╌╌╌╌╌╌╌╌╌╌╌╌╮                 │   ║ Server-to-Client Direct communication
║         ╎          │        ╎  ┏━━━━━━┓┓┓  ╎                 │   ║             ╭────────────────╮╮╮
║         ╎          │        ╎  ┃  TCP ┃┃┃  ╎─────────────────│───║─────────────│ Client Devices │││
║         ╎          │        ╎  ┗━━━━━━┛┛┛  ╎                 │   ║             ╰────────────────╯╯╯
║         ╎          │        ╰╌╌╌╌╌╌╌╌╌╌╌╌╌╌╯                 │   ║
║         ╎          │                                         │   ║
║         ╎          └─────────────────────────────────────────┘   ║
╚══════════════════════════════════════════════════════════════════╝
          ╎
          ╎
   ┌──────────────┐┐┐ Diarkis does not authenticate users by design.
   │ API Servers  │││ It relies on the existing user authentication to authenticate the users before connecting to Diarkis server cluster.
   └──────────────┘┘┘

User Connection Flow

The diagram below shows the flow of the user starting the connection with Diarkis server cluster.

                                                 ┊                      ┊
╭───────────────╮        ┌────────────────────┐  ┊   ╔═══════════════╗  ┊  ┏━━━━━━━━━━━━━━┓   ┏━━━━━━━━━━━━━━━━━┓
│ Client Device │        │ Application Server │  ┊   ║ Load balancer ║  ┊  ┃ Diarkis HTTP ┃   ┃ Diarkis UDP/TCP ┃
╰───────────────╯        └────────────────────┘  ┊   ╚═══════════════╝  ┊  ┗━━━━━━━━━━━━━━┛   ┗━━━━━━━━━━━━━━━━━┛
        │                           │            ┊           ║          ┊         │                    │
        ├───────────▶︎[ User Authentication ]     ┊           ║          ┊         │                    │
        │                           │            ┊           ║          ┊         │                    │
        │                           ├───────────────────────▶︎╠══════════▶︎[ Endpoint Request ]          │
        │                           │            ┊           ║          ┊         │                    │
        │                           │            ┊           ║          ┊         ├────────────▶︎[ User Creation ]
        │                           │            ┊           ║          ┊         │                    │
        │                  [ UDP/TCP Endpoint ]◀︎═════════════╣◀︎───────────────────┤                    │
        │                           │            ┊           ║          ┊         │                    │
[ UDP/TCP Endpoint ]◀︎───────────────┤            ┊           ║          ┊         │                    │
        │                           │            ┊           ║          ┊         │                    │
        ├───────────────────────────────────────────────────────────────────────────────▶︎[ UDP/TCP Direct Connection ]
        │                           │            ┊           ║          ┊         │                    │
        ▽                           ▽            ┊           ▽          ┊         ▽                    ▽
                                                 ┊                      ┊

Environment Variables

Diarkis server has many environment variables to control how the server behaves.

┌───────────────────────────┬─────────┬─────────────────────────────────────────────────────────────────────────────────────────┬──────────┐
│ Environment Variable Name │ Values  │ Description                                                                             │ Required │
├───────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────────────────────────┼──────────┤
│ DIARKIS_CLOUD_ENV         │ GCP     │ Auto-assign public IP address to UDP and TCP server for Google Cloud.                   │     ○    │
│                           │ AWS     │ Auto-assign public IP address to UDP and TCP server for AWS.                            │          │
│                           │ AZURE   │ Auto-assign public IP address to UDP and TCP server for Microsoft Azure.                │          │
│                           │ TENCENT │ Auto-assign public IP address to UDP and TCP server for Tencent Cloud.                  │          │
│                           │ ALIBABA │ Auto-assign public IP address to UDP and TCP server for Alibaba Cloud.                  │          │
│                           │ LINODE  │ Auto-assign public IP address to UDP and TCP server for Linode.                         │          │
│                           │ $(host) │ Manually assigns a hostname or IP address to the server.                                │          │
├───────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────────────────────────┼──────────┤
│ DIARKIS_SHUTDOWN_TIMEOUT  │ $(sec)  │ Configures the wait time in seconds to shutdown after receiving SIGTERM.                │     △    │
│                           │         │ Default is 10 seconds.                                                                  │          │
│                           │         │ Time out value configured here must match Kubernetes' terminationGracePeriodSeconds.    │          │
├───────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────────────────────────┼──────────┤
│ DIARKIS_SERVER_TYPE       │ $(type) │ Assigns custom server type to the server. Default is either HTTP, UDP, or TCP.          │          │
│                           │         │ This is the server type HTTP API of /endpoint/type/$(server_type)/user/$(user_id) uses. │          │
├───────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────────────────────────┼──────────┤
│ DIARKIS_USE_STRUCT_ERR    │ TRUE    │ If configured, all errors of built-in server commands will be structured errors.        │          │
│                           │         │ A structured error contains an error code (uint32) and an error message string.         │          │
├───────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────────────────────────┼──────────┤
│ DIARKIS_JSON_LOG          │ TRUE    │ If configured, all Diarkis logging will be JSON formatted.                              │          │
├───────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────────────────────────┼──────────┤
│ DIARKIS_APP_NAME          │ $(name) │ Assigns a custom application name to the server to group servers with the same name.    │          │
│                           │         │ If servers with different names are connected to the same MARS,                         │          │
│                           │         │ they will not see each other effectively creating different Diarkis cluster.            │          │
├───────────────────────────┼─────────┼─────────────────────────────────────────────────────────────────────────────────────────┼──────────┤
│ DIARKIS_CLIENT_KEY        │ $(key)  │ If configured, the server requires the key to be sent from all connected clients.       │          │
│                           │         │ If client key is not configured, the server does not require the key to be sent.        │          │
└───────────────────────────┴─────────┴─────────────────────────────────────────────────────────────────────────────────────────┴──────────┘

▶︎ DIARKIS_CLOUD_ENV is required for each server to assign correct public hostname/IP address.

▶︎ DIARKIS_SHUTDOWN_TIMEOUT is not required, however, it must be configured to the same value as kubernetes' terminationGracePeriodSeconds configuration.

SIGUSR1 and SIGUSR2

Diarkis server captures SIGUSR1 and SIGUSR2 signal and have the server perform pre-defined custom operations at runtime.

Below is the step by step instruction of how to trigger pre-defined custom operations:

1. Create a file called DIARKIS_SIGUSR1 or DIARKIS_SIGUSR2 under /tmp/ directory.

2. In the file, write the pre-defined operation name WITHOUT a line break.

3. Send either SIGUSR1 or SIGUSR2 signal to the server.

▶︎ Example of pre-defined operation implementation

// This is the operation name that goes into DIARKIS_SIGUSR1 file
taskName := "ExampleOperation"

// The callback does not have to be a closure function...
diarkis.OnSIGUSR1(taskName, func() {
  fmt.Println("Diarkis server received SIGUSR1 signal and task is ExampleOperation")
})

Built-in SIGUSR1 Operations

There are a few built-in SIGUSR1 operations that you may you out-of-the-box.

▶︎ TaskName: Debug

This operation is a toggle. Call it once will enable it and calling it again will disable it.

When "Debug" is enabled, Go's profiler is enabled. You may access profiler's internal server at http://127.0.0.1:6060 (Assuming port 6060 is not already being used...).

Change Log Level For A Specific Logger Name at Runtime

Diarkis logger allows you to change a specific logger's log level in runtime as well.

Logger name is the string output that is wrapped in < and >. If you see <SERVER>, then logger name is SERVER.

Below is the step by step operation to change log level by logger name in runtime.

1. Create a signal command file named DIARKIS_SIGUSR1 under /tmp/ directory. It should look like this: /tmp/DIARKIS_SIGUSR1

▶︎ Enable runtime log level change by logger name

DIARKIS_SIGUSR1 file must contain the following to enable runtime log level change:

LogLevelChangeByName
Enable
$(logger_name)
$(log_level)

Example:

The example below will enable verbose level of logging just for "ROOM" logs.

LogLevelChangeByName
Enable
ROOM
Verbose

▶︎ Disable runtime log level change by logger name

DIARKIS_SIGUSR1 file must contain the following to disable runtime log level change:

LogLevelChangeByName
Disable

Change Log Level Globally At Runtime

You may change log level for all logging at runtime.

[IMPORTANT] If LogLevelChangeByName is enabled, it takes the highest priority for the specified log name.

▶︎ TaskName: LogLevel:Verbose

This operation will change Diarkis logger's log level at runtime to verbose.

▶︎ TaskName: LogLevel:Network

This operation will change Diarkis logger's log level at runtime to network.

▶︎ TaskName: LogLevel:Sys

This operation will change Diarkis logger's log level at runtime to sys.

▶︎ TaskName: LogLevel:Debug

This operation will change Diarkis logger's log level at runtime to debug.

▶︎ TaskName: LogLevel:Info

This operation will change Diarkis logger's log level at runtime to info.

▶︎ TaskName: LogLevel:Error

This operation will change Diarkis logger's log level at runtime to error.

▶︎ TaskName: LogLevel:Fatal

This operation will change Diarkis logger's log level at runtime to fatal.

Rotate Log Level Globally

▶︎ TaskName: LogLevelChange

This operation will change Diarkis logger's log level at runtime. Every time this operation is called the log level changes.

[IMPORTANT] If LogLevelChangeByName is enabled, it takes the highest priority for the specified log name.

Below is the order of log level change:

   ╭─────────╮ ╭─────────╮ ╭─────────╮ ╭─────────╮ ╭─────────╮
╔═▶︎│ Verbose │▶︎│ Network │▶︎│   Sys   │▶︎│  Debug  │▶︎│   Info  │══╗
║  ╰─────────╯ ╰─────────╯ ╰─────────╯ ╰─────────╯ ╰─────────╯  ║
╚═══════════════════════════════════════════════════════════════╝

▶︎ TaskName: VaultDump

This operation dumps users, room, and group data of the server into stdout stream.

▶︎ MatchMakerDump

This operation dumps MatchMaker data of the server into stdout stream.

Execute Custom Operations When Server Started and Ready

You may assign your custom operations to be executed when the server is started and ready.

▶︎ Example

diarkis.OnReady(func(next func(err error)) {
  // Do something amazing because the server is ready.

  // Make sure to call next to move on.
  // Passing an error to next will abort the server with an error.
  next(nil)
})

Execute Custom Operations When Shutting Down the Server

You may assign your custom operations to be executed when the server shuts down.

The server will "wait" for those operations to finish before shutting down.

▶︎ Example

diarkis.OnTerminate(func(next func(err error)) {
  // Do something important before going away.
  // Like closing connections to DB etc.

  // Make sure to call next to move on.
  next(nil)
})

Health Check Probe

Diarkis server comes with health check probe. This probe will check UDP/RUDP's public facing network availability and internal network availability.

▶︎ How To Execute the Probe

The probe requires a configuration JSON file in the following path: The JSON file must be named health-check.json.

bin/tools/configs/health-check.json

▶︎▶︎ Test Public Network Availability (UDP/RUDP server ONLY)

When the Diarkis server is running, the server places a file that contains its public address and port.

/tmp/DIARKIS_PUBLIC_ADDR

Use the file shown above to test public network:

# Health check probe binary   # Text file that contains public address and port   # Flag for public network probe
./health-check                `cat /tmp/DIARKIS_PUBLIC_ADDR`                      out

▶︎▶︎ Test Internal Network Availability (All Diarkis servers)

When the Diarkis server is running, the server places a file that contains its internal address and port.

/tmp/DIARKIS_MESH_ADDR

Use this file shown above to test internal network:

# Health check probe binary    # Text file that contains internal address and port    # Flag for internal network probe
./health-check                 `cat /tmp/DIARKIS_MESH_ADDR`                       in

▶︎▶︎ Test Internal Network Availability (All Diarkis servers) And Communication With MARS

When the Diarkis server is running, the server places a file that contains its internal address and port.

/tmp/DIARKIS_MESH_ADDR

Use this file shown above to test internal network and communication status with MARS:

# Health check probe binary    # Text file that contains internal address and port    # Flag for internal network + MARS probe
./health-check                 `cat /tmp/DIARKIS_MESH_ADDR`                       mars

Use Environment Variables For Configurations

Diarkis uses JSON formatted configuration files to configure Diarkis itself and modules. These configuration files may have a spacial tags as configuration values to be replaced by environment variables on server start.

▶︎ Format

The placeholders in your configuration files must follow the format shown below:

{$DIARKIS_...}

▶︎ Example

DIARKIS_EXAMPLE_HELLO=HELLO
DIARKIS_EXAMPLE_NUMBER=1000

{
  "helloWorld":"{$DIARKIS_EXAMPLE_HELLO}",
  "number": {$DIARKIS_EXAMPLE_NUMBER}
}

The above example will convert the configurations as shown below:

DIARKIS_EXAMPLE_HELLO_=HELLO
DIARKIS_EXAMPLE_NUMBER=1000

{
  "helloWorld":"HELLO",
  "number": 1000
}

Constants

const (
    // Version This is the version of diarkis
    Version = "0.9.29"
    // Author This is the author of diarkis
    Author = "Diarkis"
)

func GetCPUNumUsed

func GetCPUNumUsed() int

GetCPUNumUsed returns the number of CPU the process is using

func GetDiarkisPath

func GetDiarkisPath() string

GetDiarkisPath Returns the absolute path to diarkis

func GetShutdownTimeout

func GetShutdownTimeout() int64

GetShutdownTimeout returns the server process shutdown timeout in seconds.

[IMPORTANT] Default is 10 seconds.
[IMPORTANT] If DIARKIS_SHUTDOWN_TIMEOUT env is given, shutdown timeout changes.

func GetVer

func GetVer() string

GetVer Returns the version of diarkis

func IsRunning

func IsRunning() bool

IsRunning returns true if diarkis process is running

func IsStarted

func IsStarted() bool

IsStarted returns true after OnStarted callbacks have been executed.

If true, Diarkis server process has finished all preparation operations and ready.

func IsTerminating

func IsTerminating() bool

IsTerminating returns true when the process is shutting down

func OnReady

func OnReady(task func(func(error)))

OnReady Registers a callback on diarkis ready (This will be invoked before OnStarted while the server is being started)

This event is raised after all OnStart tasks have completed their operations.

task - Callback to be invoked while Diarkis server process is being started.
       Must call next function at the end of the callback to make sure the process moves on to the next task.

func OnReadyLast

func OnReadyLast(lastTask func(func()))

OnReadyLast it is used by ONLY mesh internally

func OnSIGHUP

func OnSIGHUP(task func())

OnSIGHUP Registers a callback on SIGHUP signal

task - Callback to be invoked when the server receives the signal.

func OnSIGUSR1

func OnSIGUSR1(taskName string, task func()) bool

OnSIGUSR1 Registers a callback on SIGUSR1 signal. When the signal is captured, Diarkis will look for a specific file in /tmp/ directory.

The file in /tmp/ must be named as DIARKIS_SIGUSR1 and the file must contain a task name.

The task name is then read by Diarkis and if a task callback with the task name exists, it is then invoked.

taskName - Associated with the callback.
task     - Callback to be invoked when the server receives the signal.

func OnSIGUSR1WithParams

func OnSIGUSR1WithParams(taskName string, task func(params []string)) bool

OnSIGUSR1WithParams assigns a callback on SIGUSR1 signal. When the signal is captured, Diarkis will look for a specific file in /tmp/ directory.

The file in /tmp/ must be named as DIARKIS_SIGUSR1 and the file must contain a task name.

The task name is then read by Diarkis and if a task callback with the task name exists, it is then invoked.

Task file format:

The first line must be the task name and the following lines will be parameters.

$(task_name)
$(parameter1)
$(parameter2)
$(...)

Parameters

taskName - Associated with the callback.
task     - Callback to be invoked when the server receives the signal.

func OnSIGUSR2

func OnSIGUSR2(taskName string, task func()) bool

OnSIGUSR2 Registers a callback on SIGUSR1 signal

When the signal is captured, Diarkis will look for a specific file in /tmp/ directory.

The file in /tmp/ must be named as DIARKIS_SIGUSR2 and the file must contain a task name.

The task name is then read by Diarkis and if a task callback with the task name exists, it is then invoked.

taskName - Associated with the callback.
task     - Callback to be invoked when the server receives the signal.

func OnSIGUSR2WithParams

func OnSIGUSR2WithParams(taskName string, task func(params []string)) bool

OnSIGUSR2WithParams assigns a callback on SIGUSR2 signal. When the signal is captured, Diarkis will look for a specific file in /tmp/ directory.

The file in /tmp/ must be named as DIARKIS_SIGUSR2 and the file must contain a task name.

The task name is then read by Diarkis and if a task callback with the task name exists, it is then invoked.

Task file format:

The first line must be the task name and the following lines will be parameters.

$(task_name)
$(parameter1)
$(parameter2)
$(...)

Parameters

taskName - Associated with the callback.
task     - Callback to be invoked when the server receives the signal.

func OnStart

func OnStart(task func())

OnStart Registers a callback on diarkis process start.

task - Callback to be invoked when Diarkis server is started.

func OnStarted

func OnStarted(callback func())

OnStarted registers a callback to be invoked when diarkis server process completed all starting operations.

This event is raised after all OnReady tasks have completed their operations.

callback - Callback to be invoked when Diarkis server finishes all pre-start operations and ready.

func OnTerminate

func OnTerminate(task func(func(error)))

OnTerminate Registers a callback on diarkis process terminate

task - Callback to be invoked when the server receives SIGTERM.
       next function must be called at the end of the callback to move on to the next callbacks.

func Run

func Run()

Run Starts diarkis process and stops when all operations are done

func Start

func Start()

Start Starts diarkis process and stays running until it is instructed to stop.

This function will block until the process is terminated. It will raise OnReady event.

func Stop

func Stop()

Stop Stops diarkis process exit code is 0

func StopWithError

func StopWithError(err error)

StopWithError Stops diarkis process with an error exit code is 1

Subdirectories

Name Synopsis
..
config
datacapsule Package datacapsule ▷
debug Package debug ▷
dive Package dive ▷
dm Package dm ▷
encryption
error
eventemitter
field Package field ▷
group Package group ▷
groupSupport
log Package log ▷
lib
colorize
msg
std
mars
matching Package matching ▷
members
mesh Package mesh ▷
lib
announcer
msg
packet
reliable
udp
metrics Package metrics ▷
mutex
net
p2p
packet
process
progressbar
room Package room ▷
mapping
roomSupport
scripts
server Package server ▷
connector
http Package http ▷
tcp
udp
ws
session Package Session ▷
smap Package smap ▷
synchronizer
test
bot
lib
notifier
tester Package tester ▷
tests
cloud_services
azure
datacapsule
field
http
integration
mapping
mars
matching
members
mesh
packet
servers
cmds
smap
tcp
timed
udp
user
util
vault
timed
user
util Package util ▷
uuid
v4
vault
wsEncryption