On 02/28/2012 09:47 PM, Andrew Stitcher wrote:
On Tue, 2012-02-28 at 21:16 +0000, Gordon Sim wrote:
Why do we need AsyncResult objects as distinct from a callback context
and the status of the operation?
That goes with using a single callback for the result - there needs to
be a single base class passed back. If you used 2 callbacks then the
AsyncResult is no longer necessary.
If that is all it is for I think a simple code+description pair would be
simpler without loss of functionality, with e.g. 0 being the code for
success.
[...]
How do I get the BrokerContext back from a handle?
A simple accessor would do it - remember the base class is not shown in
the interface because it's not needed there, but I think it could be
something like:
class AsyncHandle {
public:
AsyncHandle(BrokerContext*);
~AsyncHandle() = 0;
const BrokerContext* getBrokerContext() const = 0;
};
This *is* part of the interface, since the store will define the actual
AsyncHandle implementation and the broker needs to be able to retrieve
its own context from it.
Should it be passed
to the createXxxResult() methods on Result Factory rather than the
AsyncHandle (which is really only interesting to the store)?
You pass back the AsyncHandle because the broker might want to do
something further with it. If you only pass back the BrokerContext then
you'd somehow need to create a circular link between them.
I don't see that being useful and certainly not worth the extra
complexity. Can you give an example of where the broker would need the
handle to be passed back in the callback rather than simply relying on
its own context to give it everything it needs?
I prefer having the callback context simply passed in with the
operation. That allows you for example to use a different context for
two operations that share a handle (e.g. create/destroy or enqueue/dequeue).
That is definitely a good option. The (perhaps small) benefit of this
wrapped scheme is that it passes fewer things back to the result, given
that you need to have the store contexts passed back as well for the
reasons above.
I don't think you do need store contexts passed back. I think an
optional broker provided callback context and a status object (to cover
both success and failure with the single callback) are sufficient. E.g.
as attached.
#include <stdint.h>
#include <string>
using std::string;
namespace qpid {
// This is probably not the correct forward declaration, but it allows this to compile.
namespace types {
namespace Variant {
class Map;
}
}
namespace broker {
//defined by broker:
class BrokerContext;
//subclassed by broker:
class DataSource {
public:
virtual ~DataSource() = 0;
virtual uint64_t getSize() = 0;
virtual void write(char* target) = 0;
};
//defined by store:
class QueueHandle;
class ConfigHandle;
class TxnHandle;
class EventHandle;
class EnqueueHandle;
//callback definitions:
struct AsyncResult
{
int errNo; /** 0 implies no error */
std::string errMsg;
};
typedef void (*ResultCallback)(const AsyncResult&, BrokerContext*);
//subclassed by store:
class StoreAsyncInterface {
public:
StoreAsyncInterface();
virtual ~StoreAsyncInterface() = 0;
virtual QueueHandle* createQueueHandle(const std::string& queueName , const qpid::types::Variant::Map& queueOptions) = 0;
virtual ConfigHandle* createConfigHandle() = 0;
virtual TxnHandle* createTxnHandle(const std::string& xid=std::string()) = 0;
virtual EventHandle* createEventHandle() = 0;
virtual MessageHandle* createMessageHandle() = 0;
virtual void submitCreate(ConfigHandle*, DataSource*, ResultCallback*, BrokerContext*) = 0;
virtual void submitDestroy(ConfigHandle*, ResultCallback*, BrokerContext*) = 0;
virtual void submitCreate(QueueHandle*, DataSource*, ResultCallback*, BrokerContext*) = 0;
virtual void submitDestroy(QueueHandle*, ResultCallback*, BrokerContext*) = 0;
virtual void submitFlush(QueueHandle*, ResultCallback*, BrokerContext*) = 0;
virtual void submitPrepare(TxnHandle*, ResultCallback*, BrokerContext*) = 0;
virtual void submitCommit(TxnHandle*, ResultCallback*, BrokerContext*) = 0;
virtual void submitAbort(TxnHandle*, ResultCallback*, BrokerContext*) = 0;
virtual void submitRecord(EventHandle*, DataSource*, QueueHandle*, TxnHandle*, ResultCallback*, BrokerContext*) = 0;
virtual void submitEnqueue(MessageHandle*, DataSource*, QueueHandle*, TxnHandle*, ResultCallback*, BrokerContext*) = 0;
virtual void submitDequeue(MessageHandle*, TxnHandle*, ResultCallback*, BrokerContext*) = 0;
// Legacy - Restore FTD message, is NOT async!
virtual int loadContent(MessageHandle*, QueueHandle*, char* data, uint64_t offset, const uint64_t length) = 0;
};
}}
---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project: http://qpid.apache.org
Use/Interact: mailto:[email protected]