{"id":16660563,"url":"https://github.com/mpenet/tape","last_synced_at":"2025-04-03T02:09:56.396Z","repository":{"id":52220500,"uuid":"160816699","full_name":"mpenet/tape","owner":"mpenet","description":"Chronicle Queue helpers","archived":false,"fork":false,"pushed_at":"2021-05-04T18:07:41.000Z","size":38,"stargazers_count":135,"open_issues_count":1,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-24T08:13:16.434Z","etag":null,"topics":["clojure","queue"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mpenet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":"FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"mpenet"}},"created_at":"2018-12-07T11:45:10.000Z","updated_at":"2024-11-21T17:51:29.000Z","dependencies_parsed_at":"2022-08-23T23:50:38.914Z","dependency_job_id":null,"html_url":"https://github.com/mpenet/tape","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpenet%2Ftape","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpenet%2Ftape/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpenet%2Ftape/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpenet%2Ftape/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mpenet","download_url":"https://codeload.github.com/mpenet/tape/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246922247,"owners_count":20855345,"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":["clojure","queue"],"created_at":"2024-10-12T10:29:48.770Z","updated_at":"2025-04-03T02:09:56.361Z","avatar_url":"https://github.com/mpenet.png","language":"Clojure","funding_links":["https://github.com/sponsors/mpenet"],"categories":[],"sub_categories":[],"readme":"# tape\n\n[![cljdoc badge](https://cljdoc.xyz/badge/cc.qbits/tape)](https://cljdoc.xyz/d/cc.qbits/tape/CURRENT) [![Clojars Project](https://img.shields.io/clojars/v/cc.qbits/tape.svg)](https://clojars.org/cc.qbits/tape)\n\n\u003cimg src=\"http://i.imgur.com/yNrbl1D.png\" title=\"qbits/tape\" align=\"right\"/\u003e\n\nSimple [Chronicle Queue](https://github.com/OpenHFT/Chronicle-Queue) 5\nhelpers for clojure.\n\n\u003e Micro second messaging that stores everything to disk\n\nIn short for when Kafka is too much and durable-queue not enough.\n\nChronicle Queue is similar to a low latency broker-less\ndurable/persisted JVM topic. Tape focuses on embedded usage (we do not\nsupport topic distribution).  It's essentially a disk-backed queue,\nallowing for queues that can survive processes dying, and whose size\nis bounded by available disk rather than memory.\n\nConceptually the api is somewhat similar to kafka, you can replay\nqueues, set tailer's index etc... It stores everything on flat-files,\nyou can control how rollup/purge of these happens via queue options.\n\n\nI'd encourage you read about [Chronicle\nQueue](https://github.com/OpenHFT/Chronicle-Queue) if you want to use\nthis lib, Chronicle Queue comes with its set of tradeoffs you want to\nknow first.\n\nStarted with a fork of https://github.com/malesch/croque and ended up\nrewriting/dropping most of it, hence the rename.\n\n## Installation\n\n`tape` is [available on Clojars](https://clojars.org/cc.qbits/tape).\n\n## Usage\n\n``` clj\n(ns foo\n  (:require [qbits.tape.tailer :as tailer]\n            [qbits.tape.appender :as appender]\n            [qbits.tape.queue :as queue]))\n\n;; create a queue instance\n(def q (queue/make \"/tmp/q1\"))\n\n;; create a tailer bound to that queue\n(def t (tailer/make q))\n\n;; nothing in queue yet, so nil\n(tailer/read! t) =\u003e nil\n\n;; to add to queue you need an appender\n(def appender (appender/make q))\n\n;; add stuff to queue, returns index\n(appender/write! appender {:foo [:bar {:baz 0}]}) =\u003e 76759655514210\n(appender/write! appender {:another :thing}) =\u003e 76759655514211\n\n(tailer/read! t) =\u003e {:foo [:bar {:baz 0}]}\n(tailer/read! t) =\u003e {:another :thing}\n(tailer/read! t) =\u003e nil ;; empty now\n\n\n;; back to some existing index, essentially rewinding to it\n(tailer/to-index! t 76759655514210)\n\n;; Tailers are also Sequential/Seqable/Reducible and behave as such.\n\n(run! (fn [msg] (println msg)) t)\n\n(doseq [msg t]\n  (println msg))\n\n[...]\n```\n\nThere's also a core.async facade for appenders/tailers on\n`qbits.tape.async` and other utilities to cleanup queues files you\ndon't care about anymore. Anything created with a `make` function can\nbe inspected with `clojure.datafy/datafy`.\n\nWe serialize data with fressian as a default, but you can supply your\nown qbits.tape/ICodec when you make/bind to a queue if you need to use\nsomething else.\n\n## License\n\nCopyright © 2019 Max Penet\n\nDistributed under the Eclipse Public License either version 1.0 or (at\nyour option) any later version.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpenet%2Ftape","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmpenet%2Ftape","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpenet%2Ftape/lists"}