示例#1
0
void TxnCtxt::jrnl_sync(JournalImpl* jc, timespec* timeout) {
    if (!jc || jc->is_txn_synced(getXid()))
        return;
    while (jc->get_wr_aio_evt_rem()) {
        if (jc->get_wr_events(timeout) == journal::jerrno::AIO_TIMEOUT && timeout)
            THROW_STORE_EXCEPTION(std::string("Error: timeout waiting for TxnCtxt::jrnl_sync()"));
    }
}
/**
 * Record generic durable configuration
 */
void
MessageStorePlugin::create(const broker::PersistableConfig& config)
{
    if (config.getPersistenceId()) {
        THROW_STORE_EXCEPTION("Config item already created: " +
                              config.getName());
    }
    provider->second->create(config);
}
/**
 * Record the existence of a durable exchange
 */
void
MessageStorePlugin::create(const broker::PersistableExchange& exchange,
                           const framing::FieldTable& args)
{
    if (exchange.getPersistenceId()) {
        THROW_STORE_EXCEPTION("Exchange already created: " + exchange.getName());
    }
    provider->second->create(exchange, args);
}
/**
 * Enqueues a message, storing the message if it has not
 * been previously stored and recording that the given
 * message is on the given queue.
 *
 * Note: The operation is asynchronous so the return of this function does
 * not mean the operation is complete.
 */
void
MessageStorePlugin::enqueue(broker::TransactionContext* ctxt,
                            const boost::intrusive_ptr<broker::PersistableMessage>& msg,
                            const broker::PersistableQueue& queue)
{
    if (queue.getPersistenceId() == 0) {
        THROW_STORE_EXCEPTION("Queue not created: " + queue.getName());
    }
    provider->second->enqueue(ctxt, msg, queue);
}
/**
 * Appends content to a previously staged message
 */
void
MessageStorePlugin::appendContent
  (const boost::intrusive_ptr<const broker::PersistableMessage>& msg,
   const std::string& data)
{
    if (msg->getPersistenceId())
        provider->second->appendContent(msg, data);
    else
        THROW_STORE_EXCEPTION("Cannot append content. Message not known to store!");
}
示例#6
0
void TxnCtxt::begin(DbEnv* env, bool sync) {
    int err;
    try { err = env->txn_begin(0, &txn, 0); }
    catch (const DbException&) { txn = 0; throw; }
    if (err != 0) {
        std::ostringstream oss;
        oss << "Error: Env::txn_begin() returned error code: " << err;
        THROW_STORE_EXCEPTION(oss.str());
    }
    if (sync)
        globalHolder = AutoScopedLock(new qpid::sys::Mutex::ScopedLock(globalSerialiser));
}
/**
 * Loads (a section) of content data for the specified
 * message (previously stored through a call to stage or
 * enqueue) into data. The offset refers to the content
 * only (i.e. an offset of 0 implies that the start of the
 * content should be loaded, not the headers or related
 * meta-data).
 */
void
MessageStorePlugin::loadContent(const broker::PersistableQueue& queue,
                                const boost::intrusive_ptr<const broker::PersistableMessage>& msg,
                                std::string& data,
                                uint64_t offset,
                                uint32_t length)
{
    if (msg->getPersistenceId())
        provider->second->loadContent(queue, msg, data, offset, length);
    else
        THROW_STORE_EXCEPTION("Cannot load content. Message not known to store!");
}
示例#8
0
void TxnCtxt::sync() {
    if (loggedtx) {
        try {
            for (ipqItr i = impactedQueues.begin(); i != impactedQueues.end(); i++)
                jrnl_flush(static_cast<JournalImpl*>(*i));
            if (preparedXidStorePtr)
                jrnl_flush(preparedXidStorePtr);
            for (ipqItr i = impactedQueues.begin(); i != impactedQueues.end(); i++)
                jrnl_sync(static_cast<JournalImpl*>(*i), &journal::jcntl::_aio_cmpl_timeout);
            if (preparedXidStorePtr)
                jrnl_sync(preparedXidStorePtr, &journal::jcntl::_aio_cmpl_timeout);
        } catch (const journal::jexception& e) {
            THROW_STORE_EXCEPTION(std::string("Error during txn sync: ") + e.what());
        }
    }
}
/**
 * Record the existence of a durable queue
 */
