{"id":27106510,"url":"https://github.com/jcbritobr/go-concurrency-patterns","last_synced_at":"2025-07-26T20:13:07.328Z","repository":{"id":85141988,"uuid":"281938647","full_name":"jcbritobr/go-concurrency-patterns","owner":"jcbritobr","description":"Examples on how to implement concurrency patterns in golang, and use the best feature of the language.","archived":false,"fork":false,"pushed_at":"2023-04-26T13:39:06.000Z","size":86,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-22T11:02:44.742Z","etag":null,"topics":["concurrent-programming","golang","parallel-programming","parallelism","patterns"],"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/jcbritobr.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":"2020-07-23T11:56:45.000Z","updated_at":"2023-07-18T09:12:20.000Z","dependencies_parsed_at":"2023-06-29T11:16:19.265Z","dependency_job_id":null,"html_url":"https://github.com/jcbritobr/go-concurrency-patterns","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jcbritobr/go-concurrency-patterns","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcbritobr%2Fgo-concurrency-patterns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcbritobr%2Fgo-concurrency-patterns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcbritobr%2Fgo-concurrency-patterns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcbritobr%2Fgo-concurrency-patterns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jcbritobr","download_url":"https://codeload.github.com/jcbritobr/go-concurrency-patterns/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcbritobr%2Fgo-concurrency-patterns/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261282253,"owners_count":23134937,"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":["concurrent-programming","golang","parallel-programming","parallelism","patterns"],"created_at":"2025-04-06T19:56:07.441Z","updated_at":"2025-07-26T20:13:07.307Z","avatar_url":"https://github.com/jcbritobr.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Golang Concurrency Patterns Examples\nThis repository contains implemented golang concurrency patterns.\n\n* Generator/Iterator \\\nGenerator pattern is a way to a generate data sequences using paralelism. Using this pattern we are able to make the consumer run in parallel with the generator.\n\n**Implementation**\n```go\nfunc generator(buffer ...int) \u003c-chan int {\n\t// a channel that will be returned with data\n\tc := make(chan int)\n\t// parallel process\n\tgo func() {\n\t\t// iterate over incomming data chunk\n\t\tfor item := range buffer {\n\t\t\t// pass data for channel\n\t\t\tc \u003c- item\n\t\t}\n\t\t// when finnished, close the channel\n\t\tclose(c)\n\t}()\n\t//return the channel\n\treturn c\n}\n```\n\n**Use**\n```go\n\t// data chunk\n\tdata := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}\n\t// load data into channel\n\tg := generator(data...)\n\n\t// consum the channel\n\tfor i := range g {\n\t\t// print result data chunk\n\t\tfmt.Println(\"item:\", i)\n\t}\n```\n* Future \\\nA Future will start a parallel computation, and its results will be available in the future. In golang, a simple goroutine can be use to implement this funcionality, without use of third party libraries or standard ones. \n\n**Implementation**\n```go\nfunc fiboFuture(number int) \u003c-chan int {\n\t// Channel with the result\n\tc := make(chan int)\n\n\t// Starts a parallel process to calc fibonacci number\n\tgo func() {\n\t\tif number \u003c= 1 {\n\t\t\tc \u003c- number\n\t\t\treturn\n\t\t}\n\n\t\tfib := 1\n\t\tprevFib := 1\n\t\tfor i := 0; i \u003c number; i++ {\n\t\t\ttemp := fib\n\t\t\tfib += prevFib\n\t\t\tprevFib = temp\n\t\t}\n\t\t// Send the result to channel\n\t\tc \u003c- fib\n\t\t// Close channel\n\t\tclose(c)\n\t}()\n\n\treturn c\n}\n```\n\n**Use**\n```go\n\t// Gets a future processing\n\tfuture := fiboFuture(44)\n\t// Prints the result of future. If still processing, instead, future will block\n\tfmt.Println(\"result of future processing:\", \u003c-future)\n```\n\n* Fan-in/Fan-out \\\nThe best way to implement a processing pipeline in golang is using the fan in/out pattern. The pattern is built by a function and a goroutine\nthat transports and loads data, using channels, to another. In the end of process, all the goroutines data are merged into one. Its a way of multiplexing and demultiplexing multiple input data.\nSee image below:\n\n**Implementation**\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"images/faninfanout.png\"\u003e\n\u003c/p\u003e\n\n**Use**\n```go\n\t// data to be processed\n\tdata := []int{1, 2, 3, 4, 5}\n\t// generator loads data\n\tg := generator(data...)\n\n\t// fan-out the data in square pipeline\n\tsq1 := sq(g)\n\tsq2 := sq(g)\n\n\t// consumn the parallel square pipeline - fan-in\n\tfor item := range merge(sq1, sq2) {\n\t\tfmt.Println(item)\n\t}\n```\n\n* WorkersPool \\\nWorkersPool is a pattern that aims to control the number of goroutines available to a system or application. If we create a pool with 3 workers, than no more goroutines can be spawned to new tasks, and its tasks will be waiting to others finnish.\n\n**Implementation**\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"images/workerspool.png\"\u003e\n\u003c/p\u003e\n\n```go\ntype ExecFunc func()\n\ntype ThreadPool struct {\n\treceiver chan ExecFunc\n\tsize     int\n}\n\nfunc NewThreadPool(size int) *ThreadPool {\n\tpool := \u0026ThreadPool{\n\t\treceiver: make(chan ExecFunc),\n\t\tsize:     size,\n\t}\n\n\treturn pool\n}\n\nfunc (t ThreadPool) start() {\n\tfor i := 0; i \u003c t.size; i++ {\n\t\tgo func() {\n\t\t\tfor {\n\t\t\t\tf := \u003c-t.receiver\n\t\t\t\tf()\n\t\t\t}\n\t\t}()\n\t}\n}\n\nfunc (t *ThreadPool) Execute(f ExecFunc) {\n\tt.receiver \u003c- f\n}\n\n```\n\n**Use**\n```go\npool := NewThreadPool(3)\nvar wg sync.WaitGroup\nwg.Add(2)\npool.start()\n\njob := func(id int) {\n\tfor i := 0; i \u003c 1000; i++ {\n\t\tprintln(id, \"-\u003e\", i)\n\t}\n}\n\npool.Execute(func() {\n\tjob(1)\n\twg.Done()\n})\n\npool.Execute(func() {\n\tjob(2)\n\twg.Done()\n})\n\nwg.Wait()\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcbritobr%2Fgo-concurrency-patterns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjcbritobr%2Fgo-concurrency-patterns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcbritobr%2Fgo-concurrency-patterns/lists"}