{"id":15788404,"url":"https://github.com/raphael/parallel","last_synced_at":"2025-03-31T18:24:24.259Z","repository":{"id":57619803,"uuid":"390226065","full_name":"raphael/parallel","owner":"raphael","description":"Simple and convenient parallel execution of Go functions","archived":false,"fork":false,"pushed_at":"2021-07-28T07:29:08.000Z","size":17,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-10-05T21:42:10.818Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/raphael.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-28T05:32:16.000Z","updated_at":"2021-07-28T10:51:36.000Z","dependencies_parsed_at":"2022-09-16T19:21:57.482Z","dependency_job_id":null,"html_url":"https://github.com/raphael/parallel","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphael%2Fparallel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphael%2Fparallel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphael%2Fparallel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphael%2Fparallel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/raphael","download_url":"https://codeload.github.com/raphael/parallel/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246516095,"owners_count":20790174,"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-10-04T21:42:10.655Z","updated_at":"2025-03-31T18:24:24.234Z","avatar_url":"https://github.com/raphael.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Parallel\n \n[![Build Status](https://github.com/raphael/parallel/workflows/Test/badge.svg?branch=main\u0026event=push)](https://github.com/raphael/parallel/actions?query=branch%3Amain+event%3Apush)\n[![Coverage](https://coveralls.io/repos/github/raphael/parallel/badge.svg?branch=main\u0026style=flat-square)](https://coveralls.io/github/raphael/parallel?branch=main)\n[![Go Report Card](https://goreportcard.com/badge/github.com/raphael/parallel)](https://goreportcard.com/report/github.com/raphael/parallel)\n[![Go Reference](https://pkg.go.dev/badge/github.com/raphael/parallel.svg)](https://pkg.go.dev/github.com/raphael/parallel)\n[![MIT License](https://img.shields.io/badge/License-MIT-brightgreen.svg?style=flat-square)](https://github.com/raphael/parallel/blob/main/LICENSE.txt)\n\nParallel is a simple Go package for queueing parallel executions of a given\nfunction potentially providing different values for its arguments in each\ninvocation.  Parallel returns results as they become available making it\npossible to start processing them while calls are still in progress or even\npending.\n\nA prototypical use case is the implementation of an HTTP API poller that needs\nto make many (10,000+) API requests each with a different payload. The package\nis use case agnostic though and can be used any time a function needs to be\ncalled many times in parallel.\n\nThe pattern implemented by the package is not novel however parallel provides a\nsimple and clean API that is easy to use and reason about.\n\n## Features\n\n  - Simple API\n  - Ability to provide different values for each invocation\n  - Processes results as soon as they become available\n  - No dependencies on 3rd party packages\n  - No need to worry about concurrency\n  - As efficient as it gets\n\n## Installation\n\n    go get github.com/raphael/parallel\n\n## Usage\n\nThe package can be used in two ways:\n  - Using the high level [Function](https://pkg.go.dev/github.com/raphael/parallel#Function) type\n  - Using the low level [Do](https://pkg.go.dev/github.com/raphael/parallel#Do) function\n\nThe [Function](https://pkg.go.dev/github.com/raphael/parallel#Function) type\nmethods make use of the [Do](https://pkg.go.dev/github.com/raphael/parallel#Do)\nfunction internally and take care of doing the necessary channel management to\nexpose a simple API:\n\n```go\n// Run the function fn up to n times in parallel (note: the function won't\n// actually execute until Call is invoked below).\nf := parallel.Run(fn, n)\n// Call the function with the given argument (Call can be invoked any number of\n// times and is goroutine-safe).\nf.Call(arg)\n// Wait for completion of all calls.\nf.Wait()\n```\n\nResults returned by the function can be processed using the `OnResult` method:\n\n```go\nf.OnResult(func(result interface{}) {\n        // Do something with the result.\n})\n```\n\nSimilarly errors can be handled using the `OnError` method:\n\n```go\nf.OnError(func(err error) {\n        // Do something with the error.\n})\n```\n\nThe `Function` type is the preferred way to use the package as it provides a\ncleaner API and is easier to use. However the `Do` function might be more\nconvenient in some cases, for example if the code already makes use of channels\nto handle concurrency.\n\n```go\n// Create the input channel used to provide arguments to the function.\ninput := make(chan interface{})\n\n// Run the function fn up to n times in parallel.\nresch, errch := parallel.Do(fn, n, input)\n\n// Write to input channel (typically in a separate goroutine).\ngo func(input chan interface{}) {\n    input \u003c- someValue // as many times as needed\n    // Close input channel once we have written all values.\n    close(input)\n}(input)\n\n// Read from result and error channels (typically in the main goroutine).\nloop:\n    for {\n        select {\n            case res, ok := \u003c-resch:\n                if !ok {\n                    break loop // resch is closed, we are done\n                }\n                // do something with res\n            case err, ok := \u003c-errch:\n                if ok {\n                    // do something with err\n                }\n        }\n    }\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphael%2Fparallel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraphael%2Fparallel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphael%2Fparallel/lists"}