A new "MamaResourcePool" API for OpenMAMA?


Frank Quinn
 

Hi Folks,

 

We are currently considering options for trying to make the OpenMAMA API easier to work with and more accessible for new users.

 

When I look at the OpenMAMA API's strengths and weaknesses, the setup and management of the subscriptions themselves is one of the more difficult things to manage especially with a new user. These are things which we seasoned users would take for granted but I think new users would struggle with.

 

That is why I'm suggesting a new "MamaResourcePool" api.

 

The idea is to manage OpenMAMA resources via OpenMAMA itself rather than depending on the user to manage complex state, setup, shutdown etc. I'm taking the approach of starting with what I (pretending to be a new OpenMAMA user) would like to see as opposed to things which would be technically easier to do etc.

 

So taking for example a new subscription, this is the entire code I'm proposing (in C here but should translate easily to other languages) should be required:

 

// Set up the event handlers for OpenMAMA

mamaMsgCallbacks callbacks;

memset(&callbacks, 0, sizeof(callbacks));

callbacks.onMsg = subscriptionOnMsg;

callbacks.onCreate = subscriptionOnCreate;

callbacks.onError = subscriptionOnError;

 

// Use a new "resource pool"

mamaResourcePool resourcePool;

const char* poolName = NULL;

const void* closure = NULL;

 

// Create the resource pool, allocating queues, defaults etc from configuration

mamaResourcePool_create(&resourcePool, poolName);

 

// Actually... subscribe to something via something convenient like a URI

mamaResourcePool_createSubscriptionFromUri(&subscription, "bridge://transport/source/topic", &callbacks, closure);

 

// Block

mama_start();

 

And then you would start receiving events. No transport creation, source creation, queue creation, encouraging users use default queue etc.

 

I’d also suggest that the callbacks onCreate and onError should be optional, with the default implementation simply logging those events.

 

I foresee similar with lambdas etc. The idea is that mamaResourcePool will:

 

·         When it is created:

o    Create a number of event queues for subscriptions (which could be configurable in properties based on the poolName)

o    Load all payload and middleware bridges found on the PATH / LD_LIBRARY_PATH etc

o    Call mama_open() (if not already open)

o    Create and manage internal stores of all managed subscriptions, transports, sources etc

·         Then when a resource is created inside:

o    Find / create transport bridge

o    Find / create transport

o    Find / create source

o    Find / create subscription (e.g. multiple callbacks for same subscription)

o    Find / create anything which is required to acquire the requested resource

·         Be convenient and usable, but still flexible (it would return existing OpenMama objects so they can be manipulated)

·         Take the heavy lifting and thread safety pain away from the application developer

·         Defer default "is this basic sub" or "is this market data sub" to the bridge, configuration or as an API call in the resource pool itself

 

My guess is that many of you may already have an API that does this in each of the provided languages… but newcomers won't have that. This would vastly reduce the complexity and error checking required for a new user, as well as remove the expectation around deciding “which subscription API to use” from the application developer.

 

If there is any feedback to this approach, or in particular if anyone has recently worked with a new user coming online with OpenMAMA please let us know or pop into Gitter to discuss!

 

Cheers,

Frank

 

Frank Quinn

Cascadium

T: +44 (0) 28 8678 8015

E: fquinn@...

W: http://cascadium.io

 


Bill Torpey
 

Hi Frank:

I read with interest your latest email, and certainly agree that there are ways to make OpenMAMA both easier to use (and harder to mis-use!), and more accessible to new users. We've been working on these issues since NYFIX was initially acquired by NYSE back in 2009, and have some experience (and code!) to share as a result.

For us, the biggest problem in moving our middleware stack to Mama/OpenMAMA back in the day (from Tibco Rendezvous), was the relatively poor support for setup and teardown of Mama objects. This wasn't totally surprising, as the typical use case for Mama at the time consisted of relatively long-lived publishers, with subscribers that would come and go during the day. However, in our case the subscribers (servers) tend to be the long-lived components and the publishers (clients) tended to come and go. We had a lot of problems coordinating object lifetimes, especially in a multi-threaded environment, such that we avoided memory leaks, or even worse errors such as use-after-free.

At the time, we worked with the Mama development team to create a wrapper layer called "MME" (for MAMA Managed Environment) which would manage the lifetimes of Mama event objects and remove the biggest problem in Mama: the requirement that object destruction occur only on the event dispatching thread. At the time, we hoped that MME would become part of Mama proper, but that never happened and the rights to the code were transferred to NYFIX when NYSE divested both NYFIX and SR Labs. NYFIX released the code as open-source concurrent with our release of OZ at https://github.com/nyfix/MME.

We've been using MME in the NYFIX Marketplace since approximately 2010; first with the commercial transport from SR/Vela, and for the past year and change with OZ (https://github.com/nyfix/OZ), the open-source transport that we created based on ZeroMQ.

We would be interested in working with the OpenMAMA community to extend and improve MME, and suggest that it answers several of the issues you mentioned.

One thing that MME does not address, however, is overall ease-of-use, and specifically the steep learning-curve associated with the Mama API. For that, we'd like to suggest that the community take a look at the example code included with OZ (https://github.com/nyfix/OZ/blob/master/examples/Readme.md). The example code encapsulates a lot of the "tricky bits" associated with the Mama API, enabling someone to get started quickly -- for example, see https://github.com/nyfix/OZ/blob/master/examples/sub.cpp.

Full disclosure: the OZ examples are exclusively C++ -- while the OZ transport itself is written in C, we prefer C++ for application-level code. The OZ examples do, however, work with other transports, specifically the (now deprecated) Qpid transport.

Both MME and OZ are tried and tested in production use, which is potentially a significant advantage. In any event, we'd be delighted to engage with the OpenMAMA community around either or both of these components to see how they could possibly address some or all of the important issues you raise. We hope the community will take the time to explore both MME and OZ, and we're very interested in any feedback.

Best Regards,

Bill Torpey