Hi,
a nice problem... see below
On 12/10/2012, mohan <mohan.narangoda(a)gmail.com> wrote:
Hi laune,
I'll explain the process briefly. I’m getting voice call events from our
billing system. We want give some offers if call made inside specific cell
(uploaded this fact to WM in advance) . But we have to give offer only once
per day. So repeated calls inside this cell won’t eligible for offer again.
To achieve this we initiate a new event(NotificationEvent) and insert into
WM and set metadata @expires(24h) against each mobile no. Ultimately over
1000K NotificationEvents are residing in WM per day and guess it will
trigger OutOfMemory exception. How to handle such a case? Do we need to use
caching mechanism?
Unclear: Is NotificationEvent in the preceding paragraph the
OfferedEvent in your rule below? And the expiry would have to be set
for OfferedEvent, not "each mobile no" (as written above).
Also, clarify "once per day". It seems that you want "not again in the
next 24 hours but it can also be interpreted as "only once between
0:00 and 24:00". (The latter would be much easier to handle.)
Beware: nothing of the code below is tested.
Reducing the number of facts can be done by registering offers made in a
one fact per offerId (assuming a mobile number can be stored in a long,
which should be possible):
declare OffersMade
offerId : int
origin2time : Map<Long,Long>
end
You match a call event to an offer:
rule "Call matches Offer"
when
$vc : VoiceCallEvent( $ct : eventTime,
$cell : cellID,
$mobile : originNumber)
$offer : CymOfferInfo($valTo : validTo.time >= $ct,
cellId == $cell,
$offerId : offerType.getId,
$msgContent : cepMsgTemplates.getId)
then
end
Then there's two cases: you don't have a matching OffersMade yet, or
you have but the caller isn't registered:
rule "No such offer yet"
extends "Call matches Offer"
when
not OffersMade( offerId == $offerId )
then
OffersMade offersMade = new OffersMade();
offersMade.setOfferId( $offerId );
Map o2t = new HashMap();
offersMade.setOrigin2Time( o2t );
o2t.put( $mobile, $ct.getTime() );
insert( offersMade );
MdbServiceUtil.sendSMS( $mobile, $msgContent );
retract( $vc );
end
rule "No offer for this origin"
extends "Call matches Offer"
when
$om: OffersMade( offerId == $offerId,
origin2time.keySet not contains $mobile )
then
$om.getOrigin2Time().put( $mobile, $ct.getTime() );
update( $om );
MdbServiceUtil.sendSMS( $mobile, $msgContent );
retract( $vc );
end
Finally you need to get rid of old entries. This can be done in a rule
with a timer:
rule "erase old offers"
timer (cron:* 0/15 * * * ?)
when
$om: OffersMade()
then
boolean change = false;
long limit = (new Date()).getTime() - 24*60*60*1000;
for( Map.Entry entry: $om.getOrigin2Time().entrySet() ){
if( (Long)entry.getValue() <= limit ){
$om.getOrigin2Time().remove( entry.getKey() );
change = true;
}
}
if( change ) update( $om );
end
This still requires two Long objects per offer made (and overhead for the Map).
You might reduce this further by storing the time only once per
OffersMade, so that it is sufficient to have a Set for the
originNumbers:
declare OffersMade
offerId : int
offerTime : long
origins : Set<Long>
end
Of course it would be obtuse to have one OffersMade per millisecond,
which means that offerTime must be reduced to ticks of some reasonable
granularity, I'd say between 1m and 1h. The required rule set is
similar to the preceding one, even simpler, as it is, for instance,
possible to discard an OffersMade object entirely after 24 hours:
rule "discard old set"
timer( int: 24h )
when
$om: OffersMade
then
retract( $om );
end
-W
Thanks.
see below code snippet
rule "Voice CYM offer selector"
dialect "java"
no-loop true
when
$vc : VoiceCallEvent( $ct : eventTime, $cell : cellID, $mobile :
originNumber) from entry-point "IN-VOICE-CALL-EVENT"
$offer : CymOfferInfo($valTo : validTo.time >= $ct, cellId ==
$cell,$offerId : offerType.getId, $msgContent : cepMsgTemplates.getId)
not( OfferedEvent(mobileNo == $mobile , offerId == $offerId ))
then
CYMOfferMessage genMsg = new CYMOfferMessage();
OfferedEvent offered = new OfferedEvent();
offered.setMobileNo($mobile);
offered.setOfferId((String)$offerId);
genMsg.setMobile($mobile);
genMsg.setMsgContent($msgContent);
/* atttach offer here */
/* drop SMS message to queue & block offer trigger again*/
mdbService.dropMessage(genMsg);
insert(offered);
end
--
View this message in context:
http://drools.46999.n3.nabble.com/java-lang-OutOfMemoryError-Java-heap-sp...
Sent from the Drools: User forum mailing list archive at
Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users