Git Product home page Git Product logo

freddy's Introduction

Messaging API supporting acknowledgements and request-response

Build Status

Setup

  • Inject the appropriate logger and set up connection parameters:
logger = Logger.new(STDOUT)
freddy = Freddy.build(logger, host: 'localhost', port: 5672, user: 'guest', pass: 'guest')

Releasing a new version

A new version is created when a change is merged into the master branch that changes the version number in freddy.gemspec. A Github Action will create a tag for the version and push the .gem file to rubygems.org

Supported message queues

These message queues have been tested and are working with Freddy. Other queues can be added easily:

Delivering messages

Simple delivery

Send and forget

Sends a message to the given destination. If there is no consumer then the message stays in the queue until somebody consumes it.

freddy.deliver(destination, message)

Expiring messages

Sends a message to the given destination. If nobody consumes the message in timeout seconds then the message is discarded. This is useful for showing notifications that must happen in a certain timeframe but where we don't really care if it reached the destination or not.

freddy.deliver(destination, message, timeout: 5)

Compressed messages

Sends a message to the given destination. If compress is passed as an option parameter, it will compress the payload according to the algorithm provided. Currently the zlib algorithm is implemented to compress the payload. The message heading specify the content-encoding indicating the compression algorithm used.

freddy.deliver(destination, message, compress: 'zlib')

Metadata through headers

Send a message with arbitrary message metadata included in the message headers freddy.deliver(destination, message, headers: {'my-key' => 'my-value'})

Request delivery

Expiring messages

Sends a message to the given destination. Has a default timeout of 3 and discards the message from the queue if a response hasn't been returned in that time.

response = freddy.deliver_with_response(destination, message)

Persistant messages

Sends a message to the given destination. Keeps the message in the queue if a timeout occurs.

response = freddy.deliver_with_response(destination, message, timeout: 4, delete_on_timeout: false)

Errors

deliver_with_response raises an error if an error is returned. This can be handled by rescuing from Freddy::InvalidRequestError and Freddy::TimeoutError as:

begin
  response = freddy.deliver_with_response 'Q', {}
  # ...
rescue Freddy::InvalidRequestError => e
  e.response # => { error: 'InvalidRequestError', message: 'Some error message' }
rescue Freddy::TimeoutError => e
  e.response # => { error: 'RequestTimeout', message: 'Timed out waiting for response' }

Responding to messages

freddy.respond_to destination do |message, msg_handler|
  # ...
end

The callback is called with 2 arguments

  • the parsed message (note that in the message all keys are symbolized)
  • the MessageHandler (described further down)

The MessageHandler

When responding to messages the MessageHandler is given as the second argument.

The following operations are supported:

  • responding with a successful response
msg_handler.success(response = nil)
  • responding with an error response
msg_handler.error(error: "Couldn't process message")

Tapping into messages

When it's necessary to receive messages but not consume them, consider tapping.

freddy.tap_into pattern do |message, destination|
  • destination refers to the destination that the message was sent to
  • Note that it is not possible to respond to the message while tapping.
  • When tapping the following wildcards are supported in the pattern :
    • # matching 0 or more words
    • * matching exactly one word

Examples:

freddy.tap_into "i.#.free"

receives messages that are delivered to "i.want.to.break.free"

freddy.tap_into "somebody.*.love"

receives messages that are delivered to somebody.to.love but doesn't receive messages delivered to someboy.not.to.love

It is also possible to tap using multiple patterns:

freddy.tap_into(['user.created', 'user.deleted'], group: 'user-event') do
  # This processes events from both user.created topic and user.deleted topic.
  # It also groups them into one queue called 'user-event'. This ensures that
  # only one listener within a group process a particular event.
end

The ResponderHandler

When responding to a message or tapping the ResponderHandler is returned.

responder_handler = freddy.respond_to ....

The following operations are supported:

  • stop responding
responder_handler.shutdown

Request Tracing

Freddy supports [OpenTelemetry API|https://github.com/open-telemetry/opentelemetry-ruby]. The trace information is automatically passed through deliver, deliver_with_response, respond_to and tap_into calls.

This is not compatible with opentelemetry-instrumentation-bunny library.

Notes about concurrency

freddy uses a thread pool to run concurrent responders. The thread pool is unique for each tap_into and respond_to responder. Thread pool size can be configured by passing the configuration option max_concurrency. Its default value is 4. e.g. If your application has 2 respond_to responders and 1 tap_into responder with max_concurrency set to 3 then your application may process up to 9 messages in parallel.

Note that while it is possible to use deliver_with_response inside a respond_to block, it is not possible to use another respond_to block inside a different respond_to block.

Note also that other configuration options for freddy users such as pool sizes for DB connections need to match or exceed max_concurrency to avoid running out of resources.

Read more from http://rubybunny.info/articles/concurrency.html.

Credits

freddy was originally written by Urmas Talimaa as part of SaleMove development team.

SaleMove Inc. 2012

freddy is maintained and funded by SaleMove, Inc.

The names and logos for SaleMove are trademarks of SaleMove, Inc.

freddy's People

Contributors

indrekj avatar urmastalimaa avatar madis avatar take-five avatar stenver avatar deiwin avatar annaagaf avatar meticulesque avatar steamric avatar willmore avatar ostap0207 avatar sviik avatar ddre54 avatar sturmer avatar s22su avatar minedetector avatar bautrey37 avatar sliiser avatar jaantohver avatar

Stargazers

P Gouv avatar Saul Palomino Ramos avatar Gerardo Davila avatar Stefano Uliari avatar Carlos Paniagua avatar  avatar  avatar  avatar

Watchers

 avatar Andres Jaan Tack avatar Erki avatar  avatar Carlos Paniagua avatar  avatar James Cloos avatar Dmitry Preobrazhenskiy avatar Hardi Teder avatar Cyberaa avatar Justin DiPietro avatar Dan Michaeli avatar Halliki M avatar Tony Lepmets avatar Erki Treier avatar Kert Pjatkin avatar P.Halapuu avatar Kote Ujmajuridze avatar  avatar  avatar  avatar Dmytro Koval avatar Rafael Ferreira avatar Kiril Dokh avatar José Seabra avatar  avatar Martin Sulg avatar Tõnis Kasekamp avatar  avatar Alfonso Pinto avatar Madis Lehtmets avatar Ruslan Dmitrijev avatar Corey Jack Wilson avatar Gerardo Davila avatar Dmitry Aflitonov avatar [roscoe] avatar Thomas Hertz avatar Vlad Bondarenko avatar Aadam Kaivo avatar Mart Lepanen avatar pedromartine avatar Namita Shah avatar Merlin Kasesalu avatar Abir Rahali avatar  avatar Felix Wyss avatar

freddy's Issues

Channel and thread safety

I was looking at SendAndWaitResponseProducer.
It seems that it is designed to be thread safe. However since bunny/rabbitmq channel is shared is it really safe?
According to bunny documentation channels must not be shared. Is it a special case?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.