{"id":15643055,"url":"https://github.com/code-hex/golet","last_synced_at":"2025-04-30T10:10:59.993Z","repository":{"id":71653928,"uuid":"80517294","full_name":"Code-Hex/golet","owner":"Code-Hex","description":"*.go file as a mini supervisor","archived":false,"fork":false,"pushed_at":"2018-05-30T06:05:22.000Z","size":44,"stargazers_count":60,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-30T15:07:04.178Z","etag":null,"topics":["go","golang","golang-library","golet","proclet","supervisor"],"latest_commit_sha":null,"homepage":"","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/Code-Hex.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":"2017-01-31T12:12:47.000Z","updated_at":"2022-09-22T05:26:33.000Z","dependencies_parsed_at":"2023-05-13T08:30:20.467Z","dependency_job_id":null,"html_url":"https://github.com/Code-Hex/golet","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/Code-Hex%2Fgolet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Code-Hex%2Fgolet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Code-Hex%2Fgolet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Code-Hex%2Fgolet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Code-Hex","download_url":"https://codeload.github.com/Code-Hex/golet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251683355,"owners_count":21626953,"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":["go","golang","golang-library","golet","proclet","supervisor"],"created_at":"2024-10-03T11:58:45.041Z","updated_at":"2025-04-30T10:10:59.940Z","avatar_url":"https://github.com/Code-Hex.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"Golet\n=====\n[![Build Status](https://travis-ci.org/Code-Hex/golet.svg?branch=master)](https://travis-ci.org/Code-Hex/golet) [![GoDoc](https://godoc.org/github.com/Code-Hex/golet?status.svg)](https://godoc.org/github.com/Code-Hex/golet) [![Go Report Card](https://goreportcard.com/badge/github.com/Code-Hex/golet)](https://goreportcard.com/report/github.com/Code-Hex/golet)\n\nGolet can manage many services with goroutine from one golang program. It's like a supervisor.  \nIt supports go version 1.7 or higher. Golet is based on the idea of [Proclet](https://metacpan.org/pod/Proclet).  \nProclet is a great module in Perl.\n\n# Synopsis\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"net/http\"\n    \"strings\"\n    \"syscall\"\n    \"time\"\n\n    \"github.com/Code-Hex/golet\"\n)\n\nfunc main() {\n    p := golet.New(context.Background())\n    p.EnableColor()\n    // Execution interval\n    p.SetInterval(time.Second * 1)\n\n    p.Env(map[string]string{\n        \"NAME\":  \"codehex\",\n        \"VALUE\": \"121\",\n    })\n\n    p.Add(\n        golet.Service{\n            Exec: \"plackup --port $PORT\",\n            Tag:  \"plack\",\n        },\n        golet.Service{\n            Exec:   \"echo 'This is cron!!'\",\n            Every:  \"30 * * * * *\",\n            Worker: 2,\n            Tag:    \"cron\",\n        },\n    )\n\n    p.Add(golet.Service{\n        Code: func(ctx context.Context) error {\n            c := ctx.(*golet.Context)\n            c.Println(\"Hello golet!! Port:\", c.Port())\n            mux := http.NewServeMux()\n            mux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n                fmt.Fprintf(w, \"Hello, World\")\n                buf := strings.NewReader(\"This is log string\\nNew line1\\nNew line2\\nNew line3\\n\")\n                c.Copy(buf)\n            })\n            go http.ListenAndServe(c.ServePort(), mux)\n            for {\n                select {\n                // You can notify signal received.\n                case \u003c-c.Recv():\n                    signal, err := c.Signal()\n                    if err != nil {\n                        c.Println(err.Error())\n                        return err\n                    }\n                    switch signal {\n                    case syscall.SIGTERM, syscall.SIGHUP, syscall.SIGINT:\n                        c.Println(signal.String())\n                        return nil\n                    }\n                case \u003c-ctx.Done():\n                    return nil\n                }\n            }\n        },\n        Worker: 3,\n    })\n\n    p.Run()\n}\n```\n\nSee more [example](https://github.com/Code-Hex/golet/tree/master/eg).\n\n# Logging\n\nIn case to run code of synopsis. I send INT signal to golet.\n![Logging](https://user-images.githubusercontent.com/6500104/37191403-ac145616-23a2-11e8-9edd-d54175450b84.gif)\n\n# Usage\n## Basic\nMake sure to generate a struct from the `New(context.Context)` function.  \n```go\np := golet.New(context.Background())\n```\nNext, We can add the service using the `Service` struct.  \n`Add(services ...Service) error` method is also possible to pass multiple `Service` struct arguments.\n```go\np.Add(\n    golet.Service{\n        // Replace $PORT and automatically assigned port number.\n        Exec: \"plackup --port $PORT\",\n        Tag:  \"plack\", // Keyword for log.\n    },\n    golet.Service{\n        Exec:   \"echo 'This is cron!!'\",\n        // Crontab like format. \n        Every:  \"30 * * * * *\", // See https://godoc.org/github.com/robfig/cron#hdr-CRON_Expression_Format\n        Worker: 2,              // Number of goroutine. The maximum number of workers is 100.\n        Tag:    \"cron\",\n    },\n)\n```\nFinally, You can run many services. use `Run() error`\n```go\np.Run()\n```\n\n## Option\nThe default option is like this.\n\n```\ninterval:   0\ncolor:      false\nlogger:     colorable.NewColorableStderr()\nlogWorker:  true\nexecNotice: true\ncancelSignal: -1\n```\n\nBy using the [go-colorable](https://github.com/mattn/go-colorable), colored output is also compatible with windows.  \nYou can change these options by using the following method.\n\n```go\n// SetInterval can specify the interval at which the command is executed.\nfunc (c *config) SetInterval(t time.Duration) { c.interval = t }\n\n// EnableColor can output colored log.\nfunc (c *config) EnableColor() { c.color = true }\n\n// SetLogger can specify the *os.File\n// for example in https://github.com/lestrrat/go-file-rotatelogs\n/*\n      logf, _ := rotatelogs.New(\n          \"/path/to/access_log.%Y%m%d%H%M\",\n          rotatelogs.WithLinkName(\"/path/to/access_log\"),\n          rotatelogs.WithMaxAge(24 * time.Hour),\n          rotatelogs.WithRotationTime(time.Hour),\n      )\n\n      golet.New(context.Background()).SetLogger(logf)\n*/\nfunc (c *config) SetLogger(f io.Writer) { c.logger = f }\n\n// DisableLogger is prevent to output log\nfunc (c *config) DisableLogger() { c.logWorker = false }\n\n// DisableExecNotice is disable execute notifications\nfunc (c *config) DisableExecNotice() { c.execNotice = false }\n\n// SetCtxCancelSignal can specify the signal to send processes when context cancel.\n// If you do not set, golet will not send the signal when context cancel.\nfunc (c *config) SetCtxCancelSignal(signal syscall.Signal) { c.cancelSignal = signal }\n```\n\n## Environment variables\n\nYou can use temporary environment variables in golet program.\n\n```go\np.Env(map[string]string{\n    \"NAME\":  \"codehex\",\n    \"VALUE\": \"121\",\n})\n```\n\nand, If you execute service as command, you can get also `PORT` env variable.\n\n## golet.Context\n\nSee, https://godoc.org/github.com/Code-Hex/golet#Context\n\n`golet.Context` can be to `context.Context`, `io.Writer` also `io.Closer`.\n\nSo, you can try to write strange code like this.\n\n```go\ngolet.Service{\n    Code: func(ctx context.Context) error {\n        // die program\n        c := ctx.(*golet.Context)\n        fmt.Fprintf(c, \"Hello, World!!\\n\")\n        c.Printf(\"Hello, Port: %d\\n\", c.Port())\n        time.Sleep(time.Second * 1)\n        select {\n        case \u003c-c.Recv():\n            signal, err := c.Signal()\n            if err != nil {\n                c.Println(err.Error())\n                return err\n            }\n            switch signal {\n            case syscall.SIGTERM, syscall.SIGHUP:\n                c.Println(signal.String())\n                return fmt.Errorf(\"die message\")\n            case syscall.SIGINT:\n                return nil\n            }\n            return nil\n        }\n    },\n}\n```\n\n# Installation\n\n    go get -u github.com/Code-Hex/golet\n\n# Contribution\n\n1. Fork [https://github.com/Code-Hex/golet/fork](https://github.com/Code-Hex/golet/fork)\n2. Commit your changes\n3. Create a new Pull Request\n\nI'm waiting for a lot of PR.\n\n# Future\n\n- [ ] Create like [foreman](https://github.com/ddollar/foreman) command\n- [ ] Support better windows\n- [ ] Write a test for signals for some distribution\n\n# Author\n\n[codehex](https://twitter.com/CodeHex)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-hex%2Fgolet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcode-hex%2Fgolet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-hex%2Fgolet/lists"}