{"id":19282207,"url":"https://github.com/theskyinflames/dynamic","last_synced_at":"2025-08-02T19:07:17.014Z","repository":{"id":137365651,"uuid":"317774489","full_name":"theskyinflames/dynamic","owner":"theskyinflames","description":"This is simple but powerful workflow data flow building library inspired by railway programming pattern and flow-based programming paradigm","archived":false,"fork":false,"pushed_at":"2021-07-21T11:57:28.000Z","size":151,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-22T05:33:02.666Z","etag":null,"topics":["actor-pattern","channels","flow","flow-based-programming","functional-programming","golang","golang-concurrency","goroutines","jobs","railway-oriented-programming","workfow"],"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/theskyinflames.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":"2020-12-02T06:47:06.000Z","updated_at":"2022-12-08T09:14:06.000Z","dependencies_parsed_at":"2023-07-13T20:15:34.728Z","dependency_job_id":null,"html_url":"https://github.com/theskyinflames/dynamic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/theskyinflames/dynamic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theskyinflames%2Fdynamic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theskyinflames%2Fdynamic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theskyinflames%2Fdynamic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theskyinflames%2Fdynamic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theskyinflames","download_url":"https://codeload.github.com/theskyinflames/dynamic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theskyinflames%2Fdynamic/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268438938,"owners_count":24250667,"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-08-02T02:00:12.353Z","response_time":74,"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":["actor-pattern","channels","flow","flow-based-programming","functional-programming","golang","golang-concurrency","goroutines","jobs","railway-oriented-programming","workfow"],"created_at":"2024-11-09T21:25:46.710Z","updated_at":"2025-08-02T19:07:16.964Z","avatar_url":"https://github.com/theskyinflames.png","language":"Go","readme":"\u003cimg src=\"./dynamic-logo.png\"\n     alt=\"dynamic logo\"\n     style=\"padding:10px; margin: 10px;background:white\" /\u003e\n# dynamic\nThis is a kind of workflows library inspired by:\n* [flow-based programming paradigm](https://en.wikipedia.org/wiki/Flow-based_programming)\n* [railway programming pattern](https://naveenkumarmuguda.medium.com/railway-oriented-programming-a-powerful-functional-programming-pattern-ab454e467f31)\n\nThe idea is to provide an easy way to implement complex data flow processes, included splits and joins. To achieve that, this lib uses these elements that are described below.\n\n## **Job** \n```go\n    type Job func(context.Context, Postman)\n``` \nEach **Job** implements a unique task in the *Flow*. It comunitcates with the rest of *Jobs* (parents and childs), by receiving and sending *Param* messages:\n```go\n    type Param struct {\n    \tErr   error\n    \tName  string\n    \tValue interface{}\n    }\n```\nTo receive/send messages from/to its parents/children, each *Job* receives a **Postman** implementation:\n```go\n    type Postman interface {\n\t    Receive(ctx context.Context) (*Param, error)\n\t    Send(ctx context.Context, p Param) bool\n    }\n````\nNeither of the two methods is a blocker. I mean that *Receive* method will return a nil param if there is not a message to be read from parents, and the *Send* method will return false if the message has not been sent. It can occur if the children are not still ready to receive it. But you are free to make them locker by wrapping them in an infinite loop until the message is read/sent.\n\n## **Worker**\nA *Worker* wrappers a *Job* to be indcluded and managed by a *Flow*. It is in charge of:\n* Ensuring that the *Job* is up and running.\n* Kill the *Job* when the flow is also killed.\n* Connecting the *Job* with its parents and children.\n* Provide messages from parents through the *Postman.Receive* method.\n* Filter messages from parents if a filter has been provided. The filter is provided as an option to the *Worker* constructor.\n```go\n    type InFilterFunc func(Param) bool\n```\n* Sending output messages from the *Job* to its children through the *Postman.Send* method\n\n## **Flow**\nThe *Flow* performs the flow role. It is provided with a list of workers. When it starts, all of its workers also start. And when it finishes, all of its worker finishes.\n\n# Building a flow\nThese are the steps to flow to build a flow:\n1. Coding the *Job* functions\n2. Wrapping the *Jobs* into *Workers*\n3. Defining the Flow\n4. Adding the *Workers* to the *Flow*\n5. Starting the *Flow*\n6. If the *Flow* is not and endless one, kill it when it finishes.\n\nSee [Sorting flow example](./examples/sorting/README.md) and [tests](./workflow_test.go) to figure out how to code your own flows in a easy way. It's really easy to do thanks to [Go concurrency features](https://en.wikipedia.org/wiki/Go_(programming_language)#Concurrency:_goroutines_and_channels)\n\n# Disclaimer\n**I've coded it only for fun**. Please read the [LICENSE](./LICENSE). I hope you enjoy using it as much as I enjoyed building it. All ideas are welcome. Please let me know what you would add or change.\n\n# TODO\n* Adding more examples\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheskyinflames%2Fdynamic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheskyinflames%2Fdynamic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheskyinflames%2Fdynamic/lists"}