{"id":28194285,"url":"https://github.com/monkey-projects/zmq","last_synced_at":"2025-05-16T13:12:06.035Z","repository":{"id":222311110,"uuid":"756885787","full_name":"monkey-projects/zmq","owner":"monkey-projects","description":"Functionality for creating servers and clients on top of zeromq","archived":false,"fork":false,"pushed_at":"2024-04-10T15:16:54.000Z","size":79,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-20T23:34:01.957Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/monkey-projects.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}},"created_at":"2024-02-13T13:57:46.000Z","updated_at":"2024-05-09T12:16:10.000Z","dependencies_parsed_at":"2024-04-03T12:50:07.373Z","dependency_job_id":null,"html_url":"https://github.com/monkey-projects/zmq","commit_stats":null,"previous_names":["monkey-projects/zmq"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Fzmq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Fzmq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Fzmq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Fzmq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/monkey-projects","download_url":"https://codeload.github.com/monkey-projects/zmq/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254535800,"owners_count":22087399,"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":"2025-05-16T13:11:48.700Z","updated_at":"2025-05-16T13:12:06.014Z","avatar_url":"https://github.com/monkey-projects.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Monkey ZMQ\n\nA Clojure library that provides functionality for creating servers andclients\non top of [ZeroMQ](https://zeromq.org/).  This is used by [MonkeyCI](https://monkeyci.com)\nto do communication between the various modules.\n\n## Usage\n\nInclude it in your project `deps.edn`:\n\n```clojure\n{:deps {com.monkeyprojects/zmq {:mvn/version \"\u003cVERSION\u003e\"}}}\n```\nOr with Leiningen:\n```clojure\n(defproject ...\n :dependencies [[com.monkeyprojects/zmq \"\u003cVERSION\u003e\"]])\n```\n\nThe clients and servers are grouped in namespaces.  See `monkey.zmq.req` for\nrequest/reply, or `monkey.zmq.events` for events push/pull.  The server functions\nreturn [components](https://github.com/stuartsierra/component) that should be started\nor stopped.  The server will start a background thread that invokes the specified handler\non incoming data.  The client functions return an `AutoCloseable` object that is also\na function.\n\n### Request/Reply\n\n```clojure\n(require '[monkey.zmq.req :as r])\n(require '[zeromq.zmq :as z])\n\n;; Create ZeroMQ context\n(def ctx (z/context 1))\n\n;; Create and start server\n(require '[com.stuartsierra.component :as co])\n(def server (-\u003e (r/server ctx \"inproc://test-server\" (constantly \"ok\"))\n                (co/start)))\n\n;; Create client\n(def client (r/client ctx \"inproc://test-server\"))\n\n;; Send a request, wait for a reply\n(def reply (client \"Test request\"))\n;; =\u003e \"ok\"\n```\n\nThe communication is always serialized to [EDN](https://github.com/edn-format/edn), so\nyou can also send structured information.\n\n### Passive Events\n\nThe `monkey.zmq.events` namespace provides two kinds of event handling systems.  One is\na simple event server that only passively receives events, and dispatches them to a\n`handler` function.  The other is a more complicated (and useful) event broker that\nis both able to receive and send out events.\n\nTo create the passive event server and client:\n```clojure\n(require '[monkey.zmq.events :as e])\n(require '[zeromq.zmq :as z])\n\n(def ctx (z/context 1))\n(def addr \"inproc://passive-events\")\n\n;; Create and start server\n(def server (e/event-server ctx addr println))\n;; A client\n(def client (e/event-poster ctx addr))\n;; The client is a component that implements IFn and Autoclosable so you can\n;; invoke it like this:\n(client {:type :test-event :message \"this is a test event\"})\n\n;; The server should now print out the event\n\n;; Shut down\n(.close client)\n(.close server)\n```\n\nThere is also a `close-all` utility function in `monkey.zmq.common` that closes all its args.\n\n### Bidirectional Event Broker\n\nA more useful event broker is also available in the events namespace.  It listens on an\nendpoint (multiple endpoints coming later) and dispatches any events it receives to all\nconnected clients.  Clients must register with a filter in order to receive events.  How\nthis filter looks and how it's handled is completely up to you.  When starting the server\nyou need to specify a `matches-filter?` predicate that is passed an event and a filter.\nIt decides whether a client that is registered with a given filter is allowd to receive\nthe event.  By default, all events are allowed.\n\n```clojure\n(def addr \"inproc://event-broker\")\n\n;; Start broker\n(def broker (e/broker-server ctx [addr] {:matches-filter? (fn [evt evt-filter]\n                                                            (= (:type evt) evt-filter))}))\n;; Create a client and register it\n(def client (e/broker-client ctx addr println))\n(e/register client :test-event)\n\n(client {:type :test-event :message \"Should receive this\"})\n(client {:type :other-event :message \"Should not receive this\"})\n```\n\nThis setup gives the user a lot of flexibility on how to filter events without sending\ntoo much data to the clients and burdening them with their own filtering.  The only\ncondition is that the filter is serializable.  You could event use `eval` and allow\nthe client to send Clojure code as an event filter!  Whether that is a safe solution,\nI'll leave that up to you to decide.\n\nYou can also have the broker listen on multiple addresses, just specify more than one in\nthe second argument to `broker-server`.\n\n#### Other Options\n\nOther options to pass to the broker client and server are:\n\n|---|---|---|\n|Option|Default|Description|\n|---|---|---|\n|`autostart?`|`true`|Will automatically [start](https://cljdoc.org/d/com.stuartsierra/component/1.1.0/api/com.stuartsierra.component#Lifecycle) the component.  If not, you'll have to start it yourself in order to enable the background thread.|\n|`poll-timeout`|`500`|Number of millisecs to wait for incoming data.|\n|`linger`|`0`|When closing the context, will block for this number of msecs to ensure all data is sent.  See also the [ZeroMQ documentation about lingering](http://zeromq.github.io/cljzmq/zeromq.zmq.html#var-set-linger).|\n|`close-context?`|`false`|When true, the context passed in will also be closed when shutting down the component.|\n|---|---|---|\n\n## TODO\n\nThings that still need to be implemented:\n\n - Implement a ping system to unregister any dead clients.\n - Make sure that events that match multiple filters for the same client only get sent once.\n - When sending information, first check if the socket can actually handle it.\n\n## Other Resources\n\n- [CI/CD](https://app.monkeyci.com/c/9eda9831-ea92-4a6c-95db-17bb9c9b2ab2/r/zmq)\n\n## License\n\nCopyright (c) 2024 by Monkey Projects.\n\n[GPL v3 License](LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonkey-projects%2Fzmq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmonkey-projects%2Fzmq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonkey-projects%2Fzmq/lists"}