Esempio n. 1
0
    def checkLimits(self, user_obj):
        result = CanStayOnlineResult()

        if CHARGE_DEBUG:
            toLog("checkLimits called for %s" % user_obj.getUserID(),
                  LOG_DEBUG)

        credit = user_obj.calcCurrentCredit()
        if credit <= 0:  #now set reasons for all instances to credit finished
            result.setKillForAllInstances(
                errorText("USER_LOGIN", "CREDIT_FINISHED", False),
                user_obj.instances)
            return result

        credit_usage_per_second = 0
        earliest_rule_end = defs.MAXLONG
        next_more_applicable = defs.MAXLONG
        seconds_from_morning = secondsFromMorning()

        for _index in range(user_obj.instances):
            if not user_obj.charge_info.accounting_started[_index]:
                continue

            cur_rule = user_obj.charge_info.effective_rules[_index]

            # find new rule
            try:
                effective_rule = self.getEffectiveRule(user_obj, _index + 1)
            except LoginException, e:
                result.addInstanceToKill(_index + 1, e.getErrorText())
                continue

            if cur_rule != effective_rule:

                cur_rule.end(user_obj, _index + 1)
                effective_rule.start(user_obj, _index + 1)

                #change current effective rule
                user_obj.charge_info.setEffectiveRule(_index + 1,
                                                      effective_rule)

            # if effective_rule ras or port are wildcards
            if effective_rule.priority < 3:
                #check if a more applicable rule (ras or ports are specified)
                #can be used before this rule ends
                next_more_applicable_rule = self.getNextMoreApplicableRule(
                    user_obj, _index + 1)
                if next_more_applicable_rule != None:
                    next_more_applicable = min(
                        next_more_applicable_rule.interval.getStartSeconds() -
                        seconds_from_morning, next_more_applicable)

            earliest_rule_end = min(
                earliest_rule_end,
                effective_rule.interval.getEndSeconds() -
                seconds_from_morning +
                1)  #+1 to ensure we don't run at 23:59:59 or such times

            credit_usage_per_second += effective_rule.cpm / 60.0 + \
                                        effective_rule.cpk * effective_rule.assumed_kps
Esempio n. 2
0
    def checkLimits(self,user_obj):
	result=CanStayOnlineResult()

	credit=user_obj.calcCurrentCredit()
	if credit<=0: #now set reasons for all instances to credit finished
 	    result.setKillForAllInstances(errorText("USER_LOGIN","CREDIT_FINISHED",False),user_obj.instances)
	    return result

	credit_usage_per_second=0
	earliest_rule_end=defs.MAXLONG
	next_more_applicable=defs.MAXLONG
	seconds_from_morning=secondsFromMorning()
	
	for _index in range(user_obj.instances):
	    cur_rule = user_obj.charge_info.effective_rules[_index]
	    
	    # find new rule
	    try:
		effective_rule = self.getEffectiveRule(user_obj,_index+1)
	    except LoginException,e:
		result.addInstanceToKill(_index+1,str(e))
		continue
	    
	    if cur_rule != effective_rule:

		cur_rule.end(user_obj, _index+1)
		effective_rule.start(user_obj,_index+1)
	
	
	    # if effective_rule ras or port are wildcards
	    if effective_rule.priority < 3: 
		#check if a more applicable rule (ras or ports are specified) 
	        #can be used before this rule ends
		next_more_applicable_rule=self.getNextMoreApplicableRule(user_obj,_index+1) 
		if next_more_applicable_rule!=None:
		    next_more_applicable=min(next_more_applicable_rule.interval.getStartSeconds()-seconds_from_morning,next_more_applicable)
		    
	    #change current effective rule
	    user_obj.charge_info.effective_rules[_index] = effective_rule
	
	    earliest_rule_end=min(earliest_rule_end,effective_rule.interval.getEndSeconds()-seconds_from_morning+1)#+1 to ensure we don't run at 23:59:59 or such times

	    credit_usage_per_second += effective_rule.cpm / 60.0 + \
					effective_rule.cpk * effective_rule.assumed_kps
