{"id":27880858,"url":"https://github.com/atomicgo/robin","last_synced_at":"2025-09-11T23:41:23.060Z","repository":{"id":173061563,"uuid":"650186356","full_name":"atomicgo/robin","owner":"atomicgo","description":"🔄 Generic, fast and thread-safe round-robin loadbalancer library","archived":false,"fork":false,"pushed_at":"2024-08-08T17:04:33.000Z","size":59,"stargazers_count":16,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-05T04:45:05.833Z","etag":null,"topics":["atomicgo","go","golang","golang-library","loadbalancer","loadbalancing","round-robin"],"latest_commit_sha":null,"homepage":"https://atomicgo.dev","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/atomicgo.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["MarvinJWendt"]}},"created_at":"2023-06-06T14:24:28.000Z","updated_at":"2024-11-05T09:34:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"a2d5c029-9cf3-42bb-b41d-c2359737dd56","html_url":"https://github.com/atomicgo/robin","commit_stats":null,"previous_names":["atomicgo/robin"],"tags_count":2,"template":false,"template_full_name":"atomicgo/template","purl":"pkg:github/atomicgo/robin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicgo%2Frobin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicgo%2Frobin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicgo%2Frobin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicgo%2Frobin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atomicgo","download_url":"https://codeload.github.com/atomicgo/robin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicgo%2Frobin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267470062,"owners_count":24092352,"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","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["atomicgo","go","golang","golang-library","loadbalancer","loadbalancing","round-robin"],"created_at":"2025-05-05T04:38:50.913Z","updated_at":"2025-07-28T06:08:33.872Z","avatar_url":"https://github.com/atomicgo.png","language":"Go","funding_links":["https://github.com/sponsors/MarvinJWendt"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eAtomicGo | robin\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://img.shields.io/endpoint?url=https%3A%2F%2Fatomicgo.dev%2Fapi%2Fshields%2Frobin\u0026style=flat-square\" alt=\"Downloads\"\u003e\n\n\u003ca href=\"https://github.com/atomicgo/robin/releases\"\u003e\n\u003cimg src=\"https://img.shields.io/github/v/release/atomicgo/robin?style=flat-square\" alt=\"Latest Release\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://codecov.io/gh/atomicgo/robin\" target=\"_blank\"\u003e\n\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/atomicgo/robin/go.yml?style=flat-square\" alt=\"Tests\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://codecov.io/gh/atomicgo/robin\" target=\"_blank\"\u003e\n\u003cimg src=\"https://img.shields.io/codecov/c/gh/atomicgo/robin?color=magenta\u0026logo=codecov\u0026style=flat-square\" alt=\"Coverage\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://codecov.io/gh/atomicgo/robin\"\u003e\n\u003c!-- unittestcount:start --\u003e\u003cimg src=\"https://img.shields.io/badge/Unit_Tests-11-magenta?style=flat-square\" alt=\"Unit test count\"\u003e\u003c!-- unittestcount:end --\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://opensource.org/licenses/MIT\" target=\"_blank\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square\" alt=\"License: MIT\"\u003e\n\u003c/a\u003e\n  \n\u003ca href=\"https://goreportcard.com/report/github.com/atomicgo/robin\" target=\"_blank\"\u003e\n\u003cimg src=\"https://goreportcard.com/badge/github.com/atomicgo/robin?style=flat-square\" alt=\"Go report\"\u003e\n\u003c/a\u003e   \n\n\u003c/p\u003e\n\n---\n\n\u003cp align=\"center\"\u003e\n\u003cstrong\u003e\u003ca href=\"https://pkg.go.dev/atomicgo.dev/robin#section-documentation\" target=\"_blank\"\u003eDocumentation\u003c/a\u003e\u003c/strong\u003e\n|\n\u003cstrong\u003e\u003ca href=\"https://github.com/atomicgo/atomicgo/blob/main/CONTRIBUTING.md\" target=\"_blank\"\u003eContributing\u003c/a\u003e\u003c/strong\u003e\n|\n\u003cstrong\u003e\u003ca href=\"https://github.com/atomicgo/atomicgo/blob/main/CODE_OF_CONDUCT.md\" target=\"_blank\"\u003eCode of Conduct\u003c/a\u003e\u003c/strong\u003e\n\u003c/p\u003e\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/atomicgo/atomicgo/main/assets/header.png\" alt=\"AtomicGo\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ctable\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/p\u003e\n\u003ch3  align=\"center\"\u003e\u003cpre\u003ego get atomicgo.dev/robin\u003c/pre\u003e\u003c/h3\u003e\n\u003cp align=\"center\"\u003e\n\u003ctable\u003e\n\u003ctbody\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/p\u003e\n\n\u003c!-- gomarkdoc:embed:start --\u003e\n\n\u003c!-- Code generated by gomarkdoc. DO NOT EDIT --\u003e\n\n# robin\n\n```go\nimport \"atomicgo.dev/robin\"\n```\n\nPackage robin is a simple, generic and thread\\-safe round\\-robin load balancer for Go.\n\nIt can be used to load balance any type of data. It is not limited to HTTP requests.\n\nRobin takes any slice as an input and returns the next item in the slice. When the end of the slice is reached, it starts again from the beginning.\n\nThread\\-safety is achieved by using atomic operations amd guarantees that two concurrent calls to Loadbalancer.Next will not return the same item, if the slice contains more than one item.\n\nBenchmark:\n\n```\nBenchmarkLoadbalancer_Next              252151534                4.746 ns/op           0 B/op          0 allocs/op\nBenchmarkLoadbalancer_Next-2            254281032                4.758 ns/op           0 B/op          0 allocs/op\nBenchmarkLoadbalancer_Next-4            253424396                4.738 ns/op           0 B/op          0 allocs/op\nBenchmarkLoadbalancer_Next-8            254842484                4.752 ns/op           0 B/op          0 allocs/op\nBenchmarkLoadbalancer_Next-16           247016046                4.785 ns/op           0 B/op          0 allocs/op\nBenchmarkLoadbalancer_Next-32           250539441                4.774 ns/op           0 B/op          0 allocs/op\n```\n\n## Index\n\n- [type Loadbalancer](\u003c#Loadbalancer\u003e)\n  - [func NewLoadbalancer\\[T any\\]\\(items \\[\\]T\\) \\*Loadbalancer\\[T\\]](\u003c#NewLoadbalancer\u003e)\n  - [func \\(l \\*Loadbalancer\\[T\\]\\) AddItems\\(items ...T\\)](\u003c#Loadbalancer[T].AddItems\u003e)\n  - [func \\(l \\*Loadbalancer\\[T\\]\\) Current\\(\\) T](\u003c#Loadbalancer[T].Current\u003e)\n  - [func \\(l \\*Loadbalancer\\[T\\]\\) Next\\(\\) T](\u003c#Loadbalancer[T].Next\u003e)\n  - [func \\(l \\*Loadbalancer\\[T\\]\\) Reset\\(\\)](\u003c#Loadbalancer[T].Reset\u003e)\n\n\n\u003ca name=\"Loadbalancer\"\u003e\u003c/a\u003e\n## type [Loadbalancer](\u003chttps://github.com/atomicgo/robin/blob/main/robin.go#L8-L12\u003e)\n\nLoadbalancer is a simple, generic and thread\\-safe round\\-robin load balancer for Go.\n\n```go\ntype Loadbalancer[T any] struct {\n    Items []T\n    // contains filtered or unexported fields\n}\n```\n\n\u003cdetails\u003e\u003csummary\u003eExample (Demo)\u003c/summary\u003e\n\u003cp\u003e\n\n\n\n```go\npackage main\n\nimport (\n\t\"atomicgo.dev/robin\"\n\t\"fmt\"\n)\n\ntype Person struct {\n\tName string\n}\n\nfunc main() {\n\tpeople := []Person{\n\t\t{Name: \"person1\"},\n\t\t{Name: \"person2\"},\n\t\t{Name: \"person3\"},\n\t\t{Name: \"person4\"},\n\t\t{Name: \"person5\"},\n\t}\n\n\tlb := robin.NewLoadbalancer(people)\n\n\tfor i := 0; i \u003c 10; i++ {\n\t\tfmt.Println(lb.Next().Name)\n\t}\n\n}\n```\n\n#### Output\n\n```\nperson1\nperson2\nperson3\nperson4\nperson5\nperson1\nperson2\nperson3\nperson4\nperson5\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003ca name=\"NewLoadbalancer\"\u003e\u003c/a\u003e\n### func [NewLoadbalancer](\u003chttps://github.com/atomicgo/robin/blob/main/robin.go#L16\u003e)\n\n```go\nfunc NewLoadbalancer[T any](items []T) *Loadbalancer[T]\n```\n\nNewLoadbalancer creates a new Loadbalancer. It is guaranteed that two concurrent calls to Loadbalancer.Next will not return the same item, if the slice contains more than one item.\n\n\u003cdetails\u003e\u003csummary\u003eExample\u003c/summary\u003e\n\u003cp\u003e\n\n\n\n```go\npackage main\n\nimport (\n\t\"atomicgo.dev/robin\"\n\t\"fmt\"\n)\n\nfunc main() {\n\tset := []string{\"object1\", \"object2\", \"object3\"}\n\tlb := robin.NewLoadbalancer(set)\n\n\tfmt.Println(lb.Current())\n\n}\n```\n\n#### Output\n\n```\nobject1\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003ca name=\"Loadbalancer[T].AddItems\"\u003e\u003c/a\u003e\n### func \\(\\*Loadbalancer\\[T\\]\\) [AddItems](\u003chttps://github.com/atomicgo/robin/blob/main/robin.go#L40\u003e)\n\n```go\nfunc (l *Loadbalancer[T]) AddItems(items ...T)\n```\n\nAddItems adds items to the Loadbalancer.\n\n\u003cdetails\u003e\u003csummary\u003eExample\u003c/summary\u003e\n\u003cp\u003e\n\n\n\n```go\npackage main\n\nimport (\n\t\"atomicgo.dev/robin\"\n\t\"fmt\"\n)\n\nfunc main() {\n\tset := []int{1, 2, 3}\n\tlb := robin.NewLoadbalancer(set)\n\n\tlb.AddItems(4, 5, 6)\n\n\tfmt.Println(lb.Items)\n\n}\n```\n\n#### Output\n\n```\n[1 2 3 4 5 6]\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003ca name=\"Loadbalancer[T].Current\"\u003e\u003c/a\u003e\n### func \\(\\*Loadbalancer\\[T\\]\\) [Current](\u003chttps://github.com/atomicgo/robin/blob/main/robin.go#L23\u003e)\n\n```go\nfunc (l *Loadbalancer[T]) Current() T\n```\n\nCurrent returns the current item in the slice, without advancing the Loadbalancer.\n\n\u003cdetails\u003e\u003csummary\u003eExample\u003c/summary\u003e\n\u003cp\u003e\n\n\n\n```go\npackage main\n\nimport (\n\t\"atomicgo.dev/robin\"\n\t\"fmt\"\n)\n\nfunc main() {\n\tset := []int{1, 2, 3}\n\tlb := robin.NewLoadbalancer(set)\n\n\tfmt.Println(lb.Current())\n\n}\n```\n\n#### Output\n\n```\n1\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003ca name=\"Loadbalancer[T].Next\"\u003e\u003c/a\u003e\n### func \\(\\*Loadbalancer\\[T\\]\\) [Next](\u003chttps://github.com/atomicgo/robin/blob/main/robin.go#L29\u003e)\n\n```go\nfunc (l *Loadbalancer[T]) Next() T\n```\n\nNext returns the next item in the slice. When the end of the slice is reached, it starts again from the beginning.\n\n\u003cdetails\u003e\u003csummary\u003eExample\u003c/summary\u003e\n\u003cp\u003e\n\n\n\n```go\npackage main\n\nimport (\n\t\"atomicgo.dev/robin\"\n\t\"fmt\"\n)\n\nfunc main() {\n\tset := []int{1, 2, 3}\n\tlb := robin.NewLoadbalancer(set)\n\n\tfor i := 0; i \u003c 10; i++ {\n\t\tfmt.Println(lb.Next())\n\t}\n}\n```\n\n#### Output\n\n```\n1\n2\n3\n1\n2\n3\n1\n2\n3\n1\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003ca name=\"Loadbalancer[T].Reset\"\u003e\u003c/a\u003e\n### func \\(\\*Loadbalancer\\[T\\]\\) [Reset](\u003chttps://github.com/atomicgo/robin/blob/main/robin.go#L35\u003e)\n\n```go\nfunc (l *Loadbalancer[T]) Reset()\n```\n\nReset resets the Loadbalancer to its initial state.\n\n\u003cdetails\u003e\u003csummary\u003eExample\u003c/summary\u003e\n\u003cp\u003e\n\n\n\n```go\npackage main\n\nimport (\n\t\"atomicgo.dev/robin\"\n\t\"fmt\"\n)\n\nfunc main() {\n\tset := []int{1, 2, 3, 4, 5, 6}\n\tlb := robin.NewLoadbalancer(set)\n\n\tlb.Next()\n\tlb.Next()\n\tlb.Next()\n\n\tlb.Reset()\n\n\tfmt.Println(lb.Current())\n\n}\n```\n\n#### Output\n\n```\n1\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\nGenerated by [gomarkdoc](\u003chttps://github.com/princjef/gomarkdoc\u003e)\n\n\n\u003c!-- gomarkdoc:embed:end --\u003e\n\n---\n\n\u003e [AtomicGo.dev](https://atomicgo.dev) \u0026nbsp;\u0026middot;\u0026nbsp;\n\u003e with ❤️ by [@MarvinJWendt](https://github.com/MarvinJWendt) |\n\u003e [MarvinJWendt.com](https://marvinjwendt.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatomicgo%2Frobin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatomicgo%2Frobin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatomicgo%2Frobin/lists"}