{"id":17955679,"url":"https://github.com/smallnest/glean","last_synced_at":"2025-10-29T00:38:10.575Z","repository":{"id":50393804,"uuid":"102844207","full_name":"smallnest/glean","owner":"smallnest","description":"hotfix for go applications via plugin, supports Linux and MacOS","archived":false,"fork":false,"pushed_at":"2018-02-28T03:28:11.000Z","size":31,"stargazers_count":134,"open_issues_count":1,"forks_count":6,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-06-23T18:08:08.967Z","etag":null,"topics":["hot-reload","hotfix","hotfix-update","plugin","plugins"],"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/smallnest.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-08T09:27:56.000Z","updated_at":"2025-05-12T15:57:32.000Z","dependencies_parsed_at":"2022-09-19T19:50:36.975Z","dependency_job_id":null,"html_url":"https://github.com/smallnest/glean","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/smallnest/glean","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallnest%2Fglean","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallnest%2Fglean/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallnest%2Fglean/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallnest%2Fglean/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smallnest","download_url":"https://codeload.github.com/smallnest/glean/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallnest%2Fglean/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279003389,"owners_count":26083579,"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-10-10T02:00:06.843Z","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":["hot-reload","hotfix","hotfix-update","plugin","plugins"],"created_at":"2024-10-29T10:31:43.606Z","updated_at":"2025-10-10T09:06:31.172Z","avatar_url":"https://github.com/smallnest.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Glean\n\n*A go plugin framework that can reload variables and functions from plugins automatically.*\n\n\n[![License](https://img.shields.io/:license-apache-2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![GoDoc](https://godoc.org/github.com/smallnest/glean?status.png)](http://godoc.org/github.com/smallnest/glean)  [![travis](https://travis-ci.org/smallnest/glean.svg?branch=master)](https://travis-ci.org/smallnest/glean) [![Go Report Card](https://goreportcard.com/badge/github.com/smallnest/glean)](https://goreportcard.com/report/github.com/smallnest/glean) \n\n\n## Installation\n\n```sh\ngo get -u github.com/smallnest/glean\n```\n\n## Feature\n\n- load symbol and you don't worry about errors\n- load/reload exported variables and funtions from plugins\n- watch plugins' changes and reload pointer of variables and function in applications\n\n**Notice** glean only can reload functions or variables that can be addresses.\n\n## Examples\n\nsee [Examples](https://github.com/smallnest/glean/tree/master/_example)\n\nLet's look the httpserver example to learn how to use glean.\n\n### httpserver\n\nhttpserver is a very very simple http server.\n\nA simple http server is just like this:\n\n```go\nvar FooHandler = func(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprint(w, \"Hello, world\")\n}\n\nhttp.Handle(\"/foo\", fooHandler)\n\nlog.Fatal(http.ListenAndServe(\":9988\", nil))\n```\n\nOur goal is to replace fooHandler with latest code dynamically (hot fix).\n\n```go\nvar FooHandler = func(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprint(w, \"Hello, gp\")\n}\n```\n\nNo need to restart this server.\n\n**step1:** build the two plugin\n\nenter `_example/httpserver/plugins/plugin1` and `_example/httpserver/plugins/plugin2`, and run the `build.sh` to generate the so file.\n\nCurrently plugin supports linux and MacOS.\n\n**step2:** modify the server implementation\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/smallnest/glean\"\n)\n\nfunc main() {\n\tg := glean.New(\"plugin.json\")\n\terr := g.LoadConfig()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tvar fooHandler func(w http.ResponseWriter, r *http.Request)\n\n\terr = g.ReloadAndWatch(\"FooHandlerID\", \u0026fooHandler)\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\thttp.HandleFunc(\"/foo\", WarpFuncPtr(\u0026fooHandler))\n\n\tlog.Fatal(http.ListenAndServe(\":9988\", nil))\n}\n\nfunc WarpFuncPtr(fn *func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\t(*fn)(w, r)\n\t}\n}\n```\n\nFirstly create the Glean instance and load config from given file.\nAnd then use `ReloadAndWatch` to load fooHandler and begin to watch its changes.\nAt last use WarpFuncPtr to wrap fooHandler as a HandleFunc.\n\nRun `go run main.go` to start this server, use a browser to visit \"http://locakhost:9988/foo\" and you will see `hello world`\n\nChange the config file `plugin.json` and replace `\"file\": \"plugins/plugin1/plugin1.so\"` with :\n\n```\n\"file\": \"plugins/plugin2/plugin2.so\",\n```\n\nBrowser the prior location and you will see `hello gp`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmallnest%2Fglean","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmallnest%2Fglean","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmallnest%2Fglean/lists"}