{"id":23074942,"url":"https://github.com/invisionapp/go-master","last_synced_at":"2025-08-15T17:31:27.665Z","repository":{"id":55005419,"uuid":"127919144","full_name":"InVisionApp/go-master","owner":"InVisionApp","description":"Master selection mechanism for clustered services","archived":true,"fork":false,"pushed_at":"2024-12-23T18:07:46.000Z","size":162,"stargazers_count":7,"open_issues_count":0,"forks_count":5,"subscribers_count":94,"default_branch":"master","last_synced_at":"2025-02-19T22:22:51.928Z","etag":null,"topics":["clustered","golang","lock","mongodb","mysql","opensource"],"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/InVisionApp.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":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-03T14:15:47.000Z","updated_at":"2024-12-23T18:08:16.000Z","dependencies_parsed_at":"2023-12-21T00:55:55.363Z","dependency_job_id":"26e512ed-9c43-486a-a60b-5147677ba19e","html_url":"https://github.com/InVisionApp/go-master","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/InVisionApp/go-master","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InVisionApp%2Fgo-master","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InVisionApp%2Fgo-master/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InVisionApp%2Fgo-master/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InVisionApp%2Fgo-master/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/InVisionApp","download_url":"https://codeload.github.com/InVisionApp/go-master/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InVisionApp%2Fgo-master/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270603767,"owners_count":24614562,"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-15T02:00:12.559Z","response_time":110,"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":["clustered","golang","lock","mongodb","mysql","opensource"],"created_at":"2024-12-16T08:32:00.344Z","updated_at":"2025-08-15T17:31:27.657Z","avatar_url":"https://github.com/InVisionApp.png","language":"Go","readme":"| :warning: This project is no longer actively supported.\n| ---\n\n[![CircleCI](https://circleci.com/gh/InVisionApp/go-master.svg?style=svg)](https://circleci.com/gh/InVisionApp/go-master)\n[![codecov](https://codecov.io/gh/InVisionApp/go-master/branch/master/graph/badge.svg?token=eWHfq11AM9)](https://codecov.io/gh/InVisionApp/go-master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/InVisionApp/go-master)](https://goreportcard.com/report/github.com/InVisionApp/go-master)\n[![Godocs](https://img.shields.io/badge/golang-documentation-blue.svg)](https://godoc.org/github.com/InVisionApp/go-master)\n\n\u003cimg align=\"right\" src=\"images/go-master.svg\" width=\"200\"\u003e\n\n# go-master\nA simple library for enabling master selection using flexible backends.\n\nWith the proliferation of micro-services, there are often cases where a clustered service that already has a shared backend resource will need to implement master selection. This library provides a simple way to enable master selection in a clustered service with a shared backend. It also includes a set of swappable lock implementations for common backends.  \n\nUnlike more complex leader election mechanisms based on consensus algorithms, this simply uses a lock on a shared resource. In an environment of micro-services running in a docker orchestration platform it can often be difficult to obtain direct communication channels between all the nodes of a service, and many services will already require a backend database to store shared state. This master selection library is designed to cover those use cases.\n\n## Example Use Cases\n**Database migrations** - In-app database migrations can be difficult to run in a clustered application. Use go-master to pick a master node and only run migrations from the master.\n\n**One-time tasks** - Ensure something is only run by one node in a clustered service. For example sending a email that should only be sent once.\n\n## Master Selection\n\u003cimg align=\"right\" src=\"images/master_process.svg\" width=\"300\"\u003e\nThere is a single master at all times. The master is chosen using the master lock backend. All nodes will attempt to become a master, but only one will succeed. The node chosen to be the master will write a heartbeat to the master lock while it is healthy and executing its duties. \n\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n\n## Start and Stop Hooks\nCustom start and stop hooks can be used to define what happens when a node becomes a master or is no longer a master. When a node becomes a master, the provided start hook function will be executed as a way of notifying your code that the current node is now the master. Similarly, when a node is no longer a master, the stop hook is called. The master selection mechanism does not block on these hook functions nor does it receive an error. If a critical error occurs in your start hook such that this node should not continue as the master, use the `Stop()` method to stop the node from continuing as a master.\n\n## Supported Backends\nThis library comes with support for a set of backend databases that are commonly used. All backend implementations can be found in `go-master/backend`, each under their own packages.\n\nCurrently supported: \n- MongoDB\n- MySQL\n\n### Example MySQL backend usage\n```go\n\t\"github.com/InVisionApp/go-master\"\n\t\"github.com/InVisionApp/go-master/backend/mysql\"\n\n\tmysqlBackend := mysql.NewMySQLBackend(\u0026mysql.MySQLBackendConfig{\n\t\tUser:     \"user\",\n\t\tPassword: \"pass\",\n\t\tHost:     \"localhost\",\n\t\tPort:     3306,\n\t\tDBName:   \"gomaster\",\n\t})\n\n\tif err := mysqlBackend.Connect(); err != nil {\n\t\tlogger.Errorf(\"Unable to connect to MySQL: %v\", err)\n\t\treturn err\n\t}\n\t\n\tm := master.New(\u0026master.MasterConfig{\n\t\tMasterLock: mysqlBackend,\n\t\tLogger:     logger,\n\t})\n\n\tif err := m.Start(); err != nil {\n\t\tlogger.Errorf(\"Unable to start go-master: %v\", err)\n\t\treturn err\n\t}\n\n```\n\n---\n\n#### \\[Credit\\]\nThe go-master gopher image by [talpert](https://github.com/talpert)  \nOriginal artwork designed by Renée French\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finvisionapp%2Fgo-master","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finvisionapp%2Fgo-master","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finvisionapp%2Fgo-master/lists"}