Publishing contents

Problem

A content that refers to application data (using the set_body method) needs to be freed in the right way or strange things will happen. Here is how, and why.

Explanation

Contents (amq_content_basic) are reference-counted objects. OpenAMQ uses iCL, a class library built by iMatix, which defines two types of objects for this purpose:

  • Normal objects, which we manage using new and destroy.
  • Reference-counted objects, which we manage using new, link, and unlink.

On a reference-counted object, destroy means 'zombify', i.e. render dead and inoperable immediately. We don't want this.

When we publish contents from an OpenAMQ application, what we do is pass them to a second thread which sends them asynchronously. The second thread uses reference counting to make sure the content hangs around for long enough to be sent. Calling destroy before the content is sent has fairly nasty consequences. In many apps you won't see these because the sending thread will do its work very quickly, before you can even call the destroy method in the first thread. In high-rate publishers, the problem will appear.

So the proper way to create, publish, and then get rid of a content is:

content = amq_content_basic_new ();
amq_content_basic_set_body (content, whatever);
amq_client_session_basic_publish (session, whatever);
amq_content_basic_unlink (&content);

The publish method will, internally, do a link and then at some later stage an unlink. When the last of the two unlinks is done (in any order) the content is also destroyed and the body deallocated. Make sure you provide a free_fn to the set_body method if the body is dynamically allocated (which it had better be unless you are still using COBOL).

If you see code or documentation that says different, it's wrong.

Comments

Add a New Comment

Edit | Files | Tags | Source | Print

rating: +1+x

Author

Pieter Hintjens <moc.xitami|hp#moc.xitami|hp>

All tutorials

Performance Tests: This tutorial explains how to do OpenAMQ performance tests using 0MQ performance testing framework.

Broker federation: How to setup a geographically distributed federation of OpenAMQ brokers and how to define dataflows between individual geographical locations.

The ESB cookbook: How to implement your own Enterprise Service Bus, step by step, using OpenAMQ.

Publishing contents: How to publish contents at high speed without bizarre memory issues.

Tuning OpenAMQ for low latency: How to tune your operating system and hardware to get the lowest latency, i.e. the best response times, from your OpenAMQ broker.

The mandatory and immediate flags: How to use the 'mandatory' and 'immediate' flags on the Basic.Publish method.

Load balancing: How to use OpenAMQ to distribute work between multiple applications, a technique called "load balancing".

Content based routing: How to route messages based on their header properties. It is a fast and simple way to do 'content based routing' without needing to inspect entire messages. We explain the principles and provide worked examples.

Transient or durable subscriptions: How to make subscriptions that are transient (come and go with their consuming applications) or durable (stay around).

The AMQ model: How the AMQ model works: this is a basic backgrounder for anyone starting to use OpenAMQ in their applications.

Developing on Windows: How to build OpenAMQ client applications using MSVC on Windows

Handling Ctrl-C in applications: How to properly detect an interrupt (Ctrl-C) and shut-down gracefully in C/C++ WireAPI applications.