{"id":15632757,"url":"https://github.com/cschleiden/go-workflows","last_synced_at":"2025-10-19T22:44:45.247Z","repository":{"id":37018452,"uuid":"434366539","full_name":"cschleiden/go-workflows","owner":"cschleiden","description":"Embedded durable workflows for Golang similar to DTFx/Cadence/Temporal","archived":false,"fork":false,"pushed_at":"2025-02-18T05:36:58.000Z","size":9056,"stargazers_count":292,"open_issues_count":19,"forks_count":53,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-05-16T10:04:26.976Z","etag":null,"topics":["durabletask","go","golang","orchestration","workflow","workflows"],"latest_commit_sha":null,"homepage":"https://cschleiden.github.io/go-workflows/","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/cschleiden.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":"2021-12-02T20:33:40.000Z","updated_at":"2025-05-13T03:13:58.000Z","dependencies_parsed_at":"2022-06-29T08:52:43.985Z","dependency_job_id":"a2241711-d6b5-4f54-8912-41115755d9a2","html_url":"https://github.com/cschleiden/go-workflows","commit_stats":{"total_commits":977,"total_committers":17,"mean_commits":"57.470588235294116","dds":"0.17502558853633576","last_synced_commit":"4973be84ae02d0eb6d45412ff4670d0c70dbfa0c"},"previous_names":["cschleiden/go-dt"],"tags_count":51,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cschleiden%2Fgo-workflows","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cschleiden%2Fgo-workflows/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cschleiden%2Fgo-workflows/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cschleiden%2Fgo-workflows/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cschleiden","download_url":"https://codeload.github.com/cschleiden/go-workflows/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254509476,"owners_count":22082891,"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":["durabletask","go","golang","orchestration","workflow","workflows"],"created_at":"2024-10-03T10:45:12.017Z","updated_at":"2025-10-19T22:44:45.150Z","avatar_url":"https://github.com/cschleiden.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Durable workflows using Go\n\n[![Build \u0026 Test](https://github.com/cschleiden/go-workflows/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/cschleiden/go-workflows/actions/workflows/go.yml)\n\nBorrows heavily from [Temporal](https://github.com/temporalio/temporal) (and since it's a fork also [Cadence](https://github.com/uber/cadence)) as well as [DTFx](https://github.com/Azure/durabletask).\n\nSee also:\n- https://cschleiden.dev/blog/2022-02-13-go-workflows-part1/\n- https://cschleiden.dev/blog/2022-05-02-go-workflows-part2/\n\n## Docs\n\nSee http://cschleiden.github.io/go-workflows for the current version of the documentation.\n\n## Simple example\n\n### Workflow\n\nWorkflows are written in Go code. The only exception is they must not use any of Go's non-deterministic features (`select`, iteration over a `map`, etc.). Inputs and outputs for workflows and activities have to be serializable:\n\n```go\nfunc Workflow1(ctx workflow.Context, input string) error {\n\tr1, err := workflow.ExecuteActivity[int](ctx, workflow.DefaultActivityOptions, Activity1, 35, 12).Get(ctx)\n\tif err != nil {\n\t\tpanic(\"error getting activity 1 result\")\n\t}\n\n\tlog.Println(\"A1 result:\", r1)\n\n\tr2, err := workflow.ExecuteActivity[int](ctx, workflow.DefaultActivityOptions, Activity2).Get(ctx)\n\tif err != nil {\n\t\tpanic(\"error getting activity 1 result\")\n\t}\n\n\tlog.Println(\"A2 result:\", r2)\n\n\treturn nil\n}\n```\n\n### Activities\n\nActivities can have side-effects and don't have to be deterministic. They will be executed only once and the result is persisted:\n\n```go\nfunc Activity1(ctx context.Context, a, b int) (int, error) {\n\treturn a + b, nil\n}\n\nfunc Activity2(ctx context.Context) (int, error) {\n\treturn 12, nil\n}\n\n```\n\n### Worker\n\nThe worker is responsible for executing `Workflows` and `Activities`, both need to be registered with it.\n\n```go\nfunc runWorker(ctx context.Context, mb backend.Backend) {\n\tw := worker.New(mb, nil)\n\n\tw.RegisterWorkflow(Workflow1)\n\n\tw.RegisterActivity(Activity1)\n\tw.RegisterActivity(Activity2)\n\n\tif err := w.Start(ctx); err != nil {\n\t\tpanic(\"could not start worker\")\n\t}\n}\n```\n\n### Backend\n\nThe backend is responsible for persisting the workflow events. Currently there is an in-memory backend implementation for testing, one using [SQLite](http://sqlite.org), one using MySql, and one using Redis.\n\n```go\nb := sqlite.NewSqliteBackend(\"simple.sqlite\")\n```\n\n### Putting it all together\n\nWe can start workflows from the same process the worker runs in -- or they can be separate. Here we use the SQLite backend, spawn a single worker (which then executes both `Workflows` and `Activities`), and then start a single instance of our workflow\n\n```go\nfunc main() {\n\tctx := context.Background()\n\n\tb := sqlite.NewSqliteBackend(\"simple.sqlite\")\n\n\tgo runWorker(ctx, b)\n\n\tc := client.New(b)\n\n\twf, err := c.CreateWorkflowInstance(ctx, client.WorkflowInstanceOptions{\n\t\tInstanceID: uuid.NewString(),\n\t}, Workflow1, \"input-for-workflow\")\n\tif err != nil {\n\t\tpanic(\"could not start workflow\")\n\t}\n\n\tc2 := make(chan os.Signal, 1)\n\tsignal.Notify(c2, os.Interrupt)\n\t\u003c-c2\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcschleiden%2Fgo-workflows","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcschleiden%2Fgo-workflows","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcschleiden%2Fgo-workflows/lists"}