All notable changes to this project will be documented in this file.
This format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
v3.1.0 2025-09-04 [tag version v1.999.310]
New Features
- Cron Scheduler: New
gen.Croninterface enables scheduling tasks with cron expressions, supporting second-level precision for precise task execution. See https://docs.ergo.services/basics/cron - Port Meta Process: New
meta.Portallows spawning and managing external OS processes with bidirectional communication through stdin/stdout/stderr. See https://docs.ergo.services/meta-processes/port, example https://github.com/ergo-services/examples/port - Unit Testing Framework: Comprehensive testing library (
testing/unit) provides isolated actor testing with event capture and validation capabilities. See https://docs.ergo.services/testing/unit
Enhancements
- Enhanced Logging: Default logger now supports JSON output format with structured fields, improving observability and log processing
- Environment Management: Added
gen.Process.EnvDefault()andgen.Node.EnvDefault()methods - Logger Fields: Added
gen.Log.PushFields()andgen.Log.PopFields()for contextual logging - EDF Protocol: Added support for
encoding.BinaryMarshaler/BinaryUnmarshalerinterfaces - Performance: Multiple optimizations across message handling and network operations
Critical Bug Fixes
- Node Shutdown: Fixed race condition causing "close of closed channel" panic during graceful shutdown
- Supervisor Issues: Fixed OFO supervisor child termination (#213), restart intensity calculation with millisecond precision, and duplicate Terminate callbacks
- SIGTERM Handling: Improved graceful shutdown behavior and SOFO supervisor cleanup
- EDF Codec: Fixed nil slice/map decoding issues
- Local Registrar: Improved resolver detection for service discovery
Extra Library
- Module Independence: All extra library modules (Logger, Meta, Registrar, etc...) are now independent Go modules with dependency management
- Tools Domain: All tools moved to dedicated
ergo.toolsdomain for better organization and distribution - Proto:
erlang23(Erlang network stack implementation) changed from BSL 1.1 to MIT license for broader adoption and commercial use - Registrar: New etcd registrar implementation with distributed service discovery, hierarchical configuration, real-time cluster events. See https://docs.ergo.services/extra-library/registrars/etcd-client and example https://github.com/ergo-services/examples/docker
- Logger: Added LogField support in colored logger, banner functionality, and fixed options handling. See https://docs.ergo.services/extra-library/loggers
- Application: Observer application enhanced with new Applications page, Cron job details, and UI fixes. See https://docs.ergo.services/extra-library/applications/observer
- Benchmarks: New serialization benchmarks comparing EDF vs Gob vs Protobuf performance, expanded test suite coverage. See https://github.com/ergo-services/benchmarks
v3.0.0 2024-09-04 [tag version v1.999.300]
This version marks a significant milestone in the evolution of the Ergo Framework. The framework's design has been completely overhauled, and this version was built from the ground up. It includes:
- Significant API Improvements: The
gen.Process,gen.Node, andgen.Networkinterfaces have been enhanced with numerous convenient methods. - A New Network Stack: This version introduces a completely new network stack for improved performance and flexibility. See https://github.com/ergo-services/benchmarks for the details
Alongside the release of Ergo Framework 3.0.0, new tools and an additional components library are also introduced:
- Tools (observer, saturn) https://github.com/ergo-services/tools
- Loggers (rotate, colored) - https://github.com/ergo-services/logger
- Meta (websocket) - https://github.com/ergo-services/meta
- Application (observer) - https://github.com/ergo-services/application
- Registrar (client Saturn) - https://github.com/ergo-services/registrar
- Proto (erlang23) - https://github.com/ergo-services/proto
Finally, we've published comprehensive documentation for the framework, providing detailed guides to assist you in leveraging all the capabilities of Ergo Framework effectively. Its available at https://docs.ergo.services.
v2.2.4 2023-05-01 [tag version v1.999.224]
This release includes fixes:
- Fixed incorrect handling of
gen.SupervisorStrategyRestartTransientrestart strategy ingen.Supervisor - Fixed missing
ServerBehaviorin [gen.Pool,gen.Raft,gen.Saga,gen.Stage,gen.TCP,gen.UDP,gen.Web] behavior interfaces - Introduced the new tool for boilerplate code generation -
ergohttps://github.com/ergo-services/tools. You may read more information about this tool in our article with a great example https://blog.ergo.services/quick-start-1094d56d4e2
v2.2.3 2023-04-02 [tag version v1.999.223]
This release includes fixes:
- Improved
gen.TCP. Issue #152 - Fixed incorrect decoding registered map type using etf.RegisterType
- Fixed race condition on process termination. Issue #153
v2.2.2 2023-03-01 [tag version v1.999.222]
- Introduced
gen.Pool. This behavior implements a basic design pattern with a pool of workers. All messages/requests received by the pool process are forwarded to the workers using the "Round Robin" algorithm. The worker process is automatically restarting on termination. See example here examples/genpool - Removed Erlang RPC support. A while ago Erlang has changed the way of handling this kind of request making this feature more similar to the regular
gen.Server. So, there is no reason to keep supporting it. Use a regular way of messaging instead -gen.Server. - Fixed issue #130 (
StartTypeoption ingen.ApplicationSpecis ignored for the autostarting applications) - Fixed issue #143 (incorrect cleaning up the aliases belonging to the terminated process)
v2.2.1 2023-01-18 [tag version v1.999.221]
- Now you can join your services made with Ergo Framework into a single cluster with transparent networking using our Cloud Overlay Network where they can connect to each other smoothly, no matter where they run - AWS, Azure or GCP, or anywhere else. All these connections are secured with end-to-end encryption. Read more in this article https://https://medium.com/@ergo-services/cloud-overlay-network. Here is an example of this feature in action examples/cloud
examplesmoved to https://github.com/ergo-services/examples- Added support Erlang OTP/25
- Improved handling
nilvalues for the registered types usingetf.RegisterType(...) - Improved self-signed certificate generation
- Introduced
ergo.debugoption that enables extended debug information forlib.Log(...)/lib.Warning(...) - Fixed
gen.TCPandgen.UDP(missing callbacks) - Fixed ETF registering type with
etf.Pid,etf.Aliasoretf.Refvalue types - Fixed Cloud client
- Fixed #117 (incorrect hanshake process finalization)
- Fixed #139 (panic of the gen.Stage partition dispatcher)
v2.2.0 2022-10-18 [tag version v1.999.220]
- Introduced
gen.Webbehavior. It implements Web API Gateway pattern is also sometimes known as the "Backend For Frontend" (BFF). See example examples/genweb - Introduced
gen.TCPbehavior - socket acceptor pool for TCP protocols. It provides everything you need to accept TCP connections and process packets with a small code base and low latency. Here is simple example examples/gentcp - Introduced
gen.UDP- the same asgen.TCP, but for UDP protocols. Example is here examples/genudp - Introduced Events. This is a simple pub/sub feature within a node - any
gen.Processcan become a producer by registering a new eventgen.Eventusing methodgen.Process.RegisterEvent, while the others can subscribe to these events usinggen.Process.MonitorEvent. Subscriber process will also receivegen.MessageEventDownif a producer process went down (terminated). This feature behaves in a monitor manner but only works within a node. You may also want to subscribe to a system event -node.EventNetworkto receive event notification on connect/disconnect any peers. - Introduced Cloud Client - allows connecting to the cloud platform https://ergo.sevices. You may want to register your email there, and we will inform you about the platform launch day
- Introduced type registration for the ETF encoding/decoding. This feature allows you to get rid of manually decoding with
etf.TermIntoStructfor the receiving messages. Register your type usingetf.RegisterType(...), and you will be receiving messages in a native type - Predefined set of errors has moved to the
libpackage - Updated
gen.ServerBehavior.HandleDirectmethod (got extra argumentetf.Refto distinguish the requests). This change allows you to handle these requests asynchronously using methodgen.ServerProcess.Reply(...) - Updated
node.Options. Now it has fieldListeners(typenode.Listener). It allows you to start any number of listeners with custom options -Port,TLSsettings, or customHandshake/Protointerfaces - Fixed build on 32-bit arch
- Fixed freezing on ARM arch #102
- Fixed problem with encoding negative int8
- Fixed #103 (there was an issue on interop with Elixir's GenStage)
- Fixed node stuck on start if it uses the name which is already taken in EPMD
- Fixed incorrect
gen.ProcessOptions.Contexthandling
v2.1.0 2022-04-19 [tag version v1.999.210]
- Introduced compression feature support. Here are new methods and options to manage this feature:
gen.Process:SetCompression(enable bool),Compression() boolSetCompressionLevel(level int) bool,CompressionLevel() intSetCompressionThreshold(threshold int) bool,CompressionThreshold() intmessages smaller than the threshold will be sent with no compression. The default compression threshold is 1024 bytes.
node.Options:Compressionthese settings are used as defaults for the spawning processes
- this feature will be ignored if the receiver is running on either the Erlang or Elixir node
- Introduced proxy feature support with end-to-end encryption.
node.Nodenew methods:AddProxyRoute(...),RemoveProxyRoute(...)ProxyRoute(...),ProxyRoutes()NodesIndirect()returns list of connected nodes via proxy connection
node.Options:Proxyfor configuring proxy settings
- includes support (over the proxy connection): compression, fragmentation, link/monitor process, monitor node
- example examples/proxy.
- this feature is not available for the Erlang/Elixir nodes
- Introduced behavior
gen.Raft. It's improved implementation of Raft consensus algorithm. The key improvement is using quorum under the hood to manage the leader election process and make the Raft cluster more reliable. This implementation supports quorums of 3, 5, 7, 9, or 11 quorum members. Here is an example of this feature examples/genraft. - Introduced interfaces to customize network layer
Resolverto replace EPMD routines with your solution (e.g., ZooKeeper or any other service registrar)Handshakeallows customizing authorization/authentication processProtoprovides the way to implement proprietary protocols (e.g., IoT area)
- Other new features:
gen.Processnew methods:NodeUptime(),NodeName(),NodeStop()
gen.ServerProcessnew method:MessageCounter()shows how many messages have been handled by thegen.Servercallbacks
gen.ProcessOptionsnew option:ProcessFallbackallows forward messages to the fallback process if the process mailbox is full. Forwarded messages are wrapped intogen.MessageFallbackstruct. Related to issue #96.
gen.SupervisorChildSpecandgen.ApplicationChildSpecgot optiongen.ProcessOptionsto customize options for the spawning child processes.
- Improved sending messages by etf.Pid or etf.Alias: methods
gen.Process.Send,gen.ServerProcess.Cast,gen.ServerProcess.Callnow returnnode.ErrProcessIncarnationif a message is sending to the remote process of the previous incarnation (remote node has been restarted). Making monitor on a remote process of the previous incarnation triggers sendinggen.MessageDownwith reasonincarnation. - Introduced type
gen.EnvKeyfor the environment variables - All spawned processes now have the
node.EnvKeyNodevariable to get access to thenode.Nodevalue. - Improved performance of local messaging (up to 8 times for some cases)
- Important
node.Optionshas changed. Make sure to adjust your code. - Fixed issue #89 (incorrect handling of Call requests)
- Fixed issues #87, #88 and #93 (closing network socket)
- Fixed issue #96 (silently drops message if process mailbox is full)
- Updated minimal requirement of Golang version to 1.17 (go.mod)
- We still keep the rule Zero Dependencies
v2.0.0 2021-10-12 [tag version v1.999.200]
- Added support of Erlang/OTP 24 (including Alias feature and Remote Spawn introduced in Erlang/OTP 23)
- Important: This release includes refined API (without backward compatibility) for a more convenient way to create OTP-designed microservices. Make sure to update your code.
- Important: Project repository has been moved to https://github.com/ergo-services/ergo. It is still available on the old URL https://github.com/halturin/ergo and GitHub will redirect all requests to the new one (thanks to GitHub for this feature).
- Introduced new behavior
gen.Saga. It implements Saga design pattern - a sequence of transactions that updates each service state and publishes the result (or cancels the transaction or triggers the next transaction step).gen.Sagaalso provides a feature of interim results (can be used as transaction progress or as a part of pipeline processing), time deadline (to limit transaction lifespan), two-phase commit (to make distributed transaction atomic). Here is example examples/gensaga. - Introduced new methods
Process.DirectandProcess.DirectWithTimeoutto make direct request to the actor (gen.Serveror inherited object). If an actor has no implementation ofHandleDirectcallback it returnsErrUnsupportedRequestas a error. - Introduced new callback
HandleDirectin thegen.Serverinterface as a handler for requests made byProcess.DirectorProcess.DirectWithTimeout. It should be easy to interact with actors from outside. - Introduced new types intended to be used to interact with Erlang/Elixir
etf.ListImproperto support improper lists like[a|b](a cons cell).etf.String(an alias for the Golang string) encodes as a binary in order to support Elixir string type (which isbinary()type)etf.Charlist(an alias for the Golang string) encodes as a list of chars[]runein order to support Erlang string type (which ischarlist()type)
- Introduced new methods
Node.ProvideRemoteSpawn,Node.RevokeRemoteSpawn,Process.RemoteSpawn. - Introduced new interfaces
Marshaler(methodMarshalETF) andUnmarshaler(methodUnmarshalETF) for the custom encoding/decoding data. - Improved performance for the local messaging (up to 3 times for some cases)
- Added example examples/http to demonsrate how HTTP server can be integrated into the Ergo node.
- Added example examples/gendemo - how to create a custom behavior (design pattern) on top of the
gen.Server. Take inspiration from the gen/stage.go or gen/saga.go design patterns. - Added support FreeBSD, OpenBSD, NetBSD, DragonFly.
- Fixed RPC issue #45
- Fixed internal timer issue #48
- Fixed memory leaks #53
- Fixed double panic issue #52
- Fixed Atom Cache race conditioned issue #54
- Fixed ETF encoder issues #64 #66
v1.2.0 - 2021-04-07 [tag version v1.2.0]
- Added TLS support. Introduced new option
TLSmodeinergo.NodeOptionswith the following values:ergo.TLSmodeDisableddefault value. encryption is disabledergo.TLSmodeAutoenables encryption with autogenerated and self-signed certificateergo.TLSmodeStrictenables encryption with specified server/client certificates and keys there is example of usageexamples/nodetls/tlsGenServer.go
- Introduced GenStage behavior implementation (originated from Elixir world).
GenStageis an abstraction built on top ofGenServerto provide a simple way to create a distributed Producer/Consumer architecture, while automatically managing the concept of backpressure. This implementation is fully compatible with Elixir's GenStage. Example hereexamples/genstageor just run itgo run ./examples/genstageto see it in action - Introduced new methods
AddStaticRoute/RemoveStaticRouteforNode. This feature allows you to keep EPMD service behind a firewall. - Introduced
SetTrapExit/TrapExitmethods forProcessin order to control the trappinggen.MessageExitmessage (for the linked processes) - Introduced
TermMapIntoStructandTermProplistIntoStructfunctions. It should be easy now to transformetf.Mapor[]eft.ProplistElementinto the given struct. See documentation for the details. - Improved DIST implementation in order to support KeepAlive messages and get rid of platform-dependent
syscallusage - Fixed
TermIntoStructfunction. There was a problem withTuplevalue transforming into the given struct - Fixed incorrect decoding atoms
true,falseinto the booleans - Fixed race condition and freeze of connection serving in corner case #21
- Fixed problem with monitoring process by the registered name (local and remote)
- Fixed issue with termination linked processes
- Fixed platform-dependent issues. Now Ergo Framework has tested and confirmed support of Linux, MacOS, Windows.
v1.1.0 - 2020-04-23 [tag version v1.1.0]
- 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)
v1.0.0 - 2020-03-03 [tag version 1.0.0]
- We have changed the name - Ergo (or Ergo Framework). GitHub's repo has been
renamed as well. We also created cloned repo
ergonodeto support users of the old version of this project. So, its still available at https://github.com/halturin/ergonode. But it's strongly recommend to use the new one. - Completely reworked (almost from scratch) architecture whole project
- Implemented linking process feature (in order to support Application/Supervisor behaviors)
- Reworked Monitor-feature. Now it has full-featured support with remote process/nodes
- Added multinode support
- Added experimental observer support
- Fixed incorrect ETF string encoding
- Improved ETF TermIntoStruct decoder
- Improved code structure and readability
v0.2.0 - 2019-02-23 [tag version 0.2.0]
- Now we make versioning releases
- Improve node creation. Now you can specify the listening port range. See 'Usage' for details
- Add embedded EPMD. Trying to start internal epmd service on starting ergonode.