void
MessageStorePlugin::create(broker::PersistableQueue& queue,
                           const framing::FieldTable& args)
{
    if (queue.getName().size() == 0)
    {
        QPID_LOG(error,
                 "Cannot create store for empty (null) queue name - "
                 "ignoring and attempting to continue.");
        return;
    }
    if (queue.getPersistenceId()) {
        THROW_STORE_EXCEPTION("Queue already created: " + queue.getName());
    }
    provider->second->create(queue, args);
}
示例#10
0
void TxnCtxt::commitTxn(JournalImpl* jc, bool commit) {
    if (jc && loggedtx) { /* if using journal */
        boost::intrusive_ptr<DataTokenImpl> dtokp(new DataTokenImpl);
        dtokp->addRef();
        dtokp->set_external_rid(true);
        dtokp->set_rid(loggedtx->next());
        try {
            if (commit) {
                jc->txn_commit(dtokp.get(), getXid());
                sync();
            } else {
                jc->txn_abort(dtokp.get(), getXid());
            }
        } catch (const journal::jexception& e) {
            THROW_STORE_EXCEPTION(std::string("Error commit") + e.what());
        }
    }
}
/**
 * Request recovery of queue and message state; inherited from Recoverable
 */
void
MessageStorePlugin::recover(broker::RecoveryManager& recoverer)
{
    ExchangeMap exchanges;
    QueueMap queues;
    MessageMap messages;
    MessageQueueMap messageQueueMap;
    std::vector<std::string> xids;
    PreparedTransactionMap dtxMap;

    provider->second->recoverConfigs(recoverer);
    provider->second->recoverExchanges(recoverer, exchanges);
    provider->second->recoverQueues(recoverer, queues);
    provider->second->recoverBindings(recoverer, exchanges, queues);
    // Important to recover messages before transactions in the SQL-CLFS
    // case. If this becomes a problem, it may be possible to resolve it.
    // If in doubt please raise a jira and notify Steve Huston
    // <*****@*****.**>.
    provider->second->recoverMessages(recoverer, messages, messageQueueMap);
    provider->second->recoverTransactions(recoverer, dtxMap);
    // Enqueue msgs where needed.
    for (MessageQueueMap::const_iterator i = messageQueueMap.begin();
         i != messageQueueMap.end();
         ++i) {
        // Locate the message corresponding to the current message Id
        MessageMap::const_iterator iMsg = messages.find(i->first);
        if (iMsg == messages.end()) {
            std::ostringstream oss;
            oss << "No matching message trying to re-enqueue message "
                << i->first;
            THROW_STORE_EXCEPTION(oss.str());
        }
        broker::RecoverableMessage::shared_ptr msg = iMsg->second;
        // Now for each queue referenced in the queue map, locate it
        // and re-enqueue the message.
        for (std::vector<QueueEntry>::const_iterator j = i->second.begin();
             j != i->second.end();
             ++j) {
            // Locate the queue corresponding to the current queue Id
            QueueMap::const_iterator iQ = queues.find(j->queueId);
            if (iQ == queues.end()) {
                std::ostringstream oss;
                oss << "No matching queue trying to re-enqueue message "
                    << " on queue Id " << j->queueId;
                THROW_STORE_EXCEPTION(oss.str());
            }
            // Messages involved in prepared transactions have their status
            // updated accordingly. First, though, restore a message that
            // is expected to be on a queue, including non-transacted
            // messages and those pending dequeue in a dtx.
            if (j->tplStatus != QueueEntry::ADDING)
                iQ->second->recover(msg);
            switch(j->tplStatus) {
            case QueueEntry::ADDING:
                dtxMap[j->xid]->enqueue(iQ->second, msg);
                break;
            case QueueEntry::REMOVING:
                dtxMap[j->xid]->dequeue(iQ->second, msg);
                break;
            default:
                break;
            }
        }
    }
}