{"id":13694473,"url":"https://github.com/autom8ter/machine","last_synced_at":"2025-04-05T13:07:35.895Z","repository":{"id":57546526,"uuid":"298359916","full_name":"autom8ter/machine","owner":"autom8ter","description":"Machine is a zero dependency library for highly concurrent Go applications. It is inspired by errgroup.Group with extra bells \u0026 whistles","archived":false,"fork":false,"pushed_at":"2023-03-01T15:58:59.000Z","size":287,"stargazers_count":365,"open_issues_count":0,"forks_count":17,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-29T12:07:27.219Z","etag":null,"topics":["concurrency","cron","go","goroutine","streaming"],"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/autom8ter.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-09-24T18:16:36.000Z","updated_at":"2025-02-13T19:06:19.000Z","dependencies_parsed_at":"2024-06-18T15:15:33.919Z","dependency_job_id":"149eb2f6-d047-4452-8662-e023310e1674","html_url":"https://github.com/autom8ter/machine","commit_stats":{"total_commits":133,"total_committers":4,"mean_commits":33.25,"dds":0.06766917293233088,"last_synced_commit":"4a46d83b5a7988b28d517fc9f8ab3b13b07db14b"},"previous_names":["autom8ter/sync"],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autom8ter%2Fmachine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autom8ter%2Fmachine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autom8ter%2Fmachine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autom8ter%2Fmachine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/autom8ter","download_url":"https://codeload.github.com/autom8ter/machine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247339158,"owners_count":20923014,"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":["concurrency","cron","go","goroutine","streaming"],"created_at":"2024-08-02T17:01:33.201Z","updated_at":"2025-04-05T13:07:35.862Z","avatar_url":"https://github.com/autom8ter.png","language":"Go","readme":"# Machine [![GoDoc](https://godoc.org/github.com/autom8ter/machine/v4?status.svg)](https://godoc.org/github.com/autom8ter/machine/v4)\n\n![concurrency](images/concurrency.jpg)\n\n\n`import \"github.com/autom8ter/machine/v4\"`\n\n[Machine](https://pkg.go.dev/github.com/autom8ter/machine/v4#Machine) is a zero dependency library for highly concurrent Go applications. \nIt is inspired by [`errgroup`](https://pkg.go.dev/golang.org/x/sync/errgroup)`.`[`Group`](https://pkg.go.dev/golang.org/x/sync/errgroup#Group) with extra bells \u0026 whistles:\n- In memory Publish Subscribe for asynchronously broadcasting \u0026 consuming messages in memory\n- Asynchronous worker groups similar to errgroup.Group\n- Throttled max active goroutine count\n- Asynchronous error handling(see `WithErrorHandler` to override default error handler)\n- Asynchronous cron jobs- `Cron()`\n\n## Use Cases\n\n[Machine](https://pkg.go.dev/github.com/autom8ter/machine#Machine) is meant to be completely agnostic and dependency free- its use cases are expected to be emergent.\nReally, it can be used **anywhere** goroutines are used. \n\nHighly concurrent and/or asynchronous applications include:\n\n- gRPC streaming servers\n\n- websocket servers\n\n- pubsub servers\n\n- reverse proxies\n\n- cron jobs\n\n- custom database/cache\n\n- ETL pipelines\n\n- log sink\n\n- filesystem walker\n\n- code generation\n\n\n```go\n// Machine is an interface for highly asynchronous Go applications\ntype Machine interface {\n// Publish synchronously publishes the Message\nPublish(ctx context.Context, msg Message)\n// Subscribe synchronously subscribes to messages on a given channel,  executing the given HandlerFunc UNTIL the context cancels OR false is returned by the HandlerFunc.\n// Glob matching IS supported for subscribing to multiple channels at once.\nSubscribe(ctx context.Context, channel string, handler MessageHandlerFunc, opts ...SubscriptionOpt)\n// Subscribers returns total number of subscribers to the given channel\nSubscribers(channel string) int\n// Channels returns the channel names that messages have been sent to\nChannels() []string\n// Go asynchronously executes the given Func\nGo(ctx context.Context, fn Func)\n// Cron asynchronously executes the given function on a timed interval UNTIL the context cancels OR false is returned by the CronFunc\nCron(ctx context.Context, interval time.Duration, fn CronFunc)\n// Current returns the number of active jobs that are running concurrently\nCurrent() int\n// Wait blocks until all active async functions(Go, Cron) exit\nWait()\n// Close blocks until all active routine's exit(calls Wait) then closes all active subscriptions\nClose()\n}\n```\n\n## Example\n\n```go\n        ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\n  \tdefer cancel()\n  \tvar (\n  \t\tm       = machine.New()\n  \t\tresults []string\n  \t\tmu      sync.RWMutex\n  \t)\n  \tdefer m.Close()\n  \n  \tm.Go(ctx, func(ctx context.Context) error {\n  \t\tm.Subscribe(ctx, \"accounting.*\", func(ctx context.Context, msg machine.Message) (bool, error) {\n  \t\t\tmu.Lock()\n  \t\t\tresults = append(results, fmt.Sprintf(\"(%s) received msg: %v\\n\", msg.Channel, msg.Body))\n  \t\t\tmu.Unlock()\n  \t\t\treturn true, nil\n  \t\t})\n  \t\treturn nil\n  \t})\n  \tm.Go(ctx, func(ctx context.Context) error {\n  \t\tm.Subscribe(ctx, \"engineering.*\", func(ctx context.Context, msg machine.Message) (bool, error) {\n  \t\t\tmu.Lock()\n  \t\t\tresults = append(results, fmt.Sprintf(\"(%s) received msg: %v\\n\", msg.Channel, msg.Body))\n  \t\t\tmu.Unlock()\n  \t\t\treturn true, nil\n  \t\t})\n  \t\treturn nil\n  \t})\n  \tm.Go(ctx, func(ctx context.Context) error {\n  \t\tm.Subscribe(ctx, \"human_resources.*\", func(ctx context.Context, msg machine.Message) (bool, error) {\n  \t\t\tmu.Lock()\n  \t\t\tresults = append(results, fmt.Sprintf(\"(%s) received msg: %v\\n\", msg.Channel, msg.Body))\n  \t\t\tmu.Unlock()\n  \t\t\treturn true, nil\n  \t\t})\n  \t\treturn nil\n  \t})\n  \tm.Go(ctx, func(ctx context.Context) error {\n  \t\tm.Subscribe(ctx, \"*\", func(ctx context.Context, msg machine.Message) (bool, error) {\n  \t\t\tmu.Lock()\n  \t\t\tresults = append(results, fmt.Sprintf(\"(%s) received msg: %v\\n\", msg.Channel, msg.Body))\n  \t\t\tmu.Unlock()\n  \t\t\treturn true, nil\n  \t\t})\n  \t\treturn nil\n  \t})\n  \t\u003c-time.After(1 * time.Second)\n  \tm.Publish(ctx, machine.Message{\n  \t\tChannel: \"human_resources.chat_room6\",\n  \t\tBody:    \"hello world human resources\",\n  \t})\n  \tm.Publish(ctx, machine.Message{\n  \t\tChannel: \"accounting.chat_room2\",\n  \t\tBody:    \"hello world accounting\",\n  \t})\n  \tm.Publish(ctx, machine.Message{\n  \t\tChannel: \"engineering.chat_room1\",\n  \t\tBody:    \"hello world engineering\",\n  \t})\n  \tm.Wait()\n  \tsort.Strings(results)\n  \tfor _, res := range results {\n  \t\tfmt.Print(res)\n  \t}\n  \t// Output:\n  \t//(accounting.chat_room2) received msg: hello world accounting\n  \t//(accounting.chat_room2) received msg: hello world accounting\n  \t//(engineering.chat_room1) received msg: hello world engineering\n  \t//(engineering.chat_room1) received msg: hello world engineering\n  \t//(human_resources.chat_room6) received msg: hello world human resources\n  \t//(human_resources.chat_room6) received msg: hello world human resources\n```\n\n### Extended Examples\n\nAll examples are \u003c 500 lines of code(excluding code generation)\n\n- [gRPC Bidirectional Chat Stream Server](examples/README.md#grpc-bidirectional-chat-server)\n- [Concurrent Cron Job Server](examples/README.md#concurrent-cron-server)\n- [TCP Reverse Proxy](examples/README.md#tcp-reverse-proxy)\n\n","funding_links":[],"categories":["开源类库","Open source library"],"sub_categories":["协程/线程","Coroutine/Thread"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautom8ter%2Fmachine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fautom8ter%2Fmachine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautom8ter%2Fmachine/lists"}