{"id":17335360,"url":"https://github.com/shaovie/goev","last_synced_at":"2025-05-08T21:22:18.386Z","repository":{"id":176947267,"uuid":"659774535","full_name":"shaovie/goev","owner":"shaovie","description":"goev is a lightweight, concise i/o event demultiplexer implementation in Go","archived":false,"fork":false,"pushed_at":"2023-09-22T06:51:53.000Z","size":640,"stargazers_count":146,"open_issues_count":0,"forks_count":16,"subscribers_count":4,"default_branch":"main","last_synced_at":"2023-12-19T17:12:43.132Z","etag":null,"topics":["epoll","event-driven","go","high-performance","network","reactor"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shaovie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-06-28T14:28:50.000Z","updated_at":"2023-12-14T01:52:16.000Z","dependencies_parsed_at":"2023-10-11T17:51:22.727Z","dependency_job_id":null,"html_url":"https://github.com/shaovie/goev","commit_stats":{"total_commits":260,"total_committers":4,"mean_commits":65.0,"dds":"0.20769230769230773","last_synced_commit":"a4060b705fc2fbf8fbb31d3dad7e066be92cd08f"},"previous_names":["shaovie/goev"],"tags_count":2,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaovie%2Fgoev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaovie%2Fgoev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaovie%2Fgoev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shaovie%2Fgoev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shaovie","download_url":"https://codeload.github.com/shaovie/goev/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238044093,"owners_count":19407128,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["epoll","event-driven","go","high-performance","network","reactor"],"created_at":"2024-10-15T15:09:29.562Z","updated_at":"2025-02-10T02:08:46.880Z","avatar_url":"https://github.com/shaovie.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Event-driven network framework in Go\n[中文文档](https://zhuanlan.zhihu.com/p/648641683)\n\n[C++ Implementation Version](https://github.com/shaovie/reactor)\n\nGoev provides a high-performance, lightweight, non-blocking, I/O event-driven networking framework for the Go language. It draws inspiration from the design patterns of [ACE](http://www.dre.vanderbilt.edu/~schmidt/ACE-overview.html) and provides an elegant and concise solution for TCP network programming projects. With goev, you can seamlessly integrate your projects without worrying about the coroutine pressure introduced by the standard library (go net). \n\nGoev can achieve at least a 20% performance improvement in synchronous I/O compared to the go net library. Additionally, combined with lock-free processing within the framework, it provides better optimization opportunities, resulting in even higher overall performance gains.\n\n![](images/goev.png)\n## Features\n\n* I/O event-driven architecture\n* Lightweight and minimalist implementation of the Reactor pattern, allowing flexible combinations of multiple reactors\n* Object-oriented implementation for easier encapsulation of business logic.\n* Supporting asynchronous sending allows higher-level applications to perform synchronous I/O operations while asynchronously handling business processing\n* Lock-free operations in a polling stack, enabling zero-copy data transfer for synchronous I/O.\n* Perfect support for REUSEPORT multi-poller mode\n* Built-in four-heap timer implementation, enabling lock-free/synchronous handling of I/O and timer events.\n* Fully native implementation of acceptor/connector, providing maximum customizability.\n* Controllable number of underlying threads. The per-connection per-goroutine approach usually leads to a surge in the number of threads, but using pollers helps maintain a consistent thread count, keeping it at the initial level\n* Garbage collection (GC)-friendly, minimizing additional heap memory usage during runtime.\n* Support interaction between the application layer and the poller, e.g. creating a cache within the poller coroutine, enabling lock-free usage. (like runtime.mcache)\n* Few APIs and low learning costs\n\n## Benchmarks\n\nWe're comparing gnet, which is ranked first on TechEmpower, using the test code from [gnet (GoLang) Benchmarking Test](https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Go/gnet)\n\n\u003e Test environment GCP cloud VM, 2 cores, 4GB RAM\n\nThe bench results of gnet.\n```text\nwrk -c 2 -t 2 -d10s http://127.0.0.1:8080/xxx\nRunning 10s test @ http://127.0.0.1:8080/xxx\n  2 threads and 2 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency    47.79us  170.86us   8.95ms   99.59%\n    Req/Sec    22.92k     1.00k   24.39k    78.11%\n  458456 requests in 10.10s, 56.40MB read\nRequests/sec:  45395.26\nTransfer/sec:      5.58MB\n```\n\nThe bench results of goev. [test code](https://github.com/shaovie/goev/blob/main/example/techempower.go)\n```text\nwrk -c 2 -t 2 -d10s http://127.0.0.1:8080/xxx\nRunning 10s test @ http://127.0.0.1:8080/xxx\n  2 threads and 2 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency    42.69us   92.32us   6.33ms   99.57%\n    Req/Sec    23.49k     1.77k   26.37k    54.95%\n  471993 requests in 10.10s, 68.87MB read\nRequests/sec:  46733.75\nTransfer/sec:      6.82MB\n```\n\nBy the way, let's compare the implementation of the standard library(go.net). [test code](https://github.com/shaovie/goev/blob/main/example/nettcp.go)\n```text\nwrk -c 10000 -t 2 -d10s http://127.0.0.1:8080/xxx\nRunning 10s test @ http://127.0.0.1:8080/xxx\n  2 threads and 10000 connections\n  Thread Stats   Avg      Stdev     Max   +/- Stdev\n    Latency   137.84ms   55.13ms 347.47ms   67.92%\n    Req/Sec    19.83k     6.64k   38.33k    67.86%\n  353390 requests in 10.22s, 51.56MB read\nRequests/sec:  34576.68\nTransfer/sec:      5.05MB\n```\n\n\u003e Note: This is the most basic and simplest test, for reference only\n\n\n[**NEW**] 1.6Million Req/sec Test environment Aliyun ECS, 32 vcore, 64GB RAM  ./techempower -c 48 -p 64\n\n![](images/bench-32v-64g.png)\n\n## Installation\n\n```bash\ngo get -u github.com/shaovie/goev\n```\n\n## Getting Started\n\nSee the [中文指南](DOCUMENT_CN.md) for the Chinese documentation.\n\n### Simple Service Example\n\n```go\npackage main\n\nimport (\n    \"github.com/shaovie/goev\"\n)\n\nvar connReactor *goev.Reactor\n\ntype Conn struct {\n\tgoev.IOHandle\n}\n\nfunc (c *Conn) OnOpen() bool {\n\tif err := connReactor.AddEvHandler(c, c.Fd(), goev.EvIn); err != nil {\n\t\treturn false\n\t}\n\treturn true\n}\nfunc (c *Conn) OnRead() bool {\n\tbuf, n, _ := c.Read()\n\tif n == 0 { // Abnormal connection\n\t\treturn false\n\t}\n    // parse msg\n    return true\n}\nfunc (c *Conn) OnClose() {\n    c.Destroc(h) // release resource\n}\n\nfunc main() {\n\truntime.GOMAXPROCS(runtime.NumCPU()*2 - 1)\n\tlistenReactor, err := goev.NewReactor(goev.EvPollNum(1))\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tconnReactor, err := goev.NewReactor(goev.EvPollNum(runtime.NumCPU()*3/2))\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\t_, err = goev.NewAcceptor(listenReactor, \":8080\", func() goev.EvHandler { return new(Conn) })\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\n\tgo func() {\n\t\tif err = listenReactor.Run(); err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\t}()\n    \n\tif err = connReactor.Run(); err != nil {\n\t\tpanic(err.Error())\n\t}\n}\n\n```\n\n### REUSEPORT Service Example\n\n```go\npackage main\n\n...\n\nfunc main() {\n\truntime.GOMAXPROCS(runtime.NumCPU()*2)\n\tevPollNum := runtime.NumCPU()*3/2\n\tconnReactor, err := goev.NewReactor(goev.EvPollNum(evPollNum))\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n    for i := 0; i \u003c evPollNum; i++ {\n        _, err = goev.NewAcceptor(connReactor, \":8080\", func() goev.EvHandler { return new(Conn) },\n            goev.ReusePort(true),\n        )\n        if err != nil {\n            panic(err.Error())\n        }\n    }\n\tif err = connReactor.Run(); err != nil {\n\t\tpanic(err.Error())\n\t}\n}\n\n```\n\u003e Note: The reactor will bind different acceptors (listener fd) to different epoll instances to achieve multithreaded concurrent listening on the same IP:PORT\n\n\n## Development Roadmap\n\n- [x] Async write (refer example/async_http.go)\n- [x] Websocket example\n- [x] Goev runtime GC zero pressure\n- [x] Poller cache(like thread cache)\n- [x] Poller sync. Allow the application layer to interact with the poller (limited to the operations supported by the framework) (refer example/download.go)\n\n## Contributing\nContributions are welcome! If you find any bugs or have suggestions for improvement, please open an issue or submit a pull request\n\n## License\n`goev` source code is available under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshaovie%2Fgoev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshaovie%2Fgoev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshaovie%2Fgoev/lists"}