{"id":24083360,"url":"https://github.com/mitranim/ded","last_synced_at":"2025-08-04T10:35:19.470Z","repository":{"id":82131988,"uuid":"418386339","full_name":"mitranim/ded","owner":"mitranim","description":"Simple tool for deduplicating concurrent background operations in Go, with limited-time caching.","archived":false,"fork":false,"pushed_at":"2021-10-18T07:35:01.000Z","size":9,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-25T09:02:41.262Z","etag":null,"topics":["cache","go","golang"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/mitranim/ded","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mitranim.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2021-10-18T07:14:02.000Z","updated_at":"2023-08-01T09:09:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"41d30f4c-1911-428a-b239-0062e3903201","html_url":"https://github.com/mitranim/ded","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mitranim/ded","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fded","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fded/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fded/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fded/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitranim","download_url":"https://codeload.github.com/mitranim/ded/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fded/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261841825,"owners_count":23217910,"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":["cache","go","golang"],"created_at":"2025-01-09T23:56:29.011Z","updated_at":"2025-06-25T09:03:57.361Z","avatar_url":"https://github.com/mitranim.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Overview\n\n`ded`: short for \"dedup\". Experimental tool for deduplicating concurrent background operations in Go, with support for limited-time caching.\n\nAPI docs: https://pkg.go.dev/github.com/mitranim/ded.\n\nMain primitive is `Mem` (see docs). Features:\n\n  * Stores arbitrary value and its timestamp.\n  * Provides concurrent read access, using `sync.RWMutex`.\n  * Readers can independently decide if the value is expired.\n  * When the value is expired, a reader gets upgraded to a writer, producing a new value.\n  * Readers don't wait for each other.\n  * Readers wait for the writer, if any.\n  * There is little overhead.\n\nThe current design uses blocking via `sync.RWMutex`, without support for channels or context. The main reason is efficiency. To support channels, each newly-cached value would have to be wrapped in a new \"future\" with a new channel, and work would have to be done on a new background goroutine. That's a lot of overhead for a single value. The current design is much more efficient, with no mandatory allocations per value.\n\n## Usage\n\nThe recommended way is type-oriented, by embedding relevant types in your own. All `ded` types are usable when zero-initialized, and don't require constructors.\n\nMany `ded` types are zero-sized, and can be embedded in other types to provide additional methods at no memory cost, _when fields are in the right order_. Beware of the padding gotcha: https://dave.cheney.net/2015/10/09/padding-is-hard. Zero-sized fields should come first.\n\n```golang\npackage ded_test\n\nimport (\n  \"fmt\"\n\n  \"github.com/mitranim/ded\"\n)\n\nfunc ExampleDedup() {\n  var worker Worker\n  first := worker.Fetch()\n  second := worker.Fetch()\n\n  // The value is reused without calling `(*Worker).Get` again, keeping the old\n  // timestamp, because it's not expired yet (a minute hasn't passed).\n  fmt.Println(first == second)\n  fmt.Println(first.Get())\n\n  // Output:\n  // true\n  // some value\n}\n\n// The fields `ExpireMinute` and `NowTimer` are zero-sized and only provide us\n// with methods required for `Dedup`. Only `Mem` has an actual memory cost.\ntype Worker struct {\n  ded.ExpireMinute\n  ded.NowTimer\n  ded.Mem\n}\n\n// May reuse the cached value.\nfunc (self *Worker) Fetch() ded.Timed { return ded.Dedup(self) }\n\n// Could be slow, expensive work. Not always called.\nfunc (self *Worker) Get() interface{} { return `some value` }\n```\n\n## License\n\nhttps://unlicense.org\n\n## Misc\n\nI'm receptive to suggestions. If this library _almost_ satisfies you but needs changes, open an issue or chat me up. Contacts: https://mitranim.com/#contacts\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitranim%2Fded","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitranim%2Fded","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitranim%2Fded/lists"}