{"id":25410010,"url":"https://github.com/negrel/conc","last_synced_at":"2025-12-14T22:05:15.582Z","repository":{"id":276493974,"uuid":"929440687","full_name":"negrel/conc","owner":"negrel","description":"📐 Structured concurrency for Go.","archived":false,"fork":false,"pushed_at":"2025-03-04T21:22:28.000Z","size":30,"stargazers_count":47,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-04T16:15:27.656Z","etag":null,"topics":["concurrency","go","goroutines","structured"],"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/negrel.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}},"created_at":"2025-02-08T15:02:37.000Z","updated_at":"2025-06-25T22:30:08.000Z","dependencies_parsed_at":"2025-03-04T22:30:39.269Z","dependency_job_id":null,"html_url":"https://github.com/negrel/conc","commit_stats":null,"previous_names":["negrel/sgo","negrel/conc"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/negrel/conc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/negrel%2Fconc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/negrel%2Fconc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/negrel%2Fconc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/negrel%2Fconc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/negrel","download_url":"https://codeload.github.com/negrel/conc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/negrel%2Fconc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266801396,"owners_count":23986371,"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-24T02:00:09.469Z","response_time":99,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"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":["concurrency","go","goroutines","structured"],"created_at":"2025-02-16T09:29:12.940Z","updated_at":"2025-12-14T22:05:10.550Z","avatar_url":"https://github.com/negrel.png","language":"Go","readme":"![structured concurrency schema](https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.thedevtavern.com%2Fstatic%2F671edc5ec17e1522393f07c0f7b42465%2F9bec7%2Fbanner.png\u0026f=1\u0026nofb=1\u0026ipt=3295434f2f3b02cfff98cc60776bf62cf519268dc90982d7d98a3caff5544dce\u0026ipo=images)\n\n# `conc` - Structured concurrency for Go\n\n[![Go doc](https://pkg.go.dev/badge/github.com/negrel/conc)](https://pkg.go.dev/github.com/negrel/conc)\n[![go report card](https://goreportcard.com/badge/github.com/negrel/conc)](https://goreportcard.com/report/github.com/negrel/conc)\n[![license card](https://img.shields.io/github/license/negrel/conc)](./LICENSE)\n[![PRs welcome card](https://img.shields.io/badge/PRs-Welcome-brightgreen)](https://github.com/negrel/conc/pulls)\n![Go version card](https://img.shields.io/github/go-mod/go-version/negrel/conc)\n\n`conc` is a **structured concurrency** library for Go that provides a safer,\nmore intuitive approach to concurrent programming.\n\nBy emphasizing proper resource management, error handling, and execution flow,\n`conc` helps developers write concurrent code that is less error-prone, easier\nto reason about, and aligned with established best practices.\n\n```sh\ngo get github.com/negrel/conc\n```\n\n## Predictable code flow\n\n`conc` is based on `nursery` as described in [this blog post](https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/).\n\n\nIdea behind nursery is that routines are scoped to a block that returns when\nall goroutines are done. This way, code flow remains sequential outside before\nand after the block. Here is an example:\n\n```go\nfunc main() {\n\tconc.Block(func(n conc.Nursery) error {\n\t\t// Spawn a goroutine.\n\t\tn.Go(func() error {\n\t\t\treturn nil\n\t\t})\n\n\t\t// Spawn another goroutine.\n\t\tn.Go(func() error {\n\t\t\ttime.Sleep(2 * time.Second)\n\t\t\treturn nil\n\t\t})\n\n\t\t// Sleep before returning.\n\t\ttime.Sleep(time.Second)\n\t\treturn nil\n\t})\n\t// Once block returns (here after 2 seconds), you're guaranteed that there is no\n\t// goroutine leak.\n\t// ...\n}\n```\n\nHere is the definition of the `Nursery` interface:\n\n```go\ntype Nursery interface {\n\tcontext.Context\n\tGo(func() error)\n}\n```\n\nIt is a simple extension to [`context.Context`](https://pkg.go.dev/context#Context) that allows spawning routines.\n\n[`Block`](https://pkg.go.dev/github.com/negrel/conc#Block) and\n[`Nursery`](https://pkg.go.dev/github.com/negrel/conc#Nursery) are the core of\nthe entire library.\n\n## Explicit goroutines \"leak\"\n\nNow, let's say you want to write a function spawning routines that outlives it.\nYou can pass `Nursery` as a parameter making the leak explicit:\n\n```go\nfunc workHard(n conc.Nursery) {\n\tn.Go(func() error {\n\t\treturn longWork(n)\n\t})\n\n\tn.Go(func() error {\n\t\treturn longerWork(n)\n\t})\n}\n```\n\n## And more...\n\n* Graceful panics and errors handling\n* Context integration for deadlines and cancellation\n* Limit maximum number of goroutine used by a block\n* Goroutines are pool allocated to improve efficiency\n* Dependency free\n\n## Performance\n\nHere, an operation means spawning 100 goroutines:\n\n```sh\n$ cd bench/\n$ go test -v -bench=./... -benchmem ./...\ngoos: linux\ngoarch: amd64\npkg: github.com/negrel/conc/bench\ncpu: AMD Ryzen 7 7840U w/ Radeon  780M Graphics\nBenchmarkNursery\nBenchmarkNursery/EmptyBlock\nBenchmarkNursery/EmptyBlock-16   1367210               914.3 ns/op           625 B/op         11 allocs/op\nBenchmarkNursery/WithRoutines/NoWork\nBenchmarkNursery/WithRoutines/NoWork-16                    26823             43909 ns/op            1514 B/op         65 allocs/op\nBenchmarkNursery/WithRoutines/Nested/NoWork\nBenchmarkNursery/WithRoutines/Nested/NoWork-16             18189             69416 ns/op            3623 B/op        147 allocs/op\nBenchmarkNursery/WithRoutines/1msWork\nBenchmarkNursery/WithRoutines/1msWork-16                     940           1300306 ns/op           11941 B/op        211 allocs/op\nBenchmarkNursery/WithRoutines/1-10msWork\nBenchmarkNursery/WithRoutines/1-10msWork-16                  123           9681105 ns/op           12427 B/op        292 allocs/op\nBenchmarkNursery/WithRoutines/Error\nBenchmarkNursery/WithRoutines/Error-16                     26767             44257 ns/op            1485 B/op         65 allocs/op\nBenchmarkSourceGraphConc\nBenchmarkSourceGraphConc/EmptyPool\nBenchmarkSourceGraphConc/EmptyPool-16                   13450243                85.45 ns/op          176 B/op          2 allocs/op\nBenchmarkSourceGraphConc/WithRoutines/NoWork\nBenchmarkSourceGraphConc/WithRoutines/NoWork-16            48522             23928 ns/op            1835 B/op         84 allocs/op\nBenchmarkSourceGraphConc/WithRoutines/1msWork\nBenchmarkSourceGraphConc/WithRoutines/1msWork-16                     966           1239140 ns/op           13776 B/op        302 allocs/op\nBenchmarkSourceGraphConc/WithRoutines/1-10msWork\nBenchmarkSourceGraphConc/WithRoutines/1-10msWork-16                  123           9625635 ns/op           14030 B/op        372 allocs/op\nBenchmarkGo\nBenchmarkGo/WithRoutines/NoWork\nBenchmarkGo/WithRoutines/NoWork-16                                 84024             14240 ns/op            1600 B/op        100 allocs/op\nBenchmarkGo/WithRoutines/Nested/NoWork\nBenchmarkGo/WithRoutines/Nested/NoWork-16                          81360             14497 ns/op            3199 B/op        199 allocs/op\nBenchmarkGo/WithRoutines/1msWork\nBenchmarkGo/WithRoutines/1msWork-16                                59904             18651 ns/op           11215 B/op        200 allocs/op\nBenchmarkGo/WithRoutines/1-10msWork\nBenchmarkGo/WithRoutines/1-10msWork-16                             51703             21088 ns/op           11069 B/op        190 allocs/op\nPASS\nok      github.com/negrel/conc/bench    22.347s\n```\n\n## Contributing\n\nIf you want to contribute to `conc` to add a feature or improve the code contact\nme at [alexandre@negrel.dev](mailto:alexandre@negrel.dev), open an\n[issue](https://github.com/negrel/conc/issues) or make a\n[pull request](https://github.com/negrel/conc/pulls).\n\n## :stars: Show your support\n\nPlease give a :star: if this project helped you!\n\n[![buy me a coffee](https://github.com/negrel/.github/blob/master/.github/images/bmc-button.png?raw=true)](https://www.buymeacoffee.com/negrel)\n\n## :scroll: License\n\nMIT © [Alexandre Negrel](https://www.negrel.dev/)\n","funding_links":["https://www.buymeacoffee.com/negrel"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnegrel%2Fconc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnegrel%2Fconc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnegrel%2Fconc/lists"}