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); }
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); }
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; }
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; }
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; }