Summary
How to publish contents at high speed without bizarre memory issues.
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
Author
- Pieter Hintjens <moc.xitami|hp#moc.xitami|hp>
