{"id":20723316,"url":"https://github.com/jeamon/gorsn","last_synced_at":"2026-05-27T18:32:38.744Z","repository":{"id":195341793,"uuid":"692571968","full_name":"jeamon/gorsn","owner":"jeamon","description":"simple and high-concurent and scalable go library for monitoring a folder tree and notifying on any sub-content changes.","archived":false,"fork":false,"pushed_at":"2023-11-13T00:56:46.000Z","size":53,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-11T08:29:59.438Z","etag":null,"topics":["asynchronous-tasks","event-driven","golang","goroutines-channels","notification-system"],"latest_commit_sha":null,"homepage":"https://learn.cloudmentor-scale.com","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/jeamon.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-09-16T22:30:23.000Z","updated_at":"2024-05-20T10:29:36.000Z","dependencies_parsed_at":"2023-09-17T14:55:14.860Z","dependency_job_id":"356057c9-c8d9-4d81-8d92-8ee99198cb60","html_url":"https://github.com/jeamon/gorsn","commit_stats":null,"previous_names":["jeamon/gorsn"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jeamon/gorsn","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeamon%2Fgorsn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeamon%2Fgorsn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeamon%2Fgorsn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeamon%2Fgorsn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeamon","download_url":"https://codeload.github.com/jeamon/gorsn/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeamon%2Fgorsn/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33579665,"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-05-27T02:00:06.184Z","response_time":53,"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":["asynchronous-tasks","event-driven","golang","goroutines-channels","notification-system"],"created_at":"2024-11-17T04:08:16.994Z","updated_at":"2026-05-27T18:32:38.719Z","avatar_url":"https://github.com/jeamon.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gorsn\n\n[![godoc](https://godoc.org/github.com/jeamon/gorsn?status.svg)](https://godoc.org/github.com/jeamon/gorsn)\n[![Go Report Card](https://goreportcard.com/badge/github.com/jeamon/gorsn)](https://goreportcard.com/report/github.com/jeamon/gorsn)\n![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/jeamon/gorsn)\n[![MIT License](https://img.shields.io/github/license/jeamon/gorsn)](https://github.com/jeamon/gorsn/blob/main/LICENSE)\n\n**`gorsn`** means *Go Resource Scan Notifier*. This is a simple \u0026 high-concurrent \u0026 options-rich cross-platform go-based library to periodically scan a folder and all its sub-content to get notified at any changes. Options are thread-safe and can be modified even during the program execution. The options allow for example to scale the number of workers/goroutines and to specify which kind of events we are interested in.\n\n## Features\n\nA successful scan-notifier provided by `gorsn.New` method is an interface with below actions.\n\n| Action | Description |\n|:------ | :-------------------------------------- |\n| **`Queue() \u003c-chan Event`** | provides a read-only channel to listen events from |\n| **`Start(context.Context) error`** | starts the scanner and events notifications routines |\n| **`Stop() error`** | stops the scanner and events notifications routines |\n| **`Pause() error`** | triggers to scanner to pause to avoid emitting events |\n| **`Resume() error`** | restarts the scanner and notifier after being paused |\n| **`IsRunning() bool`** | informs wether the scanner notifier is stopped or not |\n| **`Flush()`** | clears latest changes infos of files under monitoring |\n\n## Installation\n\nJust import the `gorsn` library as external package to start using it into your project. There are some examples into the examples folder to learn more. \n\n**[Step 1] -** Download the package\n\n```shell\n$ go get github.com/jeamon/gorsn\n```\n\n\n**[Step 2] -** Import the package into your project\n\n```shell\n$ import \"github.com/jeamon/gorsn\"\n```\n\n\n**[Step 3] -** Optional: Clone the library to run some examples\n\n```shell\n$ git clone https://github.com/jeamon/gorsn.git\n$ cd gorsn\n$ go run examples/default-options/example.go\n$ go run examples/custom-options/example.go\n```\n\n## Usage\n\n* **default options / settings**\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/jeamon/gorsn\"\n)\n\nfunc main() {\n\t// step 1. define a path to a valid folder.\n\troot, err := os.Getwd() // lets use this package folder\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// step 2. use default options.\n\tvar opts gorsn.Options\n\n\t// step 3. get an instance.\n\tsn, err := gorsn.New(root, \u0026opts)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// we can always change the settings at anytime in the program.\n\topts.SetMaxWorkers(5).SetScanInterval(100 * time.Millisecond)\n\n\t// [optional] stop the scan notifier on CTRL+C.\n\tgo func() {\n\t\tsigChan := make(chan os.Signal, 1)\n\t\tsignal.Notify(sigChan, syscall.SIGINT, syscall.SIGQUIT,\n\t\t\tsyscall.SIGTERM, syscall.SIGHUP, os.Interrupt)\n\n\t\t\u003c-sigChan\n\t\tsignal.Stop(sigChan)\n\t\tsn.Stop()\n\t}()\n\n\t// step 4. asynchronously receive events from the queue.\n\tgo func() {\n\t\tfor event := range sn.Queue() {\n\t\t\tlog.Printf(\"received %q %s %s %v\\n\", event.Path, event.Type, event.Name, event.Error)\n\t\t}\n\t}()\n\n\tdone := make(chan struct{})\n\t// step 5. start the scan notifier on the defined path.\n\t// lets run it as goroutine to bypass the blocking behavior.\n\tgo func() {\n\t\terr = sn.Start(context.Background())\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tdone \u003c- struct{}{}\n\t}()\n\n\t// lets change the settings on the fly.\n\topts.SetMaxWorkers(10).\n\t\tSetScanInterval(500 * time.Millisecond).\n\t\tSetIgnoreNoChangeEvent(false)\n\n\t// wait the runner to exit\n\t\u003c-done\n}\n```\n\n* **custom options / settings**\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"os\"\n\t\"os/signal\"\n\t\"regexp\"\n\t\"syscall\"\n\n\t\"github.com/jeamon/gorsn\"\n)\n\nfunc main() {\n\t// step 1. define a path to a valid folder.\n\t// lets use this current folder so you can\n\t// observe any changes into your codebase.\n\troot := \"./\"\n\n\t// step 2. set some options.\n\texcludeRule := regexp.MustCompile(`.*(\\.git).*`)\n\t// exclude `.git` folder. No include rule.\n\topts := gorsn.RegexOpts(excludeRule, nil).\n\t\t// 5 events can wait into the queue.\n\t\tSetQueueSize(5).\n\t\t// 2 goroutines to build \u0026 emit events.\n\t\tSetMaxWorkers(2).\n\t\t// 0 sec - immediate, so no delay to scan.\n\t\tSetScanInterval(0)\n\t\t// others options keep their default values.\n\n\t// step 3. get an instance based on above settings.\n\tsn, err := gorsn.New(root, opts)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// [optional] stop the scan notifier on CTRL+C.\n\tgo func() {\n\t\tsigChan := make(chan os.Signal, 1)\n\t\tsignal.Notify(sigChan, syscall.SIGINT, syscall.SIGQUIT,\n\t\t\tsyscall.SIGTERM, syscall.SIGHUP, os.Interrupt)\n\n\t\t\u003c-sigChan\n\t\tsignal.Stop(sigChan)\n\t\tsn.Stop()\n\t}()\n\n\t// step 4. asynchronously receive events from the queue.\n\tgo func() {\n\t\tfor event := range sn.Queue() {\n\t\t\tlog.Printf(\"received %q %s %s %v\\n\", event.Path, event.Type, event.Name, event.Error)\n\t\t}\n\t}()\n\n\t// step 5. start the scan notifier on the defined path.\n\terr = sn.Start(context.Background()) // blocks unless it fails or until stopped.\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n```\n\n## Contact\n\nFeel free to [reach out to me](https://blog.cloudmentor-scale.com/contact) before any action. Feel free to connect on [Twitter](https://twitter.com/jerome_amon) or [linkedin](https://www.linkedin.com/in/jeromeamon/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeamon%2Fgorsn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeamon%2Fgorsn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeamon%2Fgorsn/lists"}