Ejemplo n.º 1
0
mama_status
mamaPublisher_sendFromInbox (mamaPublisher  publisher,
                             mamaInbox      inbox,
                             mamaMsg        msg)
{
    mamaPublisherImpl* impl     = (mamaPublisherImpl*)publisher;
    mama_status        status; 
    mamaStatsCollector tportStatsCollector = NULL;

    if (!impl) return MAMA_STATUS_NULL_ARG;
    if (!impl->mMamaPublisherBridgeImpl) return MAMA_STATUS_INVALID_ARG;
    if (!impl->mBridgeImpl) return MAMA_STATUS_NO_BRIDGE_IMPL;

    status = impl->mBridgeImpl->bridgeMamaPublisherSendFromInbox
        (impl->mMamaPublisherBridgeImpl,
         inbox,
         msg);
    if (status == MAMA_STATUS_OK)
    {
        if (gGenerateTransportStats)
        {
            tportStatsCollector = mamaTransport_getStatsCollector (impl->mTport);
        }
        if (tportStatsCollector)
            mamaStatsCollector_incrementStat (tportStatsCollector, MamaStatPublisherInboxSend.mFid);

        if (mamaInternal_getGlobalStatsCollector() != NULL)
            mamaStatsCollector_incrementStat (mamaInternal_getGlobalStatsCollector(),
                    MamaStatPublisherInboxSend.mFid);

    }

    return status;
}
Ejemplo n.º 2
0
mama_status
mamaPublisher_sendReplyToInbox (mamaPublisher publisher,
                                mamaMsg       request,
                                mamaMsg       reply)
{
    mamaPublisherImpl* impl     = (mamaPublisherImpl*)publisher;
    mama_status         status; 
    mamaStatsCollector tportStatsCollector = NULL;

    if (!impl) return MAMA_STATUS_NULL_ARG;
    if (!impl->mMamaPublisherBridgeImpl) return MAMA_STATUS_INVALID_ARG;
    if (!impl->mBridgeImpl) return MAMA_STATUS_NO_BRIDGE_IMPL;
    if (!request)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR, "mamaPublisher_sendReplyToInbox() :"
                  "NULL request message.");
        return MAMA_STATUS_INVALID_ARG;
    }

    if (!reply)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR, "mamaPublisher_sendReplyToInbox(): "
                  "NULL reply message.");
        return MAMA_STATUS_INVALID_ARG;
    }

    if (!mamaMsg_isFromInbox (request))
    {
        mama_log (MAMA_LOG_LEVEL_ERROR, "mamaPublisher_sendReplyToInbox(): "
                  "Request message not from an inbox.");
        return MAMA_STATUS_INVALID_ARG;
    }
    status = impl->mBridgeImpl->bridgeMamaPublisherSendReplyToInbox
        (impl->mMamaPublisherBridgeImpl,
         request,
         reply);
    if (status == MAMA_STATUS_OK)
    {
        if (gGenerateTransportStats)
        {
            tportStatsCollector = mamaTransport_getStatsCollector (impl->mTport);
        }
        if (tportStatsCollector)
            mamaStatsCollector_incrementStat (tportStatsCollector, MamaStatPublisherReplySend.mFid);

        if (mamaInternal_getGlobalStatsCollector() != NULL)
            mamaStatsCollector_incrementStat (mamaInternal_getGlobalStatsCollector(),
                    MamaStatPublisherReplySend.mFid);

    }

    return status;
}
Ejemplo n.º 3
0
mama_status
mamaPublisher_sendReplyToInboxHandle (mamaPublisher publisher,
                                      mamaMsgReply  replyAddress,
                                      mamaMsg       reply)
{
    mamaPublisherImpl*  impl        = (mamaPublisherImpl*)publisher;
    mamaMsgReplyImpl*   replyStruct = ( mamaMsgReplyImpl *)replyAddress;
    mama_status         status; 
    mamaStatsCollector tportStatsCollector = NULL;


    if (!impl) return MAMA_STATUS_NULL_ARG;
    if (!impl->mMamaPublisherBridgeImpl) return MAMA_STATUS_INVALID_ARG;
    if (!impl->mBridgeImpl) return MAMA_STATUS_NO_BRIDGE_IMPL;

    if (!replyAddress)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR, "mamaPublisher_sendReplyToInbox() :"
                  "NULL reply handle message.");
        return MAMA_STATUS_INVALID_ARG;
    }

    if (!reply)
    {
        mama_log (MAMA_LOG_LEVEL_ERROR, "mamaPublisher_sendReplyToInbox(): "
                  "NULL reply message.");
        return MAMA_STATUS_INVALID_ARG;
    }


    status = impl->mBridgeImpl->bridgeMamaPublisherSendReplyToInboxHandle
        (impl->mMamaPublisherBridgeImpl,
         replyStruct->replyHandle,
         reply);
    if (status == MAMA_STATUS_OK)
    {
        if (gGenerateTransportStats)
        {
            tportStatsCollector = mamaTransport_getStatsCollector (impl->mTport);
        }
        if (tportStatsCollector)
            mamaStatsCollector_incrementStat (tportStatsCollector, MamaStatPublisherReplySend.mFid);

        if (mamaInternal_getGlobalStatsCollector() != NULL)
            mamaStatsCollector_incrementStat (mamaInternal_getGlobalStatsCollector(),
                    MamaStatPublisherReplySend.mFid);

    }

    return status;
}
Ejemplo n.º 4
0
mama_status 
dqStrategy_checkSeqNum (dqStrategy      strategy, 
                        mamaMsg         msg, 
                        int             msgType, 
                        mamaDqContext*  ctx)
{
    mama_seqnum_t    seqNum         = 0;
    mama_seqnum_t    ctxSeqNum      = ctx->mSeqNum;
    mama_u64_t       senderId       = 0;
    mama_u64_t       ctxSenderId    = ctx->mSenderId;
    dqState          ctxDqState     = ctx->mDQState;
    mamaSubscription subscription   = self->mSubscription;
    mama_u16_t       conflateCnt    = 1;
    wombat_subscriptionGapCB onGap  = NULL;
    mamaTransport    transport; 
    mamaStatsCollector transportStatsCollector = NULL;
    wombat_subscriptionQualityCB onQuality = NULL;
    mamaMsgStatus    msgStatus      = MAMA_MSG_STATUS_UNKNOWN;
    mamaTransport    tport        = NULL;

    mamaSubscription_getTransport (self->mSubscription, &tport);
    
    mamaMsg_getSeqNum (msg, &seqNum);

    ctx->mDoNotForward = 0;
    if (mamaMsg_getU64 (msg, MamaFieldSenderId.mName, MamaFieldSenderId.mFid, 
                        &senderId) != MAMA_STATUS_OK)
    {
        /* We just ignore it as we might be running against an older FH */
        senderId = 0;
    }

    /*Special case for dealing with a fault tolerant takeover*/
    if (ctxSenderId != 0 && senderId != 0 && ctxSenderId != senderId)
    {
        /* Only record FT Takeovers per transport and globally */
        if (gGenerateTransportStats)
        {
            mamaSubscription_getTransport (subscription, &transport);
            transportStatsCollector = mamaTransport_getStatsCollector (transport);

            mamaStatsCollector_incrementStat (transportStatsCollector, 
                                              MamaStatFtTakeovers.mFid);
        }
        if (mamaInternal_getGlobalStatsCollector() != NULL)
        {
            mamaStatsCollector_incrementStat (mamaInternal_getGlobalStatsCollector(), 
                                              MamaStatFtTakeovers.mFid);
        }
        if (DQ_FT_WAIT_FOR_RECAP==mamaTransportImpl_getFtStrategyScheme(tport))
        {
            ctx->mDoNotForward = 1;
            handleFTTakeover (strategy, msg, msgType, ctx, seqNum, senderId, 1);
        }
        else
        {
            return handleFTTakeover (strategy, msg, msgType, ctx, seqNum, senderId, 0);
        }
    }

    if (gMamaLogLevel >= MAMA_LOG_LEVEL_FINEST)
    {
        const char*  symbol = NULL;
        mamaSubscription_getSymbol (subscription, &symbol);
        symbol = symbol == NULL ? "" : symbol;
        mama_log (MAMA_LOG_LEVEL_FINEST,
                  "dqStrategy_checkSeqNum(): %s : seq# %ld",
                  symbol, 
                  seqNum);
    }

    switch (msgType)
    {
    case MAMA_MSG_TYPE_QUOTE:
    case MAMA_MSG_TYPE_TRADE:
    case MAMA_MSG_TYPE_UPDATE:
    default:
        if (MAMA_STATUS_OK != mamaMsg_getU16 (msg,
                          MamaFieldConflateCount.mName, 
                          MamaFieldConflateCount.mFid, 
                          &conflateCnt))
        {
            /*Need to set conflateCnt=1 as mamaMsg_getU16 sets conflateCnt=0 
            if not found */
            conflateCnt = 1;
        }
    /* Deliberate fallthrough.  Only the types above can be conflated, so only 
       try to extract the conflate count field for those types. */
    case MAMA_MSG_TYPE_SEC_STATUS:
    case MAMA_MSG_TYPE_BOOK_UPDATE:
        if (((ctxDqState == DQ_STATE_NOT_ESTABLISHED) ||
             (seqNum == 0) ||
             (seqNum == (ctxSeqNum + conflateCnt))) &&
             ((ctxDqState != DQ_STATE_WAITING_FOR_RECAP) ||
             (ctxDqState != DQ_STATE_WAITING_FOR_RECAP_AFTER_FT)))
        {
            /* No gap */
            if (self->mTryToFillGap)
            {
                self->mTryToFillGap = 0;
                dqContext_clearCache (ctx, 0);
            }

            /* It is no longer the case that all subscriptions are possibly
               stale. */
            mamaSubscription_unsetAllPossiblyStale (subscription);
            /* If the sequence numbers for a message are correct then the
               subscription is OK. */
                
            msgStatus = mamaMsgStatus_statusForMsg (msg);
            /* Check the status of the message.  If it is stale,
               do not request a recap and do not set status OK. */
            if (msgStatus == MAMA_MSG_STATUS_OK) 
		    {
                resetDqState (strategy, ctx);

                ctx->mSeqNum = seqNum; 
                return MAMA_STATUS_OK;
            }
        }

        /* For late joins or middlewares that support a publish cache, it is possible that you will get old updates
           in this case take no action */
        if (DQ_SCHEME_INGORE_DUPS == mamaTransportImpl_getDqStrategyScheme(tport))
        {
            if ((seqNum <= ctxSeqNum) && ((ctx->mDQState != DQ_STATE_WAITING_FOR_RECAP) &&
                                          (ctx->mDQState != DQ_STATE_WAITING_FOR_RECAP_AFTER_FT)))
            {
                ctx->mDoNotForward = 1;
                return MAMA_STATUS_OK;
            }
        }

        if ((seqNum == ctxSeqNum) && (ctxDqState != DQ_STATE_WAITING_FOR_RECAP_AFTER_FT))
        {
            /* Duplicate data - set DQQuality to DUPLICATE, invoke quality callback */
            ctx->mDQState = DQ_STATE_DUPLICATE; 
            if ((onQuality = (mamaSubscription_getUserCallbacks (subscription))->onQuality))
            {
                void*               closure = NULL;
                const char* symbol = NULL;
                short       cause;
                const void* platformInfo = NULL;
                mamaSubscription_getClosure (subscription, &closure);
                mamaSubscription_getSymbol (subscription, &symbol);
                mamaSubscription_getAdvisoryCauseAndPlatformInfo (
                                                            subscription,
                                                            &cause, &platformInfo);
                onQuality (subscription, MAMA_QUALITY_DUPLICATE, symbol,
                           cause, platformInfo, closure);
            }
            msgUtils_setStatus (msg, MAMA_MSG_STATUS_DUPLICATE);
            return MAMA_STATUS_OK;
        }
      
        if (ctxDqState == DQ_STATE_WAITING_FOR_RECAP_AFTER_FT)
        {
            ctx->mDoNotForward = 1;
            return MAMA_STATUS_OK;
        }
        else
        {
        /* If we get here, we missed a sequence number. */
         if ((PRE_INITIAL_SCHEME_ON_GAP==mamaTransportImpl_getPreInitialScheme(tport))
                &&(self->mTryToFillGap))
        {
            self->mTryToFillGap = 0;
            if (dqContext_fillGap (ctx, seqNum, subscription))
            {
                /* we filled it */
                dqContext_clearCache (ctx, 0);
                ctx->mSeqNum = seqNum;
                return MAMA_STATUS_OK;
            }
            dqContext_clearCache (ctx, 0);
        }

        if (gMamaLogLevel >= MAMA_LOG_LEVEL_FINE)
        {
            const char*  symbol = NULL;
            mamaSubscription_getSymbol (subscription, &symbol);
            symbol = symbol == NULL ? "" : symbol;
            mama_log (MAMA_LOG_LEVEL_FINE, "%s : SeqNum gap (%ld-%ld)",
                      symbol, ctxSeqNum+1, seqNum-1);
        }

        if ((onGap = 
            (mamaSubscription_getUserCallbacks (subscription)->onGap)))
        {
            void* closure = NULL;
            mamaSubscription_getClosure (subscription, &closure);
            onGap (subscription, closure);
        }

        handleStaleData (self, msg, ctx);
        }
        break;
    case MAMA_MSG_TYPE_INITIAL      :
    case MAMA_MSG_TYPE_BOOK_INITIAL :
        msgStatus = MAMA_MSG_STATUS_UNKNOWN;

        self->mTryToFillGap = 1;

        msgStatus = mamaMsgStatus_statusForMsg (msg);
        /* Check the status of the message.  If it is stale,
           do not request a recap and do not set status OK. */
        if ((msgStatus == MAMA_MSG_STATUS_POSSIBLY_STALE) ||
            (msgStatus == MAMA_MSG_STATUS_STALE))
        {
            ctx->mDQState = DQ_STATE_STALE_NO_RECAP; 
            dqStrategyImpl_resetDqContext (ctx, seqNum, senderId); 
            return MAMA_STATUS_OK; 
        }
    case MAMA_MSG_TYPE_RECAP        :
    case MAMA_MSG_TYPE_BOOK_RECAP   :
    /* For late joins or middlewares that support a publish cache, it is possible that you will get old updates
       in this case take no action */
        if (DQ_SCHEME_INGORE_DUPS == mamaTransportImpl_getDqStrategyScheme(tport))
        {
            if (MAMA_MSG_TYPE_RECAP == msgType)
            {
                /* Feed-handlers maintain sequence number for a Record FT Recap. */
                if ((seqNum <= ctxSeqNum) && ((ctx->mDQState != DQ_STATE_WAITING_FOR_RECAP) &&
                                              (ctx->mDQState != DQ_STATE_WAITING_FOR_RECAP_AFTER_FT)))
                {
                    ctx->mDoNotForward = 1;
                    return MAMA_STATUS_OK;
                }
            }
            else if (MAMA_MSG_TYPE_BOOK_RECAP == msgType)
            {
                if (0 == seqNum && ctxSeqNum > 0)
                {
                    /* Special case of an FT Order Book Recap where a SeqNum of 0 is used. */
                    if (ctx->mDQState != DQ_STATE_WAITING_FOR_RECAP_AFTER_FT)
                    {
                        ctx->mDoNotForward = 1;
                        return MAMA_STATUS_OK;
                    }
                }
                /* Solicited Recap from Feed-Handler or
                 * solicited / unsolicited Recap from mid-tier. */
                else if ((seqNum <= ctxSeqNum) && ((ctx->mDQState != DQ_STATE_WAITING_FOR_RECAP) &&
                                                   (ctx->mDQState != DQ_STATE_WAITING_FOR_RECAP_AFTER_FT)))
                {
                    ctx->mDoNotForward = 1;
                    return MAMA_STATUS_OK;
                }
            }
        }

        if (mamaTransportImpl_preRecapCacheEnabled (tport))
        {
            self->mTryToFillGap = 1;
        }
        mamaSubscription_unsetAllPossiblyStale (subscription);
        resetDqState (strategy, ctx);
        dqStrategyImpl_resetDqContext (ctx, seqNum, senderId);
        ctx->mDoNotForward = 0;
        return MAMA_STATUS_OK;
    case MAMA_MSG_TYPE_DDICT_SNAPSHOT : /*No DQ checking for Datadictionary*/
        return MAMA_STATUS_OK;
    }
    return MAMA_STATUS_OK;
}