{"id":13562499,"url":"https://github.com/oklog/run","last_synced_at":"2025-05-13T21:07:51.936Z","repository":{"id":41262873,"uuid":"110604570","full_name":"oklog/run","owner":"oklog","description":"A universal mechanism to manage goroutine lifecycles","archived":false,"fork":false,"pushed_at":"2024-04-15T13:22:42.000Z","size":23,"stargazers_count":1597,"open_issues_count":2,"forks_count":86,"subscribers_count":31,"default_branch":"main","last_synced_at":"2025-04-28T13:59:31.009Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oklog.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}},"created_at":"2017-11-13T21:30:14.000Z","updated_at":"2025-04-27T16:01:36.000Z","dependencies_parsed_at":"2023-11-29T06:31:30.895Z","dependency_job_id":"833644af-1263-4fd4-bceb-8fe10f521bd9","html_url":"https://github.com/oklog/run","commit_stats":{"total_commits":9,"total_committers":3,"mean_commits":3.0,"dds":0.2222222222222222,"last_synced_commit":"c7096881717ecba8d86fc591c1cee0940e31ec2a"},"previous_names":["oklog/rungroup"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oklog%2Frun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oklog%2Frun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oklog%2Frun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oklog%2Frun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oklog","download_url":"https://codeload.github.com/oklog/run/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254028876,"owners_count":22002280,"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":[],"created_at":"2024-08-01T13:01:09.286Z","updated_at":"2025-05-13T21:07:46.925Z","avatar_url":"https://github.com/oklog.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# run\n\n[![GoDoc](https://godoc.org/github.com/oklog/run?status.svg)](https://godoc.org/github.com/oklog/run) \n[![test](https://github.com/oklog/run/actions/workflows/test.yaml/badge.svg?branch=main\u0026event=push)](https://github.com/oklog/run/actions/workflows/test.yaml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/oklog/run)](https://goreportcard.com/report/github.com/oklog/run)\n[![Apache 2 licensed](https://img.shields.io/badge/license-Apache2-blue.svg)](https://raw.githubusercontent.com/oklog/run/master/LICENSE)\n\nrun.Group is a universal mechanism to manage goroutine lifecycles.\n\nCreate a zero-value run.Group, and then add actors to it. Actors are defined as\na pair of functions: an **execute** function, which should run synchronously;\nand an **interrupt** function, which, when invoked, should cause the execute\nfunction to return. Finally, invoke Run, which concurrently runs all of the\nactors, waits until the first actor exits, invokes the interrupt functions, and\nfinally returns control to the caller only once all actors have returned. This\ngeneral-purpose API allows callers to model pretty much any runnable task, and\nachieve well-defined lifecycle semantics for the group.\n\nrun.Group was written to manage component lifecycles in func main for \n[OK Log](https://github.com/oklog/oklog). \nBut it's useful in any circumstance where you need to orchestrate multiple\ngoroutines as a unit whole.\n[Click here](https://www.youtube.com/watch?v=LHe1Cb_Ud_M\u0026t=15m45s) to see a\nvideo of a talk where run.Group is described.\n\n## Examples\n\n### context.Context\n\n```go\nctx, cancel := context.WithCancel(context.Background())\ng.Add(func() error {\n\treturn myProcess(ctx, ...)\n}, func(error) {\n\tcancel()\n})\n```\n\n### net.Listener\n\n```go\nln, _ := net.Listen(\"tcp\", \":8080\")\ng.Add(func() error {\n\treturn http.Serve(ln, nil)\n}, func(error) {\n\tln.Close()\n})\n```\n\n### io.ReadCloser\n\n```go\nvar conn io.ReadCloser = ...\ng.Add(func() error {\n\ts := bufio.NewScanner(conn)\n\tfor s.Scan() {\n\t\tprintln(s.Text())\n\t}\n\treturn s.Err()\n}, func(error) {\n\tconn.Close()\n})\n```\n\n## Comparisons\n\nPackage run is somewhat similar to package \n[errgroup](https://godoc.org/golang.org/x/sync/errgroup), \nexcept it doesn't require actor goroutines to understand context semantics.\n\nIt's somewhat similar to package\n[tomb.v1](https://godoc.org/gopkg.in/tomb.v1) or \n[tomb.v2](https://godoc.org/gopkg.in/tomb.v2),\nexcept it has a much smaller API surface, delegating e.g. staged shutdown of \ngoroutines to the caller.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foklog%2Frun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foklog%2Frun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foklog%2Frun/lists"}