{"id":17962394,"url":"https://github.com/grafov/service","last_synced_at":"2025-04-03T19:19:56.154Z","repository":{"id":57611563,"uuid":"104577955","full_name":"grafov/service","owner":"grafov","description":"The service tree :deciduous_tree: library for Go","archived":false,"fork":false,"pushed_at":"2017-10-31T05:24:18.000Z","size":16,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-09T07:24:22.409Z","etag":null,"topics":["dependency-tree","dynamic-configuration"],"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/grafov.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}},"created_at":"2017-09-23T15:30:32.000Z","updated_at":"2019-07-18T13:30:53.000Z","dependencies_parsed_at":"2022-09-03T08:30:45.564Z","dependency_job_id":null,"html_url":"https://github.com/grafov/service","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafov%2Fservice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafov%2Fservice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafov%2Fservice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafov%2Fservice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grafov","download_url":"https://codeload.github.com/grafov/service/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247061882,"owners_count":20877176,"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":["dependency-tree","dynamic-configuration"],"created_at":"2024-10-29T11:19:17.323Z","updated_at":"2025-04-03T19:19:56.135Z","avatar_url":"https://github.com/grafov.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dependency Tree for Services [![CircleCI](https://circleci.com/gh/grafov/service/tree/master.svg?style=svg)](https://circleci.com/gh/grafov/service/tree/master) [![GoDoc](https://godoc.org/github.com/grafov/service?status.svg)](https://godoc.org/github.com/grafov/service) \n\n_The package helps you separate constant running parts of code as\n\"services\" where one \"service\" could be dependent of others._\n\nYou could run parts of logic inside your application as independent\n\"services\", inside goroutines for example. \"Services\" in this context\nare parts of the code inside application that could be dependable each\nof another. The package helps track their dependencies and restart\nthem by chain.\n\n## Features\n\nThe package does:\n\n * Provides registry for declaring parts of code as \"services\"\n * Allow setup which other services depends on a declared service\n * Notifies other services when the service they depended failed for some reason\n\n## How it works\n\nIt is simplier explain in an example. Database client reads\nconfiguration from etcd (or another kind of remote storage) and\ninitializes the client instance.  When remote configuration changed\n(for example another database node added) you should reread it and\nreinitialize client. With `service` you could run it like this (it is\npseudocode where only `service` calls are real):\n\n```go\n\n// read config from remote storage\ngo func() {\n  for {\n    s := service.Provide(\"configurator\") // notifies the service registry that it provides \"configurator\"\n    c := remoteConfig.ReadConfiguration()\n    s.Ready(c) // indicate when service is ready and pushes `remoteConfig` object into service registry\n    \u003c-service.Failed() // waiting when the service failed or require reinitialization\n  }\n} \n\n// run database connector\ngo func() {\n   for {\n     s := service.Provide(\"dbclient\") // nofifies the service registry that it provides \"dbclient\"\n\t config := s.WaitFor(\"configurator\") // it will wait until \"configurator\" is ready and gets it\n     client := database.Connect(config.DBNodes)\n\t \u003c-service.Failed()\n   }\t \n} \n \n// Somewhere in the code:\nservice.Fail(\"configurator\") // it will \"fail\" the \"configurator\" service and requires it's reinitialization\n\n// It will fail also the depended services, \"dbclient\" in this\n// example. So \"dbclient\" also get \"fail\" signal in the place where\n// service.Failed() function waits and will pass to the next\n// initialization loop.\n\n// Anywhere in the code you can get current state of the object that provided by service.\n// For example: \ndbclient := service.Get(\"dbclient\").(database.ClientType) // Get() returns interface{} so type casting required\n```\n\nSee more docs [![GoDoc](https://godoc.org/github.com/grafov/service?status.svg)](https://godoc.org/github.com/grafov/service)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrafov%2Fservice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrafov%2Fservice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrafov%2Fservice/lists"}