package diarkis

import "github.com/Diarkis/diarkis"

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 ]
        │                           │            ┊           ║          ┊         │                    │
        ▽                           ▽            ┊           ▽          ┊         ▽                    ▽
                                                 ┊                      ┊

Setting Up Diarkis Server

Please refer to diarkisexec package for more information.

Environment Variables

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

Environment Variable NameValuesDescriptionRequired
DIARKIS_CLOUD_ENV





GCP
AWS
AZURE
TENCENT
ALIBABA
LINODE
$(host)
Auto-assign public IP address to UDP and TCP server for Google Cloud.
Auto-assign public IP address to UDP and TCP server for AWS.
Auto-assign public IP address to UDP and TCP server for Microsoft Azure.
Auto-assign public IP address to UDP and TCP server for Tencent Cloud.
Auto-assign public IP address to UDP and TCP server for Alibaba Cloud.
Auto-assign public IP address to UDP and TCP server for Linode.
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_LOGTRUEIf 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_STOP_PROCESS_ON_SIGHUP

TRUE

If configured, the process will terminate itself on SIGHUP.
This is meant to be used by developer as it prevents diarkis processes to keep running
in background if their parent process terminates.

▶︎ 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.

See OnSIGUSR1 for more details.

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

Given the environment variables.

DIARKIS_EXAMPLE_HELLO=HELLO
DIARKIS_EXAMPLE_NUMBER=1000

And the configuration file.

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

The above example will convert the configurations as shown below:

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

Index

Examples

Constants

const (
	// Version This is the version of diarkis
	Version = version.Version
	// Author This is the author of diarkis
	Author = version.Author
)

Variables

var NodeRoles = []NodeRole{UDP, TCP, HTTP, DGS}

NodeRoles is the slice of all possible Diarkis node roles.

Functions

func GetCPUNumUsed deprecated

func GetCPUNumUsed() int

GetCPUNumUsed returns the number of CPU the process is using

Deprecated: Please use runtime.NumCPU to know GOMAXPROCS. This value will never change, as it is never modified once the runtime is initialized.

func GetDiarkisPath deprecated

func GetDiarkisPath() string

GetDiarkisPath Returns the absolute path to diarkis

Deprecated: Please use Path instead.

func GetShutdownTimeout deprecated

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.

Deprecated: Please use ShutdownTimeout

func GetVer deprecated

func GetVer() string

GetVer Returns the version of diarkis

Deprecated: Please reference the global constant Version instead.

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.
Example

Execute Custom Operations When Server Started and Ready. You may assign your custom operations to be executed when the server is started and ready.

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)
})

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.
Example

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

In this context /tmp/ refers to the result of os.TempDir().

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.

taskName := "ExampleOperation"

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

func OnSIGUSR1NoTask

func OnSIGUSR1NoTask(callback func())

OnSIGUSR1NoTask Registers a callback function on SIGUSR1 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 OnSIGUSR2NoTask

func OnSIGUSR2NoTask(callback func())

OnSIGUSR2NoTask Registers a callback function on SIGUSR2 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 OnStop

func OnStop(task func(ctx context.Context, done func(error)))

OnStop Registers a callback on diarkis process stop

ctx  - Use ctx.Done() to listen for the shutdown timeout.
task - Callback to be invoked when the server receives SIGTERM.
       done function must be called at the end of the callback to notify the server that the task is done.

func OnTerminate

func OnTerminate(task func(context.Context, func(error)))

OnTerminate Registers a callback on diarkis process terminate

ctx  - Use ctx.Done() to listen for the shutdown timeout.
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.
Example

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.

OnTerminate(func(ctx context.Context, next func(error)) {
	// Do something important before going away.
	// Like closing connections to DB etc.

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

func Path

func Path() string

Path returns the absolute path to Diarkis

func Run

func Run()

Run Starts diarkis process and stops when all operations are done

func ShutdownTimeout

func ShutdownTimeout() int64

ShutdownTimeout returns the server process shutdown timeout in seconds.

Default is 10 seconds if the DIARKIS_SHUTDOWN_TIMEOUT environment variable is not set.

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 StopWithCallback

func StopWithCallback(done func())

StopWithCallback Stops the process and calls `done` function when the stopping process is finished.

func StopWithError

func StopWithError(err error)

StopWithError Stops diarkis process with an error exit code is 1

Types

type NodeRole

type NodeRole string

NodeRole is an internal type representing a Diarkis node role.

const (
	// UDP represents the Diarkis UDP server role.
	UDP NodeRole = "UDP"
	// TCP represents the Diarkis TCP server role.
	TCP NodeRole = "TCP"
	// HTTP represents the Diarkis HTTP server role.
	HTTP NodeRole = "HTTP"
	// DGS represents the Diarkis DGS server role.
	DGS NodeRole = "DGS"
)

func (NodeRole) String

func (nr NodeRole) String() string

Directories

build/health-check
build/mars-stats
client Package client implements a UDP/TCP Diarkis compatible client.
config
datacapsule Package datacapsule ▷
debug Package debug ▷
derror Package derror ▷
dgs Package dgs ▷
diarkisexec Package diarkisexec ▷
dive Package dive ▷
dm Package dm ▷
field Package field ▷
group Package group ▷
groupsupport
log Package log ▷
mars
matching Package matching ▷
members
mesh Package mesh ▷
metrics Package metrics ▷
p2p
packet
process Package process is deprecated.
proto/go/debug
proto/go/dgs
proto/go/dm
proto/go/field
proto/go/group
proto/go/groupsupport
proto/go/matching
proto/go/matchmaker
proto/go/p2p
proto/go/room
proto/go/session
room Package room ▷
roomsupport
server Package server ▷
session Package session ▷
smap Package smap ▷
td Package td ▷
test/tester Package tester ▷
user
util Package util ▷
uuid/v4