Esempio n. 3
0
    def checkLimits(self,user_obj,before_start_accounting=False):
        """
            Check Limits and return a CanStayOnlineResult
            The remaining time returned is the time until one of instances should be killed
            This works for no-multilogin and multilogin rases
            
            before_start_accounting(boolean): for no-multilogin session, we want to know how much user can talk
                                              before the start accounting. So we should set this to True 
        """
        result=CanStayOnlineResult()

        credit=user_obj.calcCurrentCredit()
        if credit<=0: #now set reasons for all instances to credit finished
            result.setKillForAllInstances(errorText("USER_LOGIN","CREDIT_FINISHED",False),user_obj.instances)
            return result

        start=time.time()

        playing={}
        for instance in range(1,user_obj.instances+1):
            if before_start_accounting or user_obj.charge_info.accounting_started[instance-1]:
                playing[instance]={"call_start_time":user_obj.getTypeObj().getCallStartTime(instance)}
                playing[instance]["call_start_rule"]=self._getEffectiveRuleForTime(user_obj,instance,playing[instance]["call_start_time"])
                playing[instance]["call_start_prefix"]=playing[instance]["call_start_rule"].getPrefixObj(user_obj,instance,not before_start_accounting)

        if CHARGE_DEBUG:
            toLog("Playing Dic: %s"%playing, LOG_DEBUG)
        #playing instances, those who have accounting started
        
        remaining_time = 0
        first_iter = True #is this the first iteration? first iteration is important because it examines current state of user
        break_loop = False
        while not break_loop: #continue until one of instances should be killed
                              #this works well on single login sessions, that we want to know when user should
                              #be killed at start of session
                              #for multi login users, we do the loop just once
            credit_usage_per_second=0
            credit_finish_time=defs.MAXLONG
            earliest_rule_end=defs.MAXLONG
            next_more_applicable=defs.MAXLONG
            free_seconds_end=defs.MAXLONG #if user has free seconds remaining from first rule

            seconds_from_morning=secondsFromMorning(start)

            no_effective_rule=0 #number of instances without effective rule for this iteration

            if CHARGE_DEBUG:
                toLog("Loop Start: %s first_iter: %s remaining_time: %s before_start_accounting=%s"%(start,first_iter,remaining_time, before_start_accounting),LOG_DEBUG)


            for instance in playing.keys():


                try:
                    effective_rule = self._getEffectiveRuleForTime(user_obj,instance,start)
                except LoginException,e:
                    no_effective_rule += 1
                    
                    if first_iter:
                        result.addInstanceToKill(instance,str(e))
                        del(playing[instance])
                    else:
                        break_loop=True
                    continue
        
                if first_iter and not before_start_accounting:
                    #change effective rule
                    cur_rule=user_obj.charge_info.effective_rules[instance-1]
                    if  cur_rule!= effective_rule:

                        cur_rule.end(user_obj, instance)
                        effective_rule.start(user_obj,instance)

                        user_obj.charge_info.setEffectiveRule(instance, effective_rule)

                        
                    
                # if effective_rule ras or port are wildcards
                if effective_rule.priority < 3: 
                    #check if a more applicable rule (ras or ports are specified) 
                    #can be used before this rule ends
                    next_more_applicable_rule=self._getNextMoreApplicableRuleForTime(user_obj, instance, effective_rule, start) 
                    if next_more_applicable_rule!=None:
                        next_more_applicable=min(next_more_applicable_rule.interval.getStartSeconds()-seconds_from_morning,next_more_applicable)
                        
                earliest_rule_end=min(earliest_rule_end,effective_rule.interval.getEndSeconds()-seconds_from_morning+1)
    
                #check free seconds
                if start - playing[instance]["call_start_time"] < playing[instance]["call_start_prefix"].getFreeSeconds():
                    free_seconds_end=min(free_seconds_end,playing[instance]["call_start_prefix"].getFreeSeconds() - (start - playing[instance]["call_start_time"]) )
                else:
                    credit_usage_per_second += effective_rule.getPrefixObj(user_obj,instance,False).getCPM() / 60.0
            #end for

            #if all instances knocked out because of no effective rule
            if not len(playing) or no_effective_rule==len(playing): 
                break

            if credit_usage_per_second:
                credit_finish_time = credit / credit_usage_per_second
                
            next_event = min(earliest_rule_end,next_more_applicable,credit_finish_time,free_seconds_end)

            # we should have at least one increment
            if next_event < 1:
                next_event = 1

                toLog("VoIPCharge:Next Event is zero credit: %s credit_usage_per: %s remaining_time: %s next_event: %s credit_finish_time: %s free_seconds_end: %s earliest_rule_end: %s next_more_applicable: %s seconds_from_morning: %s"% \
                (credit,credit_usage_per_second,remaining_time,next_event,credit_finish_time,free_seconds_end,earliest_rule_end,next_more_applicable,seconds_from_morning) \
                ,LOG_ERROR)
        
            #reduce the temp credit
            if credit_usage_per_second:
                credit -= next_event * credit_usage_per_second
                if credit <= 0:
                    break_loop=True
        
            remaining_time += next_event
            # don't go for more than 1 week, who can talk for one week? ;)
            # this may happen if cpm is 0
            if remaining_time > 7 * 24 * 3600 : 
                break_loop = True

            first_iter = False

            start += next_event

            if CHARGE_DEBUG:
                toLog("Loop End: credit: %s credit_usage_per: %s remaining_time: %s next_event: %s credit_finish_time: %s free_seconds_end: %s earliest_rule_end: %s next_more_applicable: %s seconds_from_morning: %s"% \
                (credit,credit_usage_per_second,remaining_time,next_event,credit_finish_time,free_seconds_end,earliest_rule_end,next_more_applicable,seconds_from_morning) \
                ,LOG_DEBUG)
        
            if not before_start_accounting:
                break_loop=True
