{"id":19437017,"url":"https://github.com/netologist/harness","last_synced_at":"2026-06-13T02:07:20.056Z","repository":{"id":179054907,"uuid":"662663576","full_name":"netologist/harness","owner":"netologist","description":"Harness is a graceful shutdown handler for Go projects","archived":false,"fork":false,"pushed_at":"2023-07-05T20:52:21.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-25T07:13:49.849Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/netologist.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":"2023-07-05T16:00:12.000Z","updated_at":"2023-07-05T20:53:51.000Z","dependencies_parsed_at":"2023-07-07T11:45:32.992Z","dependency_job_id":null,"html_url":"https://github.com/netologist/harness","commit_stats":null,"previous_names":["netologist/harness"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/netologist/harness","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netologist%2Fharness","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netologist%2Fharness/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netologist%2Fharness/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netologist%2Fharness/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/netologist","download_url":"https://codeload.github.com/netologist/harness/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netologist%2Fharness/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34269382,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"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":[],"created_at":"2024-11-10T15:13:20.051Z","updated_at":"2026-06-13T02:07:20.041Z","avatar_url":"https://github.com/netologist.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Harness Package\nThe `harness` package provides functionality to manage and handle multiple runners concurrently. It allows graceful shutdown of these runners in response to termination signals or cancellation events.\n\n### Usage\nTo use the `harness` package, follow the steps below:\n\n1. Import the `harness` package:\n\n```go\nimport \"github.com/netologist/harness\"\n```\n2. Create a new handler using the New function, passing one or more Runner instances:\n\n```go\nrunners := []harness.Runner{\n    // Initialize your runners here\n}\n\nhandler := harness.New(runners...)\n```\n\n3. Start the handler by calling the Start method, passing a context:\n\n```go\nctx := context.Background()\nhandler.Start(ctx)\n```\n\n4. Graceful shutdown:\n\n   - If a termination signal (e.g., SIGINT or SIGTERM) is received, the handler will initiate a graceful shutdown by calling the Shutdown method on each runner.\n   - If cancellation is triggered on the provided context, the handler will also initiate a graceful shutdown.\n\n### Example Use\nHere's an example use case to illustrate how the `harness` package can be used:\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"github.com/netologist/harness\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n)\n\ntype TestRunner struct {\n}\nfunc (r *TestRunner) Name() string {\n\treturn \"test runner\"\n}\nfunc (r *TestRunner) Run(ctx context.Context) error {\n\treturn nil\n}\nfunc (r *TestRunner) Shutdown(exitType harness.ExitType) {\n\tlog.Printf(\"NAME: '%s' - EXIT_TYPE: %d\", r.Name(), exitType)\n}\n\nfunc (r *TestRunner) OnError(err error) {\n\tlog.Printf(\"NAME: '%s' - ERROR: %+v\", r.Name(), err)\n}\n\nfunc main() {\n    ctx := context.Background()\n\n\t// Create a new TestRunner instance\n\ttestRunner := \u0026TestRunner{\n\t\t// Initialize your runner\n\t\t// ...\n\t}\n\n\t// Create the handler with the runner\n\tharness.New(\n\t\tharness.Register(testRunner),\n\t\tharness.OnError(func(err error) {\n\t\t\tlog.Printf(\"error: %+v\", err)\n\t\t}),\n\t\tharness.OnCompleted(func() {\n\t\t\tlog.Printf(\"successfully completed\")\n\t\t}),\n\t\tharnes.SetSignal(os.Interrupt, syscall.SIGINT, syscall.SIGTERM), // if you want customise signals\n\t).Start(context.Background())\n}\n```\n\nIn this example, we create a custom TestRunner struct that implements the Runner interface required by the `harness` package. We then create a handler with the testRunner instance and start it in a separate goroutine. We handle termination signals and cancellation requests, triggering the corresponding actions to gracefully shut down the runners. Finally, we wait for the handler to complete and perform any necessary cleanup or exit operations.\n\nFeel free to customize the example and adapt it to your specific use case.\n\nPlease note that this is a simplified example, and you will need to implement the Runner interface methods and define your custom logic within the TestRunner struct based on your requirements.\n\nI hope this helps! Let me know if you have any further questions.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetologist%2Fharness","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnetologist%2Fharness","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetologist%2Fharness/lists"}