From dc805726d7a780fe33278f604c47a5f05f4ee471 Mon Sep 17 00:00:00 2001 From: Taras Halturin Date: Mon, 2 Sep 2024 08:34:59 +0200 Subject: [PATCH] Initial commit --- LICENSE | 21 +++++++++++ README.md | 28 ++++++++++++++ memusage/go.mod | 16 ++++++++ memusage/go.sum | 18 +++++++++ memusage/mem.go | 78 ++++++++++++++++++++++++++++++++++++++ ping/go.mod | 16 ++++++++ ping/go.sum | 18 +++++++++ ping/ping_local.go | 53 ++++++++++++++++++++++++++ ping/ping_network.go | 59 +++++++++++++++++++++++++++++ ping/pingpong.go | 58 ++++++++++++++++++++++++++++ ping/pong.go | 19 ++++++++++ ping/test_local_11.go | 65 ++++++++++++++++++++++++++++++++ ping/test_local_NN.go | 69 ++++++++++++++++++++++++++++++++++ ping/test_network_11.go | 75 +++++++++++++++++++++++++++++++++++++ ping/test_network_NN.go | 83 +++++++++++++++++++++++++++++++++++++++++ 15 files changed, 676 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 memusage/go.mod create mode 100644 memusage/go.sum create mode 100644 memusage/mem.go create mode 100644 ping/go.mod create mode 100644 ping/go.sum create mode 100644 ping/ping_local.go create mode 100644 ping/ping_network.go create mode 100644 ping/pingpong.go create mode 100644 ping/pong.go create mode 100644 ping/test_local_11.go create mode 100644 ping/test_local_NN.go create mode 100644 ping/test_network_11.go create mode 100644 ping/test_network_NN.go diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..66bd8bb --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 ergo.services + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..07a58cd --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +[![Gitbook Documentation](https://img.shields.io/badge/GitBook-Documentation-f37f40?style=plastic&logo=gitbook&logoColor=white&style=flat)](https://docs.ergo.services) +[![MIT license](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT) +[![Telegram Community](https://img.shields.io/badge/Telegram-ergo__services-229ed9?style=flat&logo=telegram&logoColor=white)](https://t.me/ergo_services) +[![Twitter](https://img.shields.io/badge/Twitter-ergo__services-00acee?style=flat&logo=twitter&logoColor=white)](https://twitter.com/ergo_services) +[![Reddit](https://img.shields.io/badge/Reddit-r/ergo__services-ff4500?style=plastic&logo=reddit&logoColor=white&style=flat)](https://reddit.com/r/ergo_services) + +# Benchmarks of the Ergo Framework 3.0 (and above) + +The tests below are performed on the laptop Macbook Air M3 (2024) + +## Ping + +Performs 4 scenarios: + - 1 process spawns 'pong'-process locally and sends 3M messages + - N processes spawn 'pong'-process locally and send 1M messages (N = number of CPU) + - 1 process spawns 'pong'-process on a remote node and sends 3M messages + - N processes spawn 'pong'-process on a remote node and send 1M messages (N = number of CPU) + +![image](https://github.com/ergo-services/benchmarks/assets/118860/31e17b33-ce92-4ef1-8dec-d6bcac0ab66f) + +## Memory usage (per process) + +Performs the following scenario: + - Takes node information that includes memory usage value. + - Starts 1M processes + - Takes node information 3 times with 1s intervals to make sure the GC has freed unused memory + +![image](https://github.com/ergo-services/benchmarks/assets/118860/ead567bb-beae-40bf-b881-519e89ce1190) diff --git a/memusage/go.mod b/memusage/go.mod new file mode 100644 index 0000000..92565b1 --- /dev/null +++ b/memusage/go.mod @@ -0,0 +1,16 @@ +module memusage + +go 1.20 + +require ( + ergo.services/ergo v1.999.225-0.20240813065603-2996d01df4fd + ergo.services/logger v0.0.0-20240902062636-f20f7612a328 + github.com/klauspost/cpuid/v2 v2.2.6 +) + +require ( + github.com/fatih/color v1.16.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + golang.org/x/sys v0.14.0 // indirect +) diff --git a/memusage/go.sum b/memusage/go.sum new file mode 100644 index 0000000..ccdd5b4 --- /dev/null +++ b/memusage/go.sum @@ -0,0 +1,18 @@ +ergo.services/ergo v1.999.225-0.20240813065603-2996d01df4fd h1:s0PyAIT+OAtm8casX1kMZFwBzDd2vZV+6dOE2qjpM0Q= +ergo.services/ergo v1.999.225-0.20240813065603-2996d01df4fd/go.mod h1:bLQ6PoO6Mz/8gVuzvPv3xfMfo1P9w6rZV1WnMXMeMdg= +ergo.services/logger v0.0.0-20240902062636-f20f7612a328 h1:WeDBT4Yifph2PU3Bj/EwYHuM034ztZeACPzokkMsfVg= +ergo.services/logger v0.0.0-20240902062636-f20f7612a328/go.mod h1:gpDWjfQm5gwvV2uIPZpOkMUJ9CHyzbX9ohXs5xj9ddg= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/memusage/mem.go b/memusage/mem.go new file mode 100644 index 0000000..3b6d0dd --- /dev/null +++ b/memusage/mem.go @@ -0,0 +1,78 @@ +package main + +import ( + "runtime" + "time" + + "ergo.services/ergo" + "ergo.services/ergo/act" + "ergo.services/ergo/gen" + "ergo.services/logger/colored" + . "github.com/klauspost/cpuid/v2" +) + +var ( + NCPU int = runtime.NumCPU() +) + +func factory_simple() gen.ProcessBehavior { + return &simple{} +} + +type simple struct { + act.Actor +} + +func main() { + var options gen.NodeOptions + + options.Network.Cookie = "123" + loggercolored, err := colored.CreateLogger(colored.Options{ + TimeFormat: time.DateTime, + }) + if err != nil { + panic(err) + } + options.Log.DefaultLogger.Disable = true + options.Log.Loggers = append( + options.Log.Loggers, + gen.Logger{Name: "colored", Logger: loggercolored}, + ) + node, err := ergo.StartNode("mem@localhost", options) + if err != nil { + panic(err) + } + + mem := func(proc bool) { + info, _ := node.Info() + node.Log().Info("Memory allocated (runtime): %.2f Kb", float64(info.MemoryAlloc)/1024.0) + node.Log().Info("Memory used (OS): %.2f Kb", float64(info.MemoryUsed)/1024.0) + if proc { + node.Log().Info("Total processes: %d (memory per process ~%.2f Kb)", + info.ProcessesTotal, + (float64(info.MemoryAlloc)/float64(info.ProcessesTotal))/1024.0) + } + runtime.GC() + } + node.Log().Info("-------------------------- Memory usage (start) ----------------------------------") + node.Log().Info("Go Version : %s", runtime.Version()) + node.Log().Info("CPU: %s (Physical Cores: %d)", CPU.BrandName, CPU.PhysicalCores) + node.Log().Info("Runtime CPUs: %d", NCPU) + + mem(false) + node.Log().Info("Starting 1M processes...") + start := time.Now() + for i := 0; i < 1000000; i++ { + if _, err := node.Spawn(factory_simple, gen.ProcessOptions{}); err != nil { + panic(err) + } + } + node.Log().Info("1M processes is started. Elapsed: %s", time.Since(start)) + + for i := 0; i < 3; i++ { + mem(true) + time.Sleep(time.Second) + } + node.Log().Info("-------------------------- Memory usage (end) ----------------------------------") + +} diff --git a/ping/go.mod b/ping/go.mod new file mode 100644 index 0000000..dbd6b17 --- /dev/null +++ b/ping/go.mod @@ -0,0 +1,16 @@ +module ping + +go 1.21.6 + +require ( + ergo.services/ergo v1.999.225-0.20240813065603-2996d01df4fd + ergo.services/logger v0.0.0-20240902062636-f20f7612a328 + github.com/klauspost/cpuid/v2 v2.2.6 +) + +require ( + github.com/fatih/color v1.16.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + golang.org/x/sys v0.14.0 // indirect +) diff --git a/ping/go.sum b/ping/go.sum new file mode 100644 index 0000000..ccdd5b4 --- /dev/null +++ b/ping/go.sum @@ -0,0 +1,18 @@ +ergo.services/ergo v1.999.225-0.20240813065603-2996d01df4fd h1:s0PyAIT+OAtm8casX1kMZFwBzDd2vZV+6dOE2qjpM0Q= +ergo.services/ergo v1.999.225-0.20240813065603-2996d01df4fd/go.mod h1:bLQ6PoO6Mz/8gVuzvPv3xfMfo1P9w6rZV1WnMXMeMdg= +ergo.services/logger v0.0.0-20240902062636-f20f7612a328 h1:WeDBT4Yifph2PU3Bj/EwYHuM034ztZeACPzokkMsfVg= +ergo.services/logger v0.0.0-20240902062636-f20f7612a328/go.mod h1:gpDWjfQm5gwvV2uIPZpOkMUJ9CHyzbX9ohXs5xj9ddg= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/ping/ping_local.go b/ping/ping_local.go new file mode 100644 index 0000000..44a34d5 --- /dev/null +++ b/ping/ping_local.go @@ -0,0 +1,53 @@ +package main + +import ( + "ergo.services/ergo/act" + "ergo.services/ergo/gen" +) + +func factory_ping_local() gen.ProcessBehavior { + return &ping_local{} +} + +type ping_local struct { + act.Actor + + pair gen.PID +} + +func (p *ping_local) Init(args ...any) error { + p.Send(p.PID(), "") + return nil +} + +func (p *ping_local) HandleMessage(from gen.PID, message any) error { + if _, err := p.MonitorEvent(EVENT); err != nil { + return err + } + + pid, err := p.Spawn(factory_pong, gen.ProcessOptions{}) + if err != nil { + return err + } + p.pair = pid + + WGready.Done() + return nil +} + +func (p *ping_local) HandleEvent(message gen.MessageEvent) error { + switch m := message.Message.(type) { + case startSend: + WG.Add(1 + m.n) + WGready.Done() + for i := 0; i < m.n; i++ { + p.SendPID(p.pair, 1) + } + WG.Done() + + default: + p.Log().Warning("unknown event: %#v", message) + } + + return nil +} diff --git a/ping/ping_network.go b/ping/ping_network.go new file mode 100644 index 0000000..d2dbdd7 --- /dev/null +++ b/ping/ping_network.go @@ -0,0 +1,59 @@ +package main + +import ( + "ergo.services/ergo/act" + "ergo.services/ergo/gen" +) + +func factory_ping_network() gen.ProcessBehavior { + return &ping_network{} +} + +type ping_network struct { + act.Actor + + remote gen.Atom + remote_pong gen.Atom + pair gen.PID +} + +func (p *ping_network) Init(args ...any) error { + p.remote = args[0].(gen.Atom) + p.remote_pong = args[1].(gen.Atom) + p.Send(p.PID(), "") + return nil +} + +func (p *ping_network) HandleMessage(from gen.PID, message any) error { + if _, err := p.MonitorEvent(EVENT); err != nil { + return err + } + remote, err := p.Node().Network().Node(p.remote) + if err != nil { + return err + } + pid, err := remote.Spawn(p.remote_pong, gen.ProcessOptions{}) + if err != nil { + return err + } + p.pair = pid + WGready.Done() + return nil +} + +func (p *ping_network) HandleEvent(message gen.MessageEvent) error { + switch m := message.Message.(type) { + case startSend: + WG.Add(1 + m.n) + WGready.Done() + for i := 0; i < m.n; i++ { + p.SendPID(p.pair, 1) + } + WG.Done() + + default: + p.Log().Warning("unknown event: %#v", message) + } + + return nil +} diff --git a/ping/pingpong.go b/ping/pingpong.go new file mode 100644 index 0000000..f439418 --- /dev/null +++ b/ping/pingpong.go @@ -0,0 +1,58 @@ +package main + +import ( + "fmt" + "runtime" + "sync" + "time" + + "ergo.services/ergo/gen" +) + +type startSend struct { + n int +} + +var ( + WGready sync.WaitGroup + WG sync.WaitGroup + EVENT gen.Event = gen.Event{Name: "send"} + NCPU int = runtime.NumCPU() +) + +func main() { + // f, err := os.Create("profile.prof") + // if err != nil { + // panic(err) + // } + // defer f.Close() + // + // // Start CPU profiling + // if err := pprof.StartCPUProfile(f); err != nil { + // panic(err) + // } + // defer pprof.StopCPUProfile() + // + // // Start tracing + // traceFile, err := os.Create("trace.out") + // if err != nil { + // panic(err) + // } + // defer traceFile.Close() + // + // if err := trace.Start(traceFile); err != nil { + // panic(err) + // } + // defer trace.Stop() + + runTestLocal11() + fmt.Println("") + time.Sleep(time.Second * 10) + runTestLocalNN() + fmt.Println("") + time.Sleep(time.Second * 10) + runTestNetwork11() + fmt.Println("") + time.Sleep(time.Second * 10) + runTestNetworkNN() +} diff --git a/ping/pong.go b/ping/pong.go new file mode 100644 index 0000000..74237a4 --- /dev/null +++ b/ping/pong.go @@ -0,0 +1,19 @@ +package main + +import ( + "ergo.services/ergo/act" + "ergo.services/ergo/gen" +) + +func factory_pong() gen.ProcessBehavior { + return &pong{} +} + +type pong struct { + act.Actor +} + +func (p *pong) HandleMessage(from gen.PID, message any) error { + WG.Done() + return nil +} diff --git a/ping/test_local_11.go b/ping/test_local_11.go new file mode 100644 index 0000000..d495c19 --- /dev/null +++ b/ping/test_local_11.go @@ -0,0 +1,65 @@ +package main + +import ( + "runtime" + "time" + + "ergo.services/ergo" + "ergo.services/ergo/gen" + "ergo.services/logger/colored" + . "github.com/klauspost/cpuid/v2" +) + +func runTestLocal11() { + N := 3_000_000 + // prepare node + options := gen.NodeOptions{} + options.Network.Cookie = "cookie" + loggercolored, err := colored.CreateLogger(colored.Options{ + TimeFormat: time.DateTime, + }) + if err != nil { + panic(err) + } + options.Log.DefaultLogger.Disable = true + options.Log.Loggers = append( + options.Log.Loggers, + gen.Logger{Name: "colored", Logger: loggercolored}, + ) + + nodeping, err := ergo.StartNode("node_local_11@localhost", options) + if err != nil { + panic(err) + } + + token, err := nodeping.RegisterEvent(EVENT.Name, gen.EventOptions{}) + if err != nil { + panic(err) + } + nodeping.Log().Info("-------------------------- LOCAL 1-1 (start) ----------------------------------") + nodeping.Log().Info("Go Version : %s", runtime.Version()) + nodeping.Log().Info("CPU: %s (Physical Cores: %d)", CPU.BrandName, CPU.PhysicalCores) + nodeping.Log().Info("Runtime CPUs: %d", NCPU) + + // starting 1 ping process + WGready.Add(1) + if _, err := nodeping.Spawn(factory_ping_local, gen.ProcessOptions{}); err != nil { + panic(err) + } + nodeping.Log().Info("BENCHMARK: 1 process sends %d messages to 1 process", N) + WGready.Wait() // created monitor on the event and spawned a pong process + + WGready.Add(1) + if err := nodeping.SendEvent(EVENT.Name, token, gen.MessageOptions{}, startSend{n: N}); err != nil { + panic(err) + } + WGready.Wait() // received event and started sending + + start := time.Now() + WG.Wait() + elapsed := time.Since(start) + + nodeping.Log().Info("received %d messages. %f msg/sec", N, float64(N)/elapsed.Seconds()) + + nodeping.Log().Info("-------------------------- LOCAL 1-1 (end) ----------------------------------") +} diff --git a/ping/test_local_NN.go b/ping/test_local_NN.go new file mode 100644 index 0000000..83bd59d --- /dev/null +++ b/ping/test_local_NN.go @@ -0,0 +1,69 @@ +package main + +import ( + "runtime" + "time" + + "ergo.services/ergo" + "ergo.services/ergo/gen" + "ergo.services/logger/colored" + . "github.com/klauspost/cpuid/v2" +) + +func runTestLocalNN() { + N := 1000_000 + // prepare node + options := gen.NodeOptions{} + options.Network.Cookie = "cookie" + loggercolored, err := colored.CreateLogger(colored.Options{ + TimeFormat: time.DateTime, + }) + if err != nil { + panic(err) + } + options.Log.DefaultLogger.Disable = true + // options.Log.Level = gen.LogLevelTrace + options.Log.Loggers = append( + options.Log.Loggers, + gen.Logger{Name: "colored", Logger: loggercolored}, + ) + + nodeping, err := ergo.StartNode("node_local_NN@localhost", options) + if err != nil { + panic(err) + } + + token, err := nodeping.RegisterEvent(EVENT.Name, gen.EventOptions{}) + if err != nil { + panic(err) + } + nodeping.Log().Info("-------------------------- LOCAL N-N (start) ----------------------------------") + nodeping.Log().Info("Go Version : %s", runtime.Version()) + nodeping.Log().Info("CPU: %s (Physical Cores: %d)", CPU.BrandName, CPU.PhysicalCores) + nodeping.Log().Info("Runtime CPUs: %d", NCPU) + // starting N ping processes + np := NCPU + WGready.Add(np) + for i := 0; i < np; i++ { + if _, err := nodeping.Spawn(factory_ping_local, gen.ProcessOptions{}); err != nil { + panic(err) + } + } + nodeping.Log().Info("BENCHMARK: %d processes send %d messages to %d process", np, np*N, np) + WGready.Wait() // created monitor on the event and spawned a pong process + + WGready.Add(np) + if err := nodeping.SendEvent(EVENT.Name, token, gen.MessageOptions{}, startSend{n: N}); err != nil { + panic(err) + } + WGready.Wait() // received event and started sending + + start := time.Now() + WG.Wait() + elapsed := time.Since(start) + + nodeping.Log().Info("received %d messages. %f msg/sec", N*np, float64(N*np)/elapsed.Seconds()) + + nodeping.Log().Info("-------------------------- LOCAL N-N (end) ----------------------------------") + +} diff --git a/ping/test_network_11.go b/ping/test_network_11.go new file mode 100644 index 0000000..b6d17ae --- /dev/null +++ b/ping/test_network_11.go @@ -0,0 +1,75 @@ +package main + +import ( + "runtime" + "time" + + "ergo.services/ergo" + "ergo.services/ergo/gen" + "ergo.services/logger/colored" + . "github.com/klauspost/cpuid/v2" +) + +func runTestNetwork11() { + N := 3_000_000 + // prepare nodes + options := gen.NodeOptions{} + options.Network.Cookie = "cookie" + loggercolored, err := colored.CreateLogger(colored.Options{ + TimeFormat: time.DateTime, + }) + if err != nil { + panic(err) + } + options.Log.DefaultLogger.Disable = true + options.Log.Loggers = append( + options.Log.Loggers, + gen.Logger{Name: "colored", Logger: loggercolored}, + ) + + nodeping, err := ergo.StartNode("node_network_11_n1@localhost", options) + if err != nil { + panic(err) + } + nodepong, err := ergo.StartNode("node_network_11_n2@localhost", options) + if err != nil { + panic(err) + } + + if _, err := nodeping.Network().GetNode(nodepong.Name()); err != nil { + panic(err) + } + + pong := gen.Atom("pong") + nodepong.Network().EnableSpawn(pong, factory_pong) + + token, err := nodeping.RegisterEvent(EVENT.Name, gen.EventOptions{}) + if err != nil { + panic(err) + } + nodeping.Log().Info("-------------------------- NETWORK 1-1 (start) ----------------------------------") + nodeping.Log().Info("Go Version : %s", runtime.Version()) + nodeping.Log().Info("CPU: %s (Physical Cores: %d)", CPU.BrandName, CPU.PhysicalCores) + nodeping.Log().Info("Runtime CPUs: %d", NCPU) + // starting 1 ping process + WGready.Add(1) + if _, err := nodeping.Spawn(factory_ping_network, gen.ProcessOptions{}, nodepong.Name(), pong); err != nil { + panic(err) + } + nodeping.Log().Info("BENCHMARK: 1 process sends %d messages to 1 process", N) + WGready.Wait() // created monitor on the event and spawned a pong process + + WGready.Add(1) + if err := nodeping.SendEvent(EVENT.Name, token, gen.MessageOptions{}, startSend{n: N}); err != nil { + panic(err) + } + WGready.Wait() // received event and started sending + + start := time.Now() + WG.Wait() + elapsed := time.Since(start) + + nodeping.Log().Info("received %d messages. %f msg/sec", N, float64(N)/elapsed.Seconds()) + + nodeping.Log().Info("-------------------------- NETWORK 1-1 (end) ----------------------------------") +} diff --git a/ping/test_network_NN.go b/ping/test_network_NN.go new file mode 100644 index 0000000..358acf1 --- /dev/null +++ b/ping/test_network_NN.go @@ -0,0 +1,83 @@ +package main + +import ( + "runtime" + "time" + + "ergo.services/ergo" + "ergo.services/ergo/gen" + "ergo.services/ergo/net/handshake" + "ergo.services/logger/colored" + . "github.com/klauspost/cpuid/v2" +) + +func runTestNetworkNN() { + N := 1_000_000 + // prepare nodes + options := gen.NodeOptions{} + options.Network.Cookie = "cookie" + a := gen.AcceptorOptions{ + Handshake: handshake.Create(handshake.Options{PoolSize: NCPU / 2}), + } + options.Network.Acceptors = append(options.Network.Acceptors, a) + loggercolored, err := colored.CreateLogger(colored.Options{ + TimeFormat: time.DateTime, + }) + if err != nil { + panic(err) + } + options.Log.DefaultLogger.Disable = true + options.Log.Loggers = append( + options.Log.Loggers, + gen.Logger{Name: "colored", Logger: loggercolored}, + ) + + nodeping, err := ergo.StartNode("node_network_NN_n1@localhost", options) + if err != nil { + panic(err) + } + nodepong, err := ergo.StartNode("node_network_NN_n2@localhost", options) + if err != nil { + panic(err) + } + + if _, err := nodeping.Network().GetNode(nodepong.Name()); err != nil { + panic(err) + } + + pong := gen.Atom("pong") + nodepong.Network().EnableSpawn(pong, factory_pong) + + token, err := nodeping.RegisterEvent(EVENT.Name, gen.EventOptions{}) + if err != nil { + panic(err) + } + nodeping.Log().Info("-------------------------- NETWORK N-N (start) ----------------------------------") + nodeping.Log().Info("Go Version : %s", runtime.Version()) + nodeping.Log().Info("CPU: %s (Physical Cores: %d)", CPU.BrandName, CPU.PhysicalCores) + nodeping.Log().Info("Runtime CPUs: %d", NCPU) + // starting N ping processes + np := NCPU + WGready.Add(np) + for i := 0; i < np; i++ { + if _, err := nodeping.Spawn(factory_ping_network, gen.ProcessOptions{}, nodepong.Name(), pong); err != nil { + panic(err) + } + } + nodeping.Log().Info("BENCHMARK: %d processes send %d messages to %d processes", np, np*N, np) + WGready.Wait() // created monitor on the event and spawned a pong process + + WGready.Add(np) + if err := nodeping.SendEvent(EVENT.Name, token, gen.MessageOptions{}, startSend{n: N}); err != nil { + panic(err) + } + WGready.Wait() // received event and started sending + + start := time.Now() + WG.Wait() + elapsed := time.Since(start) + + nodeping.Log().Info("received %d messages. %f msg/sec", N*np, float64(N*np)/elapsed.Seconds()) + + nodeping.Log().Info("-------------------------- NETWORK N-N (end) ----------------------------------") +}