コード例 #1
0
ファイル: ticket.c プロジェクト: dmuhamedagic/booth
/* is it safe to commit the grant?
 * if we didn't hear from all sites on the initial grant, we may
 * need to delay the commit
 *
 * TODO: investigate possibility to devise from history whether a
 * missing site could be holding a ticket or not
 */
static int ticket_dangerous(struct ticket_config *tk)
{
	int tdiff;
	/* we may be invoked often, don't spam the log unnecessarily
	 */
	static int no_log_delay_msg;

	if (!is_time_set(&tk->delay_commit))
		return 0;

	if (is_past(&tk->delay_commit) || all_sites_replied(tk)) {
		if (tk->leader == local) {
			tk_log_info("%s, committing to CIB",
				is_past(&tk->delay_commit) ?
				"ticket delay expired" : "all sites replied");
		}
		time_reset(&tk->delay_commit);
		no_log_delay_msg = 0;
		return 0;
	}

	tdiff = time_left(&tk->delay_commit);
	tk_log_debug("delay ticket commit for another " intfmt(tdiff));
	if (!no_log_delay_msg) {
		tk_log_info("delaying ticket commit to CIB for " intfmt(tdiff));
		tk_log_info("(or all sites are reached)");
		no_log_delay_msg = 1;
	}

	return 1;
}
コード例 #2
0
ファイル: raft.c プロジェクト: jnpkrn/booth
void elections_end(struct ticket_config *tk)
{
	struct booth_site *new_leader;

	if (is_past(&tk->election_end)) {
		/* This is previous election timed out */
		tk_log_info("elections finished");
	}

	tk->in_election = 0;
	new_leader = majority_votes(tk);
	if (new_leader == local) {
		won_elections(tk);
		tk_log_info("granted successfully here");
	} else if (new_leader) {
		tk_log_info("ticket granted at %s",
				site_string(new_leader));
	} else {
		tk_log_info("nobody won elections, new elections");
		tk->outcome = RLT_MORE;
		foreach_tkt_req(tk, notify_client);
		if (!new_election(tk, NULL, is_tie(tk) ? 2 : 0, OR_AGAIN)) {
			ticket_activate_timeout(tk);
		}
	}
}
コード例 #3
0
ファイル: ticket.c プロジェクト: dmuhamedagic/booth
static void log_reacquire_reason(struct ticket_config *tk)
{
	int valid;
	const char *where_granted = "\0";
	char buff[64];

	valid = is_time_set(&tk->term_expires) && !is_past(&tk->term_expires);

	if (tk->leader == local) {
		where_granted = "granted here";
	} else {
		snprintf(buff, sizeof(buff), "granted to %s",
			site_string(tk->leader));
		where_granted = buff;
	}

	if (!valid) {
		tk_log_warn("%s, but not valid "
			"anymore (will try to reacquire)", where_granted);
	}
	if (tk->is_granted && tk->leader != local) {
		if (tk->leader && tk->leader != no_leader) {
			tk_log_error("granted here, but also %s, "
				"that's really too bad (will try to reacquire)",
				where_granted);
		} else {
			tk_log_warn("granted here, but we're "
				"not recorded as the grantee (will try to reacquire)");
		}
	}
}
コード例 #4
0
ファイル: ticket.c プロジェクト: dmuhamedagic/booth
int disown_if_expired(struct ticket_config *tk)
{
	if (is_past(&tk->term_expires) ||
			!tk->leader) {
		disown_ticket(tk);
		return 1;
	}

	return 0;
}
コード例 #5
0
ファイル: raft.c プロジェクト: jnpkrn/booth
int new_election(struct ticket_config *tk,
	struct booth_site *preference, int update_term, cmd_reason_t reason)
{
	struct booth_site *new_leader;

	if (local->type != SITE)
		return 0;

	if ((is_reason(OR_TKT_LOST, tk) || is_reason(OR_STEPDOWN, tk)) &&
			check_attr_prereq(tk, GRANT_AUTO)) {
		tk_log_info("attribute prerequisite not met, "
			"not starting elections");
		return 0;
	}

