Example #1
0
void
d_readerListenerInitDataReader(
    d_readerListener listener,
    d_subscriber subscriber,
    const c_char* name,
    v_reliabilityKind reliability,
    v_historyQosKind historyKind,
    c_long historyDepth)
{
    v_readerQos readerQos;
    u_subscriber s;
    d_networkAddress unaddressed, myAddr;
    d_admin admin;
    c_char *query;
    q_expr expr;

    assert(d_objectIsValid(d_object(listener), D_LISTENER));

    if(listener && subscriber){
        readerQos = d_readerQosNew(V_DURABILITY_VOLATILE, reliability);
        readerQos->history.kind = historyKind;
        readerQos->history.depth = historyDepth;
        readerQos->lifecycle.autopurge_nowriter_samples_delay.seconds = 60;
        readerQos->lifecycle.autopurge_nowriter_samples_delay.nanoseconds = 0;
        readerQos->lifecycle.autopurge_disposed_samples_delay.seconds = 10;
        readerQos->lifecycle.autopurge_disposed_samples_delay.nanoseconds = 0;
        s = d_subscriberGetSubscriber(subscriber);
        admin       = d_subscriberGetAdmin(subscriber);
        myAddr      = d_adminGetMyAddress(admin);
        unaddressed = d_networkAddressUnaddressed();

        /*
         * Message is:
         * - meant for me or
         * - meant for all and not sent by me
         */
#define FILTER_EXPRESSION "select * from %s where " \
                          "parentMsg.addressee.systemId=%u OR " \
                          "parentMsg.addressee.systemId=%u AND " \
                          "parentMsg.senderAddress.systemId!=%u"

        query = (c_char*)(os_malloc(strlen(listener->name) +
                                    strlen(FILTER_EXPRESSION) + 32));
        os_sprintf(query, FILTER_EXPRESSION, listener->name,
                myAddr->systemId, unaddressed->systemId, myAddr->systemId);

        expr = q_parse(query);

        listener->dataReader =
                u_dataReaderNew (s, name, expr, NULL, readerQos, TRUE);

        q_dispose(expr);
        os_free(query);

#undef FILTER_EXPRESSION
        d_networkAddressFree(myAddr);
        d_networkAddressFree(unaddressed);
        d_readerQosFree(readerQos);
    }
}
/* Walk admin namespaces */
static void
areFellowNameSpacesCompatible(
    d_nameSpace adminNs,
    c_voidp args)
{
    struct compatibilityHelper* walkData;
    d_networkAddress address;
    char* localPartitions;
    char* remotePartitions;

    walkData    = (struct compatibilityHelper*)args;

    walkData->ns = adminNs;

    if (!d_fellowNameSpaceWalk(walkData->fellow, isFellowNameSpaceCompatible, walkData))
    {
        walkData->compatible = FALSE;
        localPartitions = d_nameSpaceGetPartitions(adminNs);
        remotePartitions = d_nameSpaceGetPartitions(walkData->fellowNs);
        address = d_fellowGetAddress (walkData->fellow);

        OS_REPORT_2(OS_ERROR, D_CONTEXT, 0,
            "Namespace '%s' from fellow '%d' is incompatible with local namespace.",
            d_nameSpaceGetName(adminNs), address->systemId);

        OS_REPORT_2(OS_ERROR, D_CONTEXT, 0,
            "Partition expressions are '%s'(local) and '%s'(remote).",
            localPartitions, remotePartitions);

        d_networkAddressFree(address);
        os_free (localPartitions);
        os_free (remotePartitions);
    }
}
/* Walk admin namespaces */
static void
areFellowNameSpacesCompatible(
    d_nameSpace adminNs,
    c_voidp args)
{
    struct compatibilityHelper* walkData;
    d_networkAddress address;
    char* localPartitions;
    char* remotePartitions;

    walkData    = (struct compatibilityHelper*)args;

    walkData->ns = adminNs;

    if (!d_fellowNameSpaceWalk(walkData->fellow, isFellowNameSpaceCompatible, walkData))
    {
        walkData->compatible = FALSE;
        localPartitions = d_nameSpaceGetPartitionTopics(adminNs);
        remotePartitions = d_nameSpaceGetPartitionTopics(walkData->fellowNs);
        address = d_fellowGetAddress (walkData->fellow);

        OS_REPORT_5(OS_ERROR, D_CONTEXT, 0,
            "NameSpace configuration of remote durability service '%u' for NameSpace "\
            "'%s' is incompatible with local NameSpace '%s'. Partition(-Topic) expressions "\
            "are '%s'(local) and '%s'(remote).",
            address->systemId, d_nameSpaceGetName(walkData->fellowNs),
            d_nameSpaceGetName(adminNs), localPartitions,
            remotePartitions);

        d_networkAddressFree(address);
        os_free (localPartitions);
        os_free (remotePartitions);
    }
}
void
d_statusRequestListenerAction(
    d_listener listener,
    d_message message)
{
    d_admin admin;
    d_publisher publisher;
    d_status status;
    d_networkAddress addr;

    assert(d_listenerIsValid(d_listener(listener), D_STATUS_REQ_LISTENER));

    admin = d_listenerGetAdmin(listener);
    publisher = d_adminGetPublisher(admin);
    status = d_statusNew(admin);
    addr = d_networkAddressNew (message->senderAddress.systemId,
                                message->senderAddress.localId,
                                message->senderAddress.lifecycleId);

    d_messageSetAddressee(d_message(status), addr);
    d_publisherStatusWrite(publisher, status, addr);
    d_statusFree(status);
    d_networkAddressFree(addr);
    return;
}
static void
checkFellowMasterWalk(
    void* o,
    c_voidp userData)
{
    struct checkFellowMasterHelper* helper;
    d_networkAddress master, fellow;
    d_nameSpace nameSpace;

    helper = (struct checkFellowMasterHelper*)userData;
    nameSpace = d_nameSpace(o);
    master = d_nameSpaceGetMaster (nameSpace);
    fellow = d_fellowGetAddress(helper->fellow);

    if (!d_networkAddressCompare (fellow, master)) {
        d_adminReportMaster (helper->admin, helper->fellow, nameSpace, helper->oldNameSpace);
    }

    d_networkAddressFree(master);
    d_networkAddressFree(fellow);
}
Example #6
0
void
d_readerListenerInit(
    d_readerListener listener,
    d_listenerAction action,
    d_subscriber subscriber,
    const c_char* topicName,
    const c_char* fieldName,
    v_reliabilityKind reliability,
    v_historyQosKind historyKind,
    c_long historyDepth,
    os_threadAttr attr,
    d_objectDeinitFunc deinit)
{
    c_char* readerName;
    d_networkAddress addr;
    d_admin admin;

    if(listener){
        d_listenerInit(d_listener(listener), subscriber, action, d_readerListenerDeinit);
        admin = d_listenerGetAdmin(d_listener(listener));
        readerName = (c_char*)(os_malloc(strlen(topicName) + 7));
        os_sprintf(readerName, "%sReader", topicName);

        addr = d_adminGetMyAddress(admin);
        listener->myAddr = addr->systemId;
        d_networkAddressFree(addr);

        d_readerListenerInitField(listener, subscriber, fieldName);

        listener->message                    = NULL;
        listener->waitsetData                = NULL;
        listener->name                       = os_strdup(topicName);
        listener->samplesTotal               = 0;
        listener->samplesFromMe              = 0;
        listener->samplesForMe               = 0;
        listener->lastInsertTime.seconds     = 0;
        listener->lastInsertTime.nanoseconds = 0;
        listener->lastSourceTime.seconds     = 0;
        listener->lastSourceTime.nanoseconds = 0;
        listener->attr                       = attr;
        listener->deinit                     = deinit;

        d_readerListenerInitDataReader(listener,
                                       subscriber,
                                       readerName,
                                       reliability,
                                       historyKind,
                                       historyDepth);

        os_free(readerName);
    }
}
static void
checkFellowMasterWalk(
    void* o,
    c_voidp userData)
{
    struct checkFellowMasterHelper* helper;
    d_networkAddress master, fellow;
    d_nameSpace nameSpace;

    helper = (struct checkFellowMasterHelper*)userData;
    nameSpace = d_nameSpace(o);                     /* the namespace of the fellow */
    master = d_nameSpaceGetMaster (nameSpace);      /* the master of the namespace of the fellow */
    fellow = d_fellowGetAddress(helper->fellow);    

    /* Only start checking for conflicts if the fellow is a master
     * for the namespace and the namespace is confirmed
     */
    if (!d_networkAddressCompare (fellow, master) && d_nameSpaceIsMasterConfirmed(nameSpace)) {
        d_adminReportMaster (helper->admin, helper->fellow, nameSpace, helper->oldNameSpace);
    }

    d_networkAddressFree(master);
    d_networkAddressFree(fellow);
}
static void
checkFellowMasterWalk(
    void* o,
    c_voidp userData)
{
    struct checkFellowMasterHelper* helper;
    d_networkAddress master;
    d_nameSpace nameSpace;

    helper = (struct checkFellowMasterHelper*)userData;
    nameSpace = d_nameSpace(o);
    master = d_nameSpaceGetMaster (nameSpace);

    if (d_nameSpaceIsMasterConfirmed (nameSpace)) {
        if (!d_networkAddressCompare (helper->fellow, master)) {
            d_adminReportMaster (helper->admin, nameSpace, helper->oldNameSpace);
        }
    }

    d_networkAddressFree (master);
}
void
d_nameSpacesRequestListenerReportNameSpaces(
    d_nameSpacesRequestListener listener)
{
    c_long count, i;
    d_networkAddress addr;
    d_nameSpaces ns;
    d_admin admin;
    d_publisher publisher;
    c_iter nameSpaces;

    assert(d_listenerIsValid(d_listener(listener), D_NAMESPACES_REQ_LISTENER));

    if(listener){
        addr = d_networkAddressUnaddressed();
        admin = d_listenerGetAdmin(d_listener(listener));

        assert (admin);

        publisher = d_adminGetPublisher(admin);

        /* Get list of namespaces */
        nameSpaces = updateNameSpaces(listener);

        count = c_iterLength(nameSpaces);
        for(i=0; i<count; i++){
            ns = d_nameSpaces(c_iterObject(nameSpaces, i));
            d_messageInit(d_message(ns), admin);
            d_messageSetAddressee(d_message(ns), addr);

            d_publisherNameSpacesWrite(publisher, ns, addr);
        }
        d_networkAddressFree(addr);

        /* Free namespace list */
        cleanNameSpaces (nameSpaces);
    }
    return;
}
static void
updateNameSpacesWalk (
    d_nameSpace n,
    c_iterActionArg userData)
{
    d_nameSpacesRequestListener listener;
    d_admin admin;
    d_nameSpaces ns;
    d_networkAddress master;
    struct updateNsWalkData* walkData;

    walkData = (struct updateNsWalkData*)userData;
    listener = walkData->listener;
    admin = d_listenerGetAdmin(d_listener(listener));

    /* Create nameSpaces object from namespace, update total later */
    ns = d_nameSpacesNew(admin, n, d_nameSpaceGetInitialQuality(n), 0);
    master = d_nameSpaceGetMaster(n);
    d_nameSpacesSetMaster(ns, master);
    d_networkAddressFree(master);

    /* Add namespaces object to listener */
    walkData->nameSpaces = c_iterAppend (walkData->nameSpaces, ns);
}
Example #11
0
d_nameSpaces
d_nameSpacesNew(
    d_admin admin,
    d_nameSpace nameSpace,
    d_quality initialQuality,
    c_ulong total)
{
    d_nameSpaces ns = NULL;
    d_networkAddress master;
    d_mergeState state;
    c_sequence *mergedStatesPtr;
    struct nsWalkHelper helper;

    if(nameSpace){
        ns = d_nameSpaces(os_malloc(C_SIZEOF(d_nameSpaces)));

        if(ns){
            master     = d_networkAddressUnaddressed();
            d_messageInit(d_message(ns), admin);

            ns->aligner                    = d_nameSpaceIsAligner(nameSpace);
            ns->durabilityKind             = d_nameSpaceGetDurabilityKind(nameSpace);
            ns->alignmentKind              = d_nameSpaceGetAlignmentKind(nameSpace);
            ns->partitions                 = d_nameSpaceGetPartitionTopics(nameSpace);
            ns->total                      = total;
            ns->initialQuality.seconds     = initialQuality.seconds;
            ns->initialQuality.nanoseconds = initialQuality.nanoseconds;
            ns->master.systemId            = master->systemId;
            ns->master.localId             = master->localId;
            ns->master.lifecycleId         = master->lifecycleId;
            ns->isComplete                 = TRUE;
            ns->name                       = os_strdup (d_nameSpaceGetName(nameSpace));
            ns->masterConfirmed            = d_nameSpaceIsMasterConfirmed(nameSpace);

            state = d_nameSpaceGetMergeState(nameSpace, NULL);
            if(state) {
                ns->state.role                 = os_strdup(state->role);
                ns->state.value                = state->value;
                d_mergeStateFree(state);
            } else {
                ns->state.role                 = d_nameSpaceGetRole(nameSpace);
                ns->state.value                = -1;
            }

            ns->mergedStatesCount          = d_tableSize(nameSpace->mergedRoleStates);

            if(ns->mergedStatesCount > 0){
                ns->mergedStates               = os_malloc(C_SIZEOF(d_mergeState)*ns->mergedStatesCount);

                helper.states = (d_mergeState*)(mergedStatesPtr = &(ns->mergedStates));
                helper.index = 0;

                d_tableWalk(nameSpace->mergedRoleStates, addMergeState, &helper);
            } else {
                ns->mergedStates = NULL;
            }
            d_networkAddressFree(master);
        }
    }
    return ns;
}
void
d_nameSpacesRequestListenerAction(
    d_listener listener,
    d_message message)
{
    d_durability durability;
    d_admin admin;
    d_fellow fellow;
    d_publisher publisher;
    c_ulong i, count;
    d_nameSpaces ns;
    d_networkAddress addr;
    d_nameSpacesRequest request;
    c_bool added;
    c_iter nameSpaces;

    assert(d_listenerIsValid(d_listener(listener), D_NAMESPACES_REQ_LISTENER));

    admin      = d_listenerGetAdmin(listener);
    durability = d_adminGetDurability(admin);
    addr       = d_networkAddressNew(message->senderAddress.systemId,
                                     message->senderAddress.localId,
                                     message->senderAddress.lifecycleId);
    fellow     = d_adminGetFellow(admin, addr);
    publisher  = d_adminGetPublisher(admin);

    d_printTimedEvent(durability, D_LEVEL_FINE,
            D_THREAD_NAMESPACES_REQUEST_LISTENER,
            "Received nameSpacesRequest from fellow %d.\n",
            message->senderAddress.systemId);

    /* Update nameSpaces list for listener */
    nameSpaces = updateNameSpaces(d_nameSpacesRequestListener(listener));

    if(!fellow){
        fellow = d_fellowNew(addr, message->senderState);
        d_fellowUpdateStatus(fellow, message->senderState, v_timeGet());
        added = d_adminAddFellow(admin, fellow);

        if(added == FALSE){
            d_fellowFree(fellow);
            fellow = d_adminGetFellow(admin, addr);
            assert(fellow);
        } else {
            fellow = d_adminGetFellow(admin, addr);
            d_printTimedEvent(durability, D_LEVEL_FINE,
                D_THREAD_NAMESPACES_REQUEST_LISTENER,
                "Fellow %d unknown, added to administration and requesting nameSpaces.\n",
                message->senderAddress.systemId);
            request = d_nameSpacesRequestNew(admin);
            d_messageSetAddressee(d_message(request), addr);
            d_publisherNameSpacesRequestWrite(publisher, request, addr);
            d_nameSpacesRequestFree(request);
        }
    }
    d_fellowUpdateStatus(fellow, message->senderState, v_timeGet());

    count = c_iterLength(nameSpaces);

    for(i=0; i<count; i++){
        ns = d_nameSpaces(c_iterObject(nameSpaces, i));
        d_messageInit(d_message(ns), admin);
        d_messageSetAddressee(d_message(ns), addr);
        d_publisherNameSpacesWrite(publisher, ns, addr);
    }
    cleanNameSpaces (nameSpaces);
    d_fellowFree(fellow);
    d_networkAddressFree(addr);

    return;
}
Example #13
0
void
d_nameSpacesListenerAction(
    d_listener listener,
    d_message message)
{
    d_durability durability;
    d_admin admin;
    d_publisher publisher;
    d_fellow fellow;
    c_bool allowed;
    d_nameSpace nameSpace, localNameSpace, oldFellowNameSpace;
    c_ulong count;
    d_configuration config;
    d_nameSpacesRequest nsRequest;
    d_networkAddress sender;
    d_subscriber subscriber;
    d_sampleChainListener sampleChainListener;
    struct compatibilityHelper helper;
    d_adminStatisticsInfo info;
    c_bool added;
    os_time srcTime , curTime, difTime, maxDifTime;
    struct checkFellowMasterHelper fellowMasterHelper;
    d_name role;
    c_iter fellowNameSpaces;
    d_nameSpace ns;

    assert(d_listenerIsValid(d_listener(listener), D_NAMESPACES_LISTENER));

    admin               = d_listenerGetAdmin(listener);
    publisher           = d_adminGetPublisher(admin);
    durability          = d_adminGetDurability(admin);
    config              = d_durabilityGetConfiguration(durability);
    fellowNameSpaces    = NULL;

    d_printTimedEvent         (durability, D_LEVEL_FINE,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Received nameSpace from fellow %d (his master: %d, confirmed: %d, mergeState: %s, %d).\n",
                               message->senderAddress.systemId,
                               d_nameSpaces(message)->master.systemId,
                               d_nameSpaces(message)->masterConfirmed,
                               d_nameSpaces(message)->state.role,
                               d_nameSpaces(message)->state.value);

    sender = d_networkAddressNew(message->senderAddress.systemId,
                               message->senderAddress.localId,
                               message->senderAddress.lifecycleId);

    fellow = d_adminGetFellow(admin, sender);

    if(!fellow){
        d_printTimedEvent (durability, D_LEVEL_FINE,
                           D_THREAD_NAMESPACES_LISTENER,
                           "Fellow %d unknown, administrating it.\n",
                           message->senderAddress.systemId);
        fellow = d_fellowNew(sender, message->senderState);
        d_fellowUpdateStatus(fellow, message->senderState, v_timeGet());
        added = d_adminAddFellow(admin, fellow);

        if(added == FALSE){
            d_fellowFree(fellow);
            fellow = d_adminGetFellow(admin, sender);
            assert(fellow);
        } else {
            fellow = d_adminGetFellow(admin, sender); /*Do this to allow fellowFree at the end*/
            nsRequest = d_nameSpacesRequestNew(admin);
            d_messageSetAddressee(d_message(nsRequest), sender);
            d_publisherNameSpacesRequestWrite(publisher, nsRequest, sender);
            d_nameSpacesRequestFree(nsRequest);
        }
    }
    d_fellowUpdateStatus(fellow, message->senderState, v_timeGet());

    nameSpace = d_nameSpaceFromNameSpaces(config, d_nameSpaces(message));

    if(d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_APPROVED){

        /* Get old namespace of fellow */
        oldFellowNameSpace = d_nameSpaceCopy (d_fellowGetNameSpace (fellow, nameSpace));

        /* Update master of fellow nameSpace */
        added = d_fellowAddNameSpace(fellow, nameSpace);

        /* Create namespace with local policy (if a match exists) */
        localNameSpace = d_nameSpaceNew (config, d_nameSpaceGetName(nameSpace));

        /* If namespace is created, add to administration */
        if (localNameSpace) {
            /* Copy partitions to local nameSpace */
            d_nameSpaceCopyPartitions (localNameSpace, nameSpace);
            d_adminAddNameSpace (admin, localNameSpace);
            d_nameSpaceFree (localNameSpace);
        }

        /* If fellow is master for a namespace, report it to admin */
        fellowMasterHelper.admin = admin;
        fellowMasterHelper.fellow = d_fellowGetAddress(fellow);
        fellowMasterHelper.oldNameSpace = oldFellowNameSpace;
        checkFellowMasterWalk (nameSpace, &fellowMasterHelper);
        d_free (fellowMasterHelper.fellow);

        /* If the namespace was not added to the fellow (because it already existed there), free it */
        if(!added){
            d_nameSpaceFree(nameSpace);
        }

        d_nameSpaceFree (oldFellowNameSpace);

    } else {
        info = d_adminStatisticsInfoNew();
        d_fellowSetExpectedNameSpaces(fellow, d_nameSpaces(message)->total);
        d_fellowAddNameSpace(fellow, nameSpace);
        count = d_fellowNameSpaceCount(fellow);

        if(count == d_nameSpaces(message)->total){
            allowed = isFellowStateCompatible(durability, fellow);

            if(allowed == TRUE){
                config = d_durabilityGetConfiguration(durability);
                helper.fellow = fellow;
                helper.compatible = TRUE;

                d_adminNameSpaceWalk (admin, areFellowNameSpacesCompatible, &helper);

                if(helper.compatible == TRUE){

                    if(config->timeAlignment == TRUE){
                        curTime.tv_sec     = d_readerListener(listener)->lastInsertTime.seconds;
                        curTime.tv_nsec    = d_readerListener(listener)->lastInsertTime.nanoseconds;
                        srcTime.tv_sec     = d_readerListener(listener)->lastSourceTime.seconds;
                        srcTime.tv_nsec    = d_readerListener(listener)->lastSourceTime.nanoseconds;
                        maxDifTime.tv_sec  = 1; /*1s*/
                        maxDifTime.tv_nsec = 0;
                        difTime            = os_timeAbs(os_timeSub(curTime, srcTime));

                        if(os_timeCompare(difTime, maxDifTime) == OS_MORE){
                            d_printTimedEvent (durability, D_LEVEL_WARNING,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Estimated time difference including latency with " \
                               "fellow %d is %f seconds, which is larger then " \
                               "expected.\n",
                               message->senderAddress.systemId,
                               os_timeToReal(difTime));
                            OS_REPORT_2(OS_WARNING, D_CONTEXT, 0,
                                "Estimated time difference including latency " \
                                "with fellow '%d' is larger then expected " \
                                "(%f seconds). Durability alignment might not be " \
                                "reliable. Please align time between these nodes " \
                                "and restart.",
                                message->senderAddress.systemId,
                                os_timeToReal(difTime));
                        } else {
                            d_printTimedEvent (durability, D_LEVEL_FINER,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Estimated time difference including latency with " \
                               "fellow %d is %f seconds.\n",
                               message->senderAddress.systemId,
                               os_timeToReal(difTime));
                        }
                    }

                    /* Set role of fellow (take native role from namespace) */
                    role = d_nameSpaceGetRole(nameSpace);
                    d_fellowSetRole (fellow, role);
                    os_free (role);

                    d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_APPROVED);
                    info->fellowsApprovedDif += 1;
                    subscriber = d_adminGetSubscriber(admin);
                    sampleChainListener = d_subscriberGetSampleChainListener(subscriber);

                    if(sampleChainListener){
                        d_sampleChainListenerTryFulfillChains(sampleChainListener, NULL);
                    }

                    /* Check if the fellow is master for one or more namespaces and report this to admin */
                    fellowNameSpaces = c_iterNew(NULL);

                    /* Collect fellow namespaces */
                    d_fellowNameSpaceWalk (fellow, collectFellowNsWalk, fellowNameSpaces);

                    fellowMasterHelper.admin = admin;
                    fellowMasterHelper.fellow = d_fellowGetAddress(fellow);
                    fellowMasterHelper.oldNameSpace = NULL;
                    c_iterWalk (fellowNameSpaces, checkFellowMasterWalk, &fellowMasterHelper);

                    while ((ns = c_iterTakeFirst(fellowNameSpaces))) {
                        d_nameSpaceFree(ns);
                    }
                    c_iterFree(fellowNameSpaces);

                    d_free (fellowMasterHelper.fellow);

                } else {
                    info->fellowsIncompatibleDataModelDif += 1;

                    d_printTimedEvent (durability, D_LEVEL_WARNING,
                                   D_THREAD_NAMESPACES_LISTENER,
                                   "Communication with fellow %d NOT approved, because data model is not compatible\n",
                                   message->senderAddress.systemId);
                    d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_INCOMPATIBLE_DATA_MODEL);
                }
            } else {
                info->fellowsIncompatibleStateDif += 1;
                d_printTimedEvent (durability, D_LEVEL_WARNING,
                                   D_THREAD_NAMESPACES_LISTENER,
                                   "Communication with fellow %d NOT approved, because state is not compatible my state: %d, fellow state: %d\n",
                                   message->senderAddress.systemId,
                                   d_durabilityGetState(durability),
                                   message->senderState);
                d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_INCOMPATIBLE_STATE);
            }
        } else {
            d_printTimedEvent (durability, D_LEVEL_WARNING,
                               D_THREAD_NAMESPACES_LISTENER,
                               "Received %u of %u nameSpaces from fellow %u.\n",
                               count, d_nameSpaces(message)->total,
                               message->senderAddress.systemId);
        }
        d_adminUpdateStatistics(admin, info);
        d_adminStatisticsInfoFree(info);
    }
    d_fellowFree(fellow);
    d_networkAddressFree(sender);

    return;
}
Example #14
0
void
d_statusListenerAction(
    d_listener listener,
    d_message message)
{
    d_admin admin;
    d_durability durability;
    d_fellow fellow, fellow2;
    d_networkAddress sender;
    d_timestamp receptionTime;
    c_time t;
    d_nameSpacesRequest request;
    d_publisher publisher;
    c_bool added;
    d_serviceState oldState;

    assert(d_listenerIsValid(d_listener(listener), D_STATUS_LISTENER));
    t = v_timeGet();

    receptionTime.seconds     = t.seconds;
    receptionTime.nanoseconds = t.nanoseconds;

    admin      = d_listenerGetAdmin(listener);
    durability = d_adminGetDurability(admin);
    publisher  = d_adminGetPublisher(admin);
    sender     = d_networkAddressNew(message->senderAddress.systemId,
                                     message->senderAddress.localId,
                                     message->senderAddress.lifecycleId);
    fellow     = d_adminGetFellow(admin, sender);

    if(!fellow){
        d_printTimedEvent (durability, D_LEVEL_FINE,
                           D_THREAD_STATUS_LISTENER,
                           "Fellow %d unknown, administrating it.\n",
                           message->senderAddress.systemId);
        fellow = d_fellowNew(sender, message->senderState);
        d_fellowUpdateStatus(fellow, message->senderState, receptionTime);
        added = d_adminAddFellow(admin, fellow);

        if(added == FALSE){
            d_fellowFree(fellow);
            fellow = d_adminGetFellow(admin, sender);
            d_fellowUpdateStatus(fellow, message->senderState, receptionTime);
            assert(fellow);
        } else {
            fellow = d_adminGetFellow(admin, sender); /* This allows free at the end in all cases */
            assert(fellow);
            request = d_nameSpacesRequestNew(admin);
            d_messageSetAddressee(d_message(request), sender);
            d_publisherNameSpacesRequestWrite(publisher, request, sender);
            d_nameSpacesRequestFree(request);
        }
        d_fellowFree(fellow);
    } else {
        /* Update fellow state, or remove if it terminates */
        switch(message->senderState){
            case D_STATE_TERMINATING:
            case D_STATE_TERMINATED:
                d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_TERMINATED);
                fellow2 = d_adminRemoveFellow(admin, fellow);
                d_fellowFree(fellow);

                if(fellow2){
                    d_fellowFree(fellow2);
                }
                d_printTimedEvent(durability, D_LEVEL_INFO, D_THREAD_STATUS_LISTENER, "Fellow removed from admin.\n");
                break;
            default:
                /* Update the state of the fellow */
                oldState = d_fellowGetState(fellow);

                if(oldState != message->senderState){
                    d_printTimedEvent (durability, D_LEVEL_FINE,
                               D_THREAD_STATUS_LISTENER,
                               "Updating state of fellow '%d' to '%s'.\n",
                               message->senderAddress.systemId, d_fellowStateText(message->senderState));
                }
                d_fellowUpdateStatus(fellow, message->senderState, receptionTime);
                d_fellowFree(fellow);
                break;
        }
    }
    d_networkAddressFree(sender);

    return;
}
void
d_groupRemoteListenerAction(
    d_listener listener,
    d_message message)
{
    d_newGroup remote;
    d_configuration config;
    d_durability durability;
    d_admin admin;
    d_group group, group2;
    d_fellow fellow;
    c_bool createLocally, added;
    v_duration duration;
    u_group ugroup;
    d_networkAddress addr;
    c_bool result;
    d_subscriber subscriber;
    d_sampleChainListener sampleChainListener;
    d_completeness localCompleteness;

    assert(d_listenerIsValid(d_listener(listener), D_GROUP_REMOTE_LISTENER));

    remote     = d_newGroup(message);
    admin      = d_listenerGetAdmin(listener);
    durability = d_adminGetDurability(admin);
    config     = d_durabilityGetConfiguration(durability);
    addr       = d_networkAddressNew(message->senderAddress.systemId,
                                     message->senderAddress.localId,
                                     message->senderAddress.lifecycleId);
    fellow     = d_adminGetFellow(admin, addr);

    if(remote->partition && remote->topic){
        d_printTimedEvent(durability, D_LEVEL_FINEST,
                          D_THREAD_GROUP_REMOTE_LISTENER,
                          "Received remote group '%s.%s'.\n",
                          remote->partition, remote->topic);
    }
    if(fellow){
        if(d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_APPROVED){
            if(!(remote->partition) && !(remote->topic)){
                d_fellowSetExpectedGroupCount(fellow, remote->alignerCount);
            } else {
                group = d_adminGetLocalGroup(admin, remote->partition,
                                             remote->topic, remote->durabilityKind);
                if(!group){
                    d_printTimedEvent(durability, D_LEVEL_FINE,
                                            D_THREAD_GROUP_REMOTE_LISTENER,
                                            "Received remote group %s.%s which is locally unknown.\n",
                                            remote->partition, remote->topic);

                    /* Group unknown locally, check if it is in the alignee namespace.
                     */
                    createLocally = d_adminGroupInAligneeNS(
                                                admin, remote->partition,
                                                remote->topic,
                                                remote->durabilityKind);

                    if(createLocally == TRUE){
                        group = d_groupNew(remote->partition, remote->topic,
                                           remote->durabilityKind,
                                           remote->completeness, remote->quality);
                        added = d_fellowAddGroup(fellow, group);
                        d_fellowSetExpectedGroupCount(fellow, remote->alignerCount);

                        if(added == FALSE){
                            d_groupFree(group);
                            group = d_fellowGetGroup(fellow, remote->partition,
                                                     remote->topic,
                                                     remote->durabilityKind);

                            if(group){
                                d_groupUpdate(group, remote->completeness,
                                              remote->quality);
                                d_groupFree(group);
                            }
                        }
                        /* Group unknown locally, check if it should be aligned
                         * initially.
                         */
                        createLocally = d_adminGroupInInitialAligneeNS(
                                                    admin, remote->partition,
                                                    remote->topic,
                                                    remote->durabilityKind);

                        if(createLocally == TRUE){
                            d_printTimedEvent(durability, D_LEVEL_FINE,
                                                D_THREAD_GROUP_REMOTE_LISTENER,
                                                "Remote group %s.%s in initial alignee namespace.\n",
                                                remote->partition, remote->topic);

                            duration.seconds = 0;
                            duration.nanoseconds = 10000000;

                            ugroup = u_groupNew(
                                    u_participant(d_durabilityGetService(durability)),
                                    remote->partition, remote->topic, duration);

                            if(ugroup){
                                d_printTimedEvent(durability, D_LEVEL_FINE,
                                                D_THREAD_GROUP_REMOTE_LISTENER,
                                                "Remote group %s.%s with quality %d created locally.\n",
                                                remote->partition, remote->topic, remote->quality.seconds);
                                u_entityFree(u_entity(ugroup));
                            } else {
                                d_printTimedEvent(durability, D_LEVEL_WARNING,
                                    D_THREAD_GROUP_REMOTE_LISTENER,
                                    "Remote group %s.%s with quality %d could NOT be created locally.\n",
                                    remote->partition, remote->topic, remote->quality.seconds);
                                /**
                                 * TODO: quality must not be taken over
                                 * from remote.
                                 */
                                group2 = d_groupNew(remote->partition, remote->topic,
                                               remote->durabilityKind,
                                               D_GROUP_INCOMPLETE,
                                               remote->quality);
                                result = d_groupCreationQueueAdd(
                                    d_groupRemoteListener(listener)->groupCreationQueue,
                                    group2);

                                if(result == FALSE){
                                    d_printTimedEvent(durability, D_LEVEL_FINER,
                                            D_THREAD_GROUP_REMOTE_LISTENER,
                                            "Remote group %s.%s already in creation queue. Skipping this one.\n",
                                            remote->partition, remote->topic);
                                    d_groupFree(group2);
                                }
                            }
                        } else {
                            d_printTimedEvent(durability, D_LEVEL_FINE,
                                            D_THREAD_GROUP_REMOTE_LISTENER,
                                            "Remote group %s.%s in alignee namespace, but not initial.\n",
                                            remote->partition, remote->topic);
                        }
                    } else {
                        d_printTimedEvent(durability, D_LEVEL_INFO,
                            D_THREAD_GROUP_REMOTE_LISTENER,
                            "Remote group '%s.%s' is not in alignee namespace.\n",
                            remote->partition, remote->topic);
                    }
                } else {
                    localCompleteness = d_groupGetCompleteness(group);
                    group = d_fellowGetGroup(fellow, remote->partition,
                                                     remote->topic,
                                                     remote->durabilityKind);

                    if(group){
                        d_groupUpdate(group, remote->completeness,
                                      remote->quality);
                        d_printTimedEvent(durability, D_LEVEL_FINEST,
                              D_THREAD_GROUP_REMOTE_LISTENER,
                              "Updating remote group '%s.%s' completeness: '%d'.\n",
                              remote->partition, remote->topic, remote->completeness);
						d_groupFree(group);
                    } else if(localCompleteness != D_GROUP_COMPLETE){
                        group = d_groupNew(remote->partition, remote->topic,
                                           remote->durabilityKind,
                                           remote->completeness, remote->quality);
                        added = d_fellowAddGroup(fellow, group);

                        if(added == FALSE){
                            d_groupFree(group);
                            group = d_fellowGetGroup(fellow, remote->partition,
                                                     remote->topic,
                                                     remote->durabilityKind);

                            if(group){
                                d_groupUpdate(group, remote->completeness,
                                              remote->quality);
                                d_groupFree(group);
                            }
                        } else {

                            d_printTimedEvent(durability, D_LEVEL_FINEST,
                                                      D_THREAD_GROUP_REMOTE_LISTENER,
                                                      "Remote group '%s.%s' with completeness: '%d' registered for fellow.\n",
                                                      remote->partition, remote->topic, remote->completeness);
                        }
                    }
                    /* A complete group might be interesting in case there are
                     * still unfullfilled chain requests.
                     */
                    if(remote->completeness == D_GROUP_COMPLETE){
                        d_printTimedEvent(durability, D_LEVEL_FINEST,
                                                  D_THREAD_GROUP_REMOTE_LISTENER,
                                                  "Remote group '%s.%s' complete, check for unfullfilled chains.\n",
                                                  remote->partition, remote->topic);
                        subscriber = d_adminGetSubscriber(admin);
                        sampleChainListener = d_subscriberGetSampleChainListener(subscriber);

                        group = d_groupNew(remote->partition, remote->topic,
                                           remote->durabilityKind,
                                           remote->completeness, remote->quality);

                        d_sampleChainListenerTryFulfillChains(sampleChainListener, group);

                        d_groupFree(group);
                    }
                }
            }
        } else {
            d_printTimedEvent(durability, D_LEVEL_WARNING,
                       D_THREAD_GROUP_REMOTE_LISTENER,
                      "Fellow not approved, so ignore the message.\n");
        }
        d_fellowFree(fellow);
    } else {
        d_printTimedEvent(durability, D_LEVEL_WARNING,
                D_THREAD_GROUP_REMOTE_LISTENER,
                "Fellow unknown so far, so ignore the message.\n");
    }
    d_networkAddressFree(addr);

    return;
}