{"id":15406619,"url":"https://github.com/jstotz/jstreams","last_synced_at":"2025-04-17T22:57:05.509Z","repository":{"id":66448171,"uuid":"178877137","full_name":"jstotz/jstreams","owner":"jstotz","description":"A distributed streaming platform for Ruby built on top of Redis Streams","archived":false,"fork":false,"pushed_at":"2024-04-03T22:06:41.000Z","size":87,"stargazers_count":4,"open_issues_count":1,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-29T06:11:32.342Z","etag":null,"topics":["pubsub","redis","redis-streams","ruby","streams"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/jstotz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2019-04-01T14:07:55.000Z","updated_at":"2022-09-07T15:03:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"b509a7ce-4537-4cc0-84ed-38af1bf80955","html_url":"https://github.com/jstotz/jstreams","commit_stats":{"total_commits":66,"total_committers":2,"mean_commits":33.0,"dds":0.0757575757575758,"last_synced_commit":"472195adae3f5ba32137ba4a0bd4b49554b5f208"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jstotz%2Fjstreams","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jstotz%2Fjstreams/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jstotz%2Fjstreams/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jstotz%2Fjstreams/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jstotz","download_url":"https://codeload.github.com/jstotz/jstreams/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249389125,"owners_count":21262851,"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":["pubsub","redis","redis-streams","ruby","streams"],"created_at":"2024-10-01T16:24:42.300Z","updated_at":"2025-04-17T22:57:05.491Z","avatar_url":"https://github.com/jstotz.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jstreams\n\n[![Gem](https://img.shields.io/gem/v/jstreams.svg)](https://rubygems.org/gems/jstreams)\n[![CircleCI](https://img.shields.io/circleci/project/github/jstotz/jstreams/master.svg)](https://circleci.com/gh/jstotz/jstreams)\n[![Test Coverage](https://img.shields.io/codeclimate/coverage/jstotz/jstreams.svg)](https://codeclimate.com/github/jstotz/jstreams/test_coverage)\n[![Maintainability](https://img.shields.io/codeclimate/maintainability/jstotz/jstreams.svg)](https://codeclimate.com/github/jstotz/jstreams/maintainability)\n[![Docs](https://img.shields.io/badge/docs-yard-green.svg)](https://www.rubydoc.info/github/jstotz/jstreams/master)\n\nA distributed streaming platform for Ruby built on top of Redis Streams.\n\nProvides a multi-threaded publisher/subscriber.\n\n## Project Status\n\nThis is alpha software and not suitable for production use.\n\n## Features\n\n- Load balancing among subscribers within a group\n- Automatically message reassignment when consumers go away\n- Multi-threaded subscribers\n- Configurable message serialization\n\n## Roadmap\n\n- Configurable retry logic\n- Replay a stream from a given point\n- Wildcard subscriptions\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'jstreams'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install jstreams\n\n## Usage\n\n### Publisher\n\n```ruby\njstreams = Jstreams::Context.new\n\njstreams.publish(\n  :users,\n  event: 'user_created',\n  user_id: 1,\n  name: 'King Buzzo',\n  email: 'buzzo@example.com'\n)\n\njstreams.publish(:users, event: 'user_logged_in', user_id: 1)\n```\n\n### Subscriber\n\n```ruby\njstreams = Jstreams::Context.new\n\njstreams.subscribe(\n  :user_activity_logger,\n  :users\n) do |message, _stream, _subscriber|\n  case message['event']\n  when 'user_created'\n    logger.info \"User #{message['name']} created\"\n  when 'user_logged_in'\n    logger.info \"User #{message['id']} logged in\"\n  end\nend\n\njstreams.subscribe(\n  :send_welcome_email,\n  :users\n) do |message, _stream, _subscriber|\n  send_user_welcome_email(message['id']) if message['event'] == 'user_created'\nend\n\n# Spawns subscriber threads and blocks\njstreams.run\n```\n\n### Replay\n\nStarts a temporary copy of the given subscriber until messages have been replayed up to the checkpoint stored at the time replay is called.\n\n```ruby\njstreams.replay(:user_activity_logger, from: message_id)\n```\n\n### Retries\n\nBy default subscribers will process messages indefinitely until successful.\n\n```ruby\n# TODO\n```\n\n### Serialization\n\n```ruby\nclass Serializer\n  MESSAGE_TYPES = {\n    user_created: UserCreatedMessage, user_logged_in: UserLoggedInMessage\n  }\n\n  def serialize(type, message)\n    message_class(type).serialize(message)\n  end\n\n  def deserialize(type, message)\n    message_class(type).deserialize(message)\n  end\n\n  private\n\n  def message_class(type)\n    MESSAGE_TYPES.fetch(type) { raise \"Unknown message type: #{type}\" }\n  end\nend\n\njstreams = Jstreams::Context.new(serializer: Serializer)\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/jstotz/jstreams. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the jstreams project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jstotz/jstreams/blob/master/CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjstotz%2Fjstreams","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjstotz%2Fjstreams","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjstotz%2Fjstreams/lists"}