{"id":16719247,"url":"https://github.com/reiddraper/knockbox","last_synced_at":"2025-03-17T01:31:21.435Z","repository":{"id":1826913,"uuid":"2751200","full_name":"reiddraper/knockbox","owner":"reiddraper","description":null,"archived":false,"fork":false,"pushed_at":"2012-03-11T22:54:59.000Z","size":191,"stargazers_count":141,"open_issues_count":2,"forks_count":4,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-11T11:51:42.901Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"poole/hyde","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reiddraper.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":"2011-11-10T19:56:07.000Z","updated_at":"2024-05-15T07:22:16.000Z","dependencies_parsed_at":"2022-08-20T09:40:27.758Z","dependency_job_id":null,"html_url":"https://github.com/reiddraper/knockbox","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/reiddraper%2Fknockbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reiddraper%2Fknockbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reiddraper%2Fknockbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reiddraper%2Fknockbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reiddraper","download_url":"https://codeload.github.com/reiddraper/knockbox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243835959,"owners_count":20355613,"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":[],"created_at":"2024-10-12T21:41:11.734Z","updated_at":"2025-03-17T01:31:21.033Z","avatar_url":"https://github.com/reiddraper.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Knockbox\n\n## Build status\n\n[![Build Status](https://secure.travis-ci.org/reiddraper/knockbox.png)](http://travis-ci.org/reiddraper/knockbox)\n\nknockbox is an eventual-consistency toolbox for Clojure,\nand eventually the JVM in general. It's inspired by\n[statebox](https://github.com/mochi/statebox) and\nthe paper\n[A comprehensive study of Convergent and Commutative Replicated Data Types](http://hal.archives-ouvertes.fr/inria-00555588/).\n\n\nDatabases like [Riak](https://github.com/basho/riak) let you trade consistency for availability.\nThis means that you can have two conflicting values for a particular key. Resolving these conflicts\nis up to application-logic in the database clients. Certain data-types and operations are suited\nfor automatic conflict-resolution. This project is a collection of these data-types and operations.\n\nThere is also a blog post about knockbox [here](http://reiddraper.com/introducing-knockbox/).\n\n## Status\n\nknockbox is currently in development and the API will be changing quickly, without notice.\n\n## Resolution Protocol\n\nEach of the data type in knockbox implement the `knockbox.resolvable/Resolvable`\nprotocol, which is currently simply:\n\n```clojure\n(resolve [a b]))\n```\n\nWhen it comes time to resolve sibling, you can resolve\na vector of them like this:\n\n```clojure\n;; notice the namespace difference\n(knockbox.core/resolve [a b c d e])\n```\n\nThe data types also implement any appropriate Java Interfaces\nand Clojure Protocols. The different knockbox set implementations,\nfor example, can be used just like Clojure Sets.\n\n## Sets\n\n```clojure\n(require 'knockbox.sets)\n\n;; last-write-wins set\n(def a (knockbox.sets/lww))\n;; =\u003e #{}\n\n;; two-phase set\n(def b (knockbox.sets/two-phase))\n;; =\u003e #{}\n\n;; observed-remove set \n(def c (knockbox.sets/observed-remove))\n;; =\u003e #{}\n\n(disj a :foo)\n;; =\u003e #{}\n\n(conj b :bar)\n;; =\u003e #{:bar}\n```\n\n## Registers\n\nRegisters are simple containers for values.\nCurrently there is one Register implementation with\nlast-write-wins semantics.\n\n```clojure\n(require '(knockbox core registers))\n\n;; the only argument to lww is the value\n;; of the register\n(def a (knockbox.registers/lww \"1\"))\n(def b (knockbox.registers/lww \"2\"))\n(def c (knockbox.registers/lww \"3\"))\n\n;; the value can be queried like\n(.value a)\n;; =\u003e \"1\"\n\n(.value (knockbox.core/resolve [c b a]))\n;; =\u003e \"3\"\n```\n\n## Maps\n\nMaps are currently a work in progress, and don't\nyet implement all of the necessary Java intefaces.\n\n## Counters\n\nCounters with an unbounded number of actors\n(ie. each of your JVM's + Pids) are a tough\ngarbage collection problem. I haven't yet\nfigured out a way to deal with this. Finding\na way to bound the number of actors, and not\ndoing GC may be another option.\n\n## Serialization\n\nknockbox currently supports JSON serialization for the three\nset types. Usage below:\n\n```clojure\n(require '(knockbox sets core))\n\n(def a (knockbox.sets/lww))\n\n(def b (conj a :foo :bar :baz))\n\n(def j (knockbox.core/to-json b))\n\n(def c (knockbox.core/from-json j))\n\n(= b c)\n;; =\u003e true\n```\n\n## Tests\n\nTests can be run by typing:\n\n    lein deps # this only needs to be done once\n    lein midje\n\n\n## Documentation\n\nSource documentation can be generated by typing:\n\n    lein deps\n    lein marg\n\n`lein deps` only needs to be run once.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freiddraper%2Fknockbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freiddraper%2Fknockbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freiddraper%2Fknockbox/lists"}