Esempio n. 4
0
    def checkLimits(self,user_obj,before_start_accounting=False):
	"""
	    Check Limits and return a CanStayOnlineResult
	    The remaining time returned is the time until one of instances should be killed
	    This works for no-multilogin and multilogin rases
	    
	    before_start_accounting(boolean): for no-multilogin session, we want to know how much user can talk
					      before the start accounting. So we should set this to True 
	"""
	result=CanStayOnlineResult()

	credit=user_obj.calcCurrentCredit()
	if credit<=0: #now set reasons for all instances to credit finished
 	    result.setKillForAllInstances(errorText("USER_LOGIN","CREDIT_FINISHED"),user_obj.instances)
	    return result

	start=time.time()

	playing={}
	for instance in range(1,user_obj.instances+1):
	    if before_start_accounting or user_obj.charge_info.accounting_started[instance-1]:
		playing[instance]={"call_start_time":user_obj.getTypeObj().getCallStartTime(instance)}
		playing[instance]["call_start_rule"]=self._getEffectiveRuleForTime(user_obj,instance,playing[instance]["call_start_time"])
		playing[instance]["call_start_prefix"]=playing[instance]["call_start_rule"].getPrefixObj(user_obj,instance,not before_start_accounting)

	if CHARGE_DEBUG:
	    toLog("Playing Dic: %s"%playing, LOG_DEBUG)
	#playing instances, those who have accounting started
    	
	remaining_time = 0
	first_iter = True #is this the first iteration? first iteration is important because it examines current state of user
	break_loop = False
	while not break_loop: #continue until one of instances should be killed
			      #this works well on single login sessions, that we want to know when user should
			      #be killed at start of session
			      #for multi login users, we do the loop just once
	    credit_usage_per_second=0
	    credit_finish_time=defs.MAXLONG
	    earliest_rule_end=defs.MAXLONG
	    next_more_applicable=defs.MAXLONG
	    free_seconds_end=defs.MAXLONG #if user has free seconds remaining from first rule

	    seconds_from_morning=secondsFromMorning(start)

	    no_effective_rule=0 #number of instances without effective rule for this iteration

	    if CHARGE_DEBUG:
		toLog("Loop Start: %s first_iter: %s remaining_time: %s"%(start,first_iter,remaining_time),LOG_DEBUG)


	    for instance in playing.keys():


	        try:
		    effective_rule = self._getEffectiveRuleForTime(user_obj,instance,start)
	        except LoginException,e:
		    no_effective_rule += 1
		    
		    if first_iter:
			result.addInstanceToKill(instance,str(e))
			del(playing[instance])
		    else:
			break_loop=True
		    continue
	
		if first_iter:
		    #change effective rule
		    cur_rule=user_obj.charge_info.effective_rules[instance-1]
		    if  cur_rule!= effective_rule:

	    	        cur_rule.end(user_obj, instance)
	    		effective_rule.start(user_obj,instance)

			user_obj.charge_info.effective_rules[instance-1] = effective_rule
			
		    
		# if effective_rule ras or port are wildcards
	        if effective_rule.priority < 3: 
		    #check if a more applicable rule (ras or ports are specified) 
	            #can be used before this rule ends
		    next_more_applicable_rule=self._getNextMoreApplicableRuleForTime(user_obj, instance, effective_rule, start) 
		    if next_more_applicable_rule!=None:
			next_more_applicable=min(next_more_applicable_rule.interval.getStartSeconds()-seconds_from_morning,next_more_applicable)
			
		earliest_rule_end=min(earliest_rule_end,effective_rule.interval.getEndSeconds()-seconds_from_morning+1)#+1 to ensure we don't run at 23:59:59 or such times

		#check free seconds
		if start - playing[instance]["call_start_time"] < playing[instance]["call_start_prefix"].getFreeSeconds():
		    free_seconds_end=min(free_seconds_end,playing[instance]["call_start_prefix"].getFreeSeconds() - (start - playing[instance]["call_start_time"]) )
		else:
		    credit_usage_per_second += effective_rule.getPrefixObj(user_obj,instance,False).getCPM() / 60.0
	    #end for

	    #if all instances knocked out because of no effective rule
	    if not len(playing) or no_effective_rule==len(playing): 
		break

	    if credit_usage_per_second:
		credit_finish_time = credit / credit_usage_per_second
		
	    next_event = min(earliest_rule_end,next_more_applicable,credit_finish_time,free_seconds_end)
	
	    #reduce the temp credit
	    if credit_usage_per_second:
		credit -= next_event * credit_usage_per_second
		if credit <= 0:
		    break_loop=True
	
	    remaining_time += next_event
	    # don't go for more than 1 week, who can talk for one week? ;)
	    # this may happen if cpm is 0
	    if remaining_time > 7 * 24 * 3600 : 
		break_loop = True

	    first_iter = False

	    start += next_event

	    if CHARGE_DEBUG:
		toLog("Loop End: credit: %s credit_usage_per: %s remaining_time: %s next_event: %s credit_finish_time: %s free_seconds_end: %s earliest_rule_end: %s next_more_applicable: %s seconds_from_morning: %s"% \
		(credit,credit_usage_per_second,remaining_time,next_event,credit_finish_time,free_seconds_end,earliest_rule_end,next_more_applicable,seconds_from_morning) \
		,LOG_DEBUG)
	
	    if not before_start_accounting:
		break_loop=True