	/* elections were already started, but not yet finished/timed out */
	if (is_time_set(&tk->election_end) && !is_past(&tk->election_end))
		return 1;

	if (ANYDEBUG) {
		int tdiff;
		if (is_time_set(&tk->election_end)) {
			tdiff = -time_left(&tk->election_end);
			tk_log_debug("starting elections, previous finished since " intfmt(tdiff));
		} else {
			tk_log_debug("starting elections");
		}
		tk_log_debug("elections caused by %s %s",
				state_to_string(reason),
				reason == OR_AGAIN ? state_to_string(tk->election_reason) : "" );
	}

	/* §5.2 */
	/* If there was _no_ answer, don't keep incrementing the term number
	 * indefinitely. If there was no peer, there'll probably be no one
	 * listening now either. However, we don't know if we were
	 * invoked due to a timeout (caller does).
	 */
	/* increment the term only if either the current term was
	 * valid or if there was a tie (in that case update_term > 1)
	 */
	if ((update_term > 1) ||
		(update_term && tk->last_valid_tk &&
			tk->last_valid_tk->current_term >= tk->current_term)) {
		/* save the previous term, we may need to send out the
		 * MY_INDEX message */
		if (tk->state != ST_CANDIDATE) {
			save_committed_tkt(tk);
		}
		tk->current_term++;
	}

	set_future_time(&tk->election_end, tk->timeout);
	tk->in_election = 1;

	tk_log_info("starting new election (term=%d)",
			tk->current_term);
	clear_election(tk);

	if(preference)
		new_leader = preference;
	else
		new_leader = (local->type == SITE) ? local : NULL;
	record_vote(tk, local, new_leader);
	tk->voted_for = new_leader;

	set_state(tk, ST_CANDIDATE);

	/* some callers may want just to repeat on timeout */
	if (reason == OR_AGAIN) {
		reason = tk->election_reason;
	} else {
		tk->election_reason = reason;
	}

	ticket_broadcast(tk, OP_REQ_VOTE, OP_VOTE_FOR, RLT_SUCCESS, reason);
	add_random_delay(tk);
	return 0;
}
コード例 #6
0
ファイル: EngAlg_3.cpp プロジェクト: deNULL/seman
void CEngSemStructure::ImpersonalVerb(int iEngNode)
{
// не применяется, если граф не собран
	if( !IsConnected() )
		return;
//	
	if( m_Nodes[iEngNode].m_MainWordNo==-1 )
		return;
	int iRusNode = m_Nodes[iEngNode].RusNode;
	if( iRusNode == -1 )
		return;

	const CSemNode& rusNode = RusStr.GetNode(iRusNode);
//
	CEngSemNode& engNode = m_Nodes[iEngNode];
	CEngSemWord& engWord = engNode.m_Words[engNode.m_MainWordNo];

	if( !engWord.HasPOS(eVERB) && !engWord.HasPOS(eMOD) )
		return;

	if( engNode.HasRelOperator("_мягк_пригласит_наклонение") ||
		engNode.HasRelOperator("_пригласит_наклонение") )
		return;

	if( engNode.m_Words[0].m_Lemma=="have" )
		return;
	if( engNode.m_Words[0].m_Lemma=="keep" )
		return;

	vector<long> inRels;
	GetIncomingRelations(iEngNode, inRels, false);
	for( int k=0; k<inRels.size(); k++ )
	{
		if( m_Nodes[m_Relations[inRels[k]].m_SourceNodeNo].m_Words[0].m_Lemma=="keep" )
			return;
	}

	if (!HasSubjAsFirstValency(engNode))
		return;

// модальный глагол
	bool bModCX = ( engNode.GetType()!=NoneRoss &&  GetRossHolder(engNode.GetType())->HasFieldValue("SF","MODL",engNode.GetUnitNo()) );
// (3|прш) + мн
	bool bCase1 = (engWord.HasOneGrammem(eThirdPerson) || is_past(engWord.GetTense()))
					&& engWord.HasOneGrammem(ePlural);

// (3|(ср&прш)) + ед
	bool bCase2 = ( engWord.HasOneGrammem(eThirdPerson)
					|| (is_past(engWord.GetTense())
						&& !engWord.HasOneGrammem(eMasculinum)
						&& !engWord.HasOneGrammem(eFeminum))
				  )
				  && engWord.HasOneGrammem(eSingular);

	if( !bCase1 && !bCase2 )
		return;

	// если есть subj
	if ( GetSubj(iEngNode) != -1 ) return;

	// для помет pass(ADR) ищем адресата	
	vector<long> outRels;
	GetOutcomingRelations(iEngNode,outRels);

	int iAdrRel = -1;
	if( HasALG(m_Nodes[iEngNode].GetType(),m_Nodes[iEngNode].GetUnitNo(),"pass(ADR)") )	
	{
		for( int i=0; i<outRels.size(); i++ )	
		{
			int iSrc = m_Nodes[m_Relations[outRels[i]].m_SourceNodeNo].m_ClauseNo;
			int iTrg = m_Nodes[m_Relations[outRels[i]].m_TargetNodeNo].m_ClauseNo;
			if( iSrc != iTrg )
				continue;

if( m_Relations[outRels[i]].m_Valency.m_RelationStr=="ADR" )			{
				iAdrRel = outRels[i];
				break;
			}
		}
	}
	
// ищем объект, который не subj
	int iObjRel = -1;
	for(int  i=0; i<outRels.size(); i++ )	
	{
		int iSrc = m_Nodes[m_Relations[outRels[i]].m_SourceNodeNo].m_ClauseNo;
		int iTrg = m_Nodes[m_Relations[outRels[i]].m_TargetNodeNo].m_ClauseNo;
		if( iSrc != iTrg )
			continue;

		if( IsObjPattern(m_Relations[outRels[i]]) )
		{
			iObjRel = outRels[i];
			break;
		}
	}

// будующий subj
	int iSubRel = iAdrRel;
	if( iSubRel==-1 )
		iSubRel = iObjRel;

// если есть кого - переведем его в subj, проставим Passive и число
	if( iSubRel != -1 )		
	{		
		m_Relations[iSubRel].m_SynReal.m_Cortege = engNode.m_Patterns[0].m_GramCorteges[0];
		m_Relations[iSubRel].m_Valency = engNode.m_Vals[0];

		m_Relations[iSubRel].m_Position = "<";
		m_Relations[iSubRel].m_PosType = FromAlgorithmPosType;
		CEngSemNode& impNode = m_Nodes[m_Relations[iSubRel].m_SourceNodeNo];
		CEngSemNode& objNode = m_Nodes[m_Relations[iSubRel].m_TargetNodeNo];
		int iImpMainWord = impNode.m_MainWordNo;
		assert( iImpMainWord != -1 );
		impNode.m_Words[iImpMainWord].m_bMorphologicalPassiveForm = true;

		int iRusObj = objNode.RusNode;
		if( iRusObj != -1 )
			TransferNumberGrammems(RusStr.GetNode(iRusObj),impNode.m_Words[iImpMainWord]);

// тот же пассив надо проставить всем "и" узлам без Subj
		for( int i=0; i<outRels.size(); i++ )
		{
			int iSrc = m_Nodes[m_Relations[outRels[i]].m_SourceNodeNo].m_ClauseNo;
			int iTrg = m_Nodes[m_Relations[outRels[i]].m_TargetNodeNo].m_ClauseNo;
			if( iSrc == iTrg )
				continue;
			if( m_Relations[outRels[i]].m_Valency.m_RelationStr != "AND" )
				continue;
			int iNode = m_Relations[outRels[i]].m_TargetNodeNo;
			if( !m_Nodes[iNode].HasPOS(eVERB) )
				continue;
			vector<long> outRels2;
			GetOutcomingRelations(iNode,outRels2);
			bool bHasSub = false;
			for( int j=0; j<outRels2.size(); j++ )
			{
				if( IsSubj(m_Relations[outRels2[j]]) )
					bHasSub = true;
			}
			if( bHasSub )
				continue;
			if( m_Nodes[iNode].m_MainWordNo == -1 )
				continue;
			m_Nodes[iNode].m_Words[m_Nodes[iNode].m_MainWordNo].m_bMorphologicalPassiveForm = true;
			if( iRusObj != -1 )
				TransferNumberGrammems(RusStr.GetNode(iRusObj),m_Nodes[iNode].m_Words[m_Nodes[iNode].m_MainWordNo]);
		}

		return;
	}

	for( int k=0; k<inRels.size(); k++ )
	{
		int iSrc = m_Nodes[m_Relations[inRels[k]].m_SourceNodeNo].m_ClauseNo;
		int iTrg = m_Nodes[m_Relations[inRels[k]].m_TargetNodeNo].m_ClauseNo;
		if( iSrc == iTrg )
			continue;
		if( m_Relations[inRels[k]].m_Valency.m_RelationStr == "AND" )
		return; // часть глагольной MUA	
	}
	
// нет объекта	
	CEngSemNode newNode;
	if( bCase1 )
	{
		CreateSimpleEnglNode("they",newNode,0,true);
		newNode.m_Words[0].AddFormGrammem (ePlural);
	}
	else if( !bModCX )
	{
		CreateSimpleEnglNode("it",newNode,0,true);
		newNode.m_Words[0].AddFormGrammem(eSingular);
	}
	else
	{
		CreateSimpleEnglNode("one",newNode,0,true);
		newNode.m_Words[0].AddFormGrammem(eSingular);
	}

	newNode.m_ClauseNo = m_Nodes[iEngNode].m_ClauseNo;

	long wNo = m_Nodes[iEngNode].GetMinWordNo();
	FreeWordNo(wNo);
	newNode.m_Words[0].m_WordNo = wNo;

	m_Nodes.push_back(newNode);

	CEngSemRelation newRel(CValency("ImpersonalVerb",A_C),iEngNode,m_Nodes.size()-1,"");
	newRel.m_bInterpreted = false;

	if (!engNode.m_Patterns.empty()  && !engNode.m_Patterns[0].m_GramCorteges.empty())
		newRel.m_SynReal.m_Cortege = engNode.m_Patterns[0].m_GramCorteges[0];

	if (!engNode.m_Vals.empty())
		newRel.m_Valency = engNode.m_Vals[0];

	newRel.m_Position = "<";
	newRel.m_PosType = FromAlgorithmPosType;
	m_Relations.push_back(newRel);		
}
コード例 #7
0
ファイル: ticket.c プロジェクト: dmuhamedagic/booth
int list_ticket(char **pdata, unsigned int *len)
{
	struct ticket_config *tk;
	char timeout_str[64];
	char pending_str[64];
	char *data, *cp;
	int i, alloc;
	time_t ts;

	*pdata = NULL;
	*len = 0;

	alloc = booth_conf->ticket_count * (BOOTH_NAME_LEN * 2 + 128);
	data = malloc(alloc);
	if (!data)
		return -ENOMEM;

	cp = data;
	foreach_ticket(i, tk) {
		if (is_time_set(&tk->term_expires)) {
			ts = wall_ts(&tk->term_expires);
			strftime(timeout_str, sizeof(timeout_str), "%F %T",
					localtime(&ts));
		} else
			strcpy(timeout_str, "INF");

		if (tk->leader == local && is_time_set(&tk->delay_commit)
				&& !is_past(&tk->delay_commit)) {
			ts = wall_ts(&tk->delay_commit);
			strcpy(pending_str, " (commit pending until ");
			strftime(pending_str + strlen(" (commit pending until "),
					sizeof(pending_str) - strlen(" (commit pending until ") - 1,
					"%F %T", localtime(&ts));
			strcat(pending_str, ")");
		} else
			*pending_str = '\0';

		cp += snprintf(cp,
				alloc - (cp - data),
				"ticket: %s, leader: %s",
				tk->name,
				ticket_leader_string(tk));

		if (is_owned(tk)) {
			cp += snprintf(cp,
					alloc - (cp - data),
					", expires: %s%s\n",
					timeout_str,
					pending_str);
		} else {
			cp += snprintf(cp, alloc - (cp - data), "\n");
		}

		if (alloc - (cp - data) <= 0) {
			free(data);
			return -ENOMEM;
		}
	}

	*pdata = data;
	*len = cp - data;

	return 0;
}