All Projects → halturin → Ergo

halturin / Ergo

Licence: mit
a Framework for creating mesh networks using technologies and design patterns of Erlang/OTP in Golang

Programming Languages

go
31211 projects - #10 most used programming language
golang
3204 projects
elixir
2628 projects
erlang
1774 projects

Projects that are alternatives of or similar to Ergo

Micro
Micro is a distributed cloud operating system
Stars: ✭ 10,778 (+2766.49%)
Mutual labels:  framework, distributed-systems
director
Director is a production-ready supervisor and manager for Erlang/Elixir processes that focuses on speed, performance and flexibility.
Stars: ✭ 62 (-83.51%)
Mutual labels:  otp, supervisor
Panic Server
Testing for collaborative apps and tools
Stars: ✭ 128 (-65.96%)
Mutual labels:  framework, distributed-systems
Netjsongraph.js
NetJSON NetworkGraph visualizer based on d3.js
Stars: ✭ 216 (-42.55%)
Mutual labels:  mesh, mesh-networks
supervisorring
otp/supervisor-like interface to supervise distributed processes
Stars: ✭ 15 (-96.01%)
Mutual labels:  otp, supervisor
Gotree
Gotree is a vertically distributed framework. Gotree's goal is to easily develop distributed services and liberate the mental burden of developers.
Stars: ✭ 91 (-75.8%)
Mutual labels:  framework, distributed-systems
MeshNetSimulator
A simulator for sketching mesh network routing strategies
Stars: ✭ 71 (-81.12%)
Mutual labels:  mesh-networks, mesh
Wireguard Private Networking
Build your own multi server private network using wireguard and ansible
Stars: ✭ 124 (-67.02%)
Mutual labels:  mesh, mesh-networks
vyatta-cjdns
A cjdns package for Ubiquiti EdgeOS and VyOS, allowing cjdns to be used on EdgeRouters
Stars: ✭ 39 (-89.63%)
Mutual labels:  mesh-networks, mesh
clojang
Clojure API for Erlang/OTP Communications (built on jiface)
Stars: ✭ 61 (-83.78%)
Mutual labels:  distributed-systems, otp
Prototype Cjdns Pi
Prototype system for mesh networks on single board computers
Stars: ✭ 205 (-45.48%)
Mutual labels:  mesh, mesh-networks
yggmail
End-to-end encrypted email for the mesh networking age
Stars: ✭ 72 (-80.85%)
Mutual labels:  mesh-networks, mesh
Lime Packages
OpenWrt packages composing LibreMesh meta-firmware for wireless mesh networking
Stars: ✭ 204 (-45.74%)
Mutual labels:  mesh, mesh-networks
Rails Disco
Distributed Rails with commands, events and projections.
Stars: ✭ 95 (-74.73%)
Mutual labels:  framework, distributed-systems
Django Netjsongraph
Network Topology Visualizer & Network Topology Collector
Stars: ✭ 131 (-65.16%)
Mutual labels:  mesh, mesh-networks
Go Chassis
a microservice framework for rapid development of micro services in Go with rich eco-system
Stars: ✭ 2,428 (+545.74%)
Mutual labels:  framework, distributed-systems
Spruce Network
Decentralized peer-to-peer mesh network.
Stars: ✭ 61 (-83.78%)
Mutual labels:  mesh, mesh-networks
Wifimeshraspberrypi
Workshop to create a sensor application over a WiFi Mesh network
Stars: ✭ 99 (-73.67%)
Mutual labels:  mesh, mesh-networks
edgevpn
⛵ The immutable, decentralized, statically built p2p VPN without any central server and automatic discovery! Create decentralized introspectable tunnels over p2p with shared tokens
Stars: ✭ 223 (-40.69%)
Mutual labels:  mesh-networks, mesh
netmaker
Netmaker makes networks with WireGuard. Netmaker automates fast, secure, and distributed virtual networks.
Stars: ✭ 4,147 (+1002.93%)
Mutual labels:  mesh-networks, mesh

Ergo Framework

GitHub release Go Report Card GoDoc MIT license codecov Build Status

Implementation of Erlang/OTP in Golang. Up to x5 times faster than original Erlang/OTP. The easiest drop-in replacement for your hot nodes in the cluster.

Purpose

The goal of this project is to leverage Erlang/OTP experience with Golang performance. Ergo Framework implements OTP design patterns such as GenServer/Supervisor/Application and makes you able to create high performance and reliable application having native integration with Erlang infrastructure

Features

  • Erlang node (run single/multinode)
  • embedded EPMD (in order to get rid of erlang' dependencies)
  • Spawn Erlang-like processes
  • Register/unregister processes with simple atom
  • GenServer behavior support (with atomic state)
  • Supervisor behavior support (with all known restart strategies support)
  • Application behavior support
  • Connect to (accept connection from) any Erlang node within a cluster (or clusters, if running as multinode)
  • Making sync/async request in fashion of gen_server:call or gen_server:cast
  • Monitor processes/nodes
    • local -> local
    • local -> remote
    • remote -> local
  • Link processes
    • local <-> local
    • local <-> remote
    • remote <-> local
  • RPC callbacks support
  • Experimental observer support
  • Unmarshalling terms into the struct using etf.TermIntoStruct
  • Support Erlang 22. (with fragmentation)
  • Encryption (TLS 1.3) support
  • Tested and confirmed support Windows, Darwin (MacOS), Linux

Requirements

  • Go 1.15.x and above

Benchmarks

Here is simple EndToEnd test demonstrates performance of messaging subsystem

Hardware: laptop with Intel(R) Core(TM) i5-8265U (4 cores. 8 with HT)

Sequential GenServer.Call using two processes running on single and two nodes

❯❯❯❯ go test -bench=NodeSequential -run=XXX -benchtime=10s
goos: linux
goarch: amd64
pkg: github.com/halturin/ergo
BenchmarkNodeSequential/number-8 	  256108	     48578 ns/op
BenchmarkNodeSequential/string-8 	  266906	     51531 ns/op
BenchmarkNodeSequential/tuple_(PID)-8         	  233700	     58192 ns/op
BenchmarkNodeSequential/binary_1MB-8          	    5617	   2092495 ns/op
BenchmarkNodeSequentialSingleNode/number-8         	 2527580	      4857 ns/op
BenchmarkNodeSequentialSingleNode/string-8         	 2519410	      4760 ns/op
BenchmarkNodeSequentialSingleNode/tuple_(PID)-8    	 2524701	      4757 ns/op
BenchmarkNodeSequentialSingleNode/binary_1MB-8     	 2521370	      4758 ns/op
PASS
ok  	github.com/halturin/ergo	120.720s

it means Ergo Framework provides around 25000 sync rps via localhost for simple data and around 4Gbit/sec for 1MB messages

Parallel GenServer.Call using 120 pairs of processes running on a single and two nodes

❯❯❯❯ go test -bench=NodeParallel -run=XXX -benchtime=10s
goos: linux
goarch: amd64
pkg: github.com/halturin/ergo
BenchmarkNodeParallel-8        	         2652494	      5246 ns/op
BenchmarkNodeParallelSingleNode-8   	 6100352	      2226 ns/op
PASS
ok  	github.com/halturin/ergo	34.145s

these numbers shows around 260000 sync rps via localhost using simple data for messaging

vs original Erlang/OTP

benchmarks

sources of these benchmarks are here

EPMD

Ergo Framework has embedded EPMD implementation in order to run your node without external epmd process needs. By default it works as a client with erlang' epmd daemon or others ergo's nodes either.

The one thing that makes embedded EPMD different is the behavior of handling connection hangs - if ergo' node is running as an EPMD client and lost connection it tries either to run its own embedded EPMD service or to restore the lost connection.

As an extra option, we provide EPMD service as a standalone application. There is a simple drop-in replacement of the original Erlang' epmd daemon.

go get -u github.com/halturin/ergo/cmd/epmd

Multinode

This feature allows create two or more nodes within a single running instance. The only needs is specify the different set of options for creating nodes (such as: node name, empd port number, secret cookie). You may also want to use this feature to create 'proxy'-node between some clusters. See Examples for more details

Observer

It allows you to see the most metrics/information using standard tool of Erlang distribution. The example below shows this feature in action using one of the examples:

observer demo

Changelog

Here are the changes of latest release. For more details see the ChangeLog

1.1.0 - 2020-04-23

  • Fragmentation support (which was introduced in Erlang/OTP 22)
  • Completely rewritten network subsystem (DIST/ETF).
  • Improved performance in terms of network messaging (outperforms original Erlang/OTP up to x5 times. See Benchmarks)

Examples

Code below is a simple implementation of GenServer pattern examples/simple/GenServer.go

package main

import (
    "fmt"
    "time"

    "github.com/halturin/ergo"
    "github.com/halturin/ergo/etf"
)

type ExampleGenServer struct {
    ergo.GenServer
    process ergo.Process
}

type State struct {
    value int
}

func (egs *ExampleGenServer) Init(p ergo.Process, args ...interface{}) (state interface{}) {
    fmt.Printf("Init: args %v \n", args)
    egs.process = p
    InitialState := &State{
        value: args[0].(int), // 100
    }
    return InitialState
}

func (egs *ExampleGenServer) HandleCast(message etf.Term, state interface{}) (string, interface{}) {
    fmt.Printf("HandleCast: %#v (state value %d) \n", message, state.(*State).value)
    time.Sleep(1 * time.Second)
    state.(*State).value++

    if state.(*State).value > 103 {
        egs.process.Send(egs.process.Self(), "hello")
    } else {
        egs.process.Cast(egs.process.Self(), "hi")
    }

    return "noreply", state
}

func (egs *ExampleGenServer) HandleCall(from etf.Tuple, message etf.Term, state interface{}) (string, etf.Term, interface{}) {
    fmt.Printf("HandleCall: %#v, From: %#v\n", message, from)
    return "reply", message, state
}

func (egs *ExampleGenServer) HandleInfo(message etf.Term, state interface{}) (string, interface{}) {
    fmt.Printf("HandleInfo: %#v (state value %d) \n", message, state.(*State).value)
    time.Sleep(1 * time.Second)
    state.(*State).value++
    if state.(*State).value > 106 {
        return "stop", "normal"
    } else {
        egs.process.Send(egs.process.Self(), "hello")
    }
    return "noreply", state
}
func (egs *ExampleGenServer) Terminate(reason string, state interface{}) {
    fmt.Printf("Terminate: %#v \n", reason)
}

func main() {
    node := ergo.CreateNode("[email protected]", "cookies", ergo.NodeOptions{})
    gs1 := &ExampleGenServer{}
    process, _ := node.Spawn("gs1", ergo.ProcessOptions{}, gs1, 100)

    process.Cast(process.Self(), "hey")

    select {
    case <-process.Context.Done():
        fmt.Println("exited")
    }
}

here is output of this code

$ go run ./examples/simple/GenServer.go
Init: args [100]
HandleCast: "hey" (state value 100)
HandleCast: "hi" (state value 101)
HandleCast: "hi" (state value 102)
HandleCast: "hi" (state value 103)
HandleInfo: "hello" (state value 104)
HandleInfo: "hello" (state value 105)
HandleInfo: "hello" (state value 106)
Terminate: "normal"
exited

See examples/ for more details

Elixir Phoenix Users

Users of the Elixir Phoenix framework might encounter timeouts when trying to connect a Phoenix node to an ergo node. The reason is that, in addition to global_name_server and net_kernel, Phoenix attempts to broadcast messages to the pg2 PubSub handler

To work with Phoenix nodes, you must create and register a dedicated pg2 GenServer, and spawn it inside your node. Take inspiration from the global_name_server.go for the rest of the GenServer methods, but the Spawn must have "pg2" as a process name:

type Pg2GenServer struct {
    ergo.GenServer
}

func main() {
    // ...
    pg2 := &Pg2GenServer{}
    node1 := ergo.CreateNode("[email protected]", "cookies", ergo.NodeOptions{})
    process, _ := node1.Spawn("pg2", ergo.ProcessOptions{}, pg2, nil)
    // ...
}

Development and debugging

There is a couple of options are already defined that you might want to use

  • -trace.node
  • -trace.dist

To enable Golang profiler just add --tags debug in your go run or go build like this:

go run --tags debug ./examples/genserver/demoGenServer.go

Now golang' profiler is available at http://localhost:9009/debug/pprof

Companies are using Ergo Framework

Kaspersky RingCentral LilithGames

is your company using Ergo? add your company logo/name here

Commercial support

if you are looking for commercial support feel free to contact me via email (halturin at gmail dot com)

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].