This post is updated according to a revised approach to event algebra. More details will be given shortly. Beginning where the previous article left off, let's look at an example that shows reaction groups including reactions that form a sequence, rather than are active at the same time. In fact, there is no need to use anyhing else but AND-groups introduced in the previous post. We are still using the same example, logins from a different IP address for the same user but now we want to detect situations when a user login is followed by a sequence of the user logout and login from another IP address, BOTH within a given delay from the first login. Here is a new client from rules/reloaded/sequence_group_2.prova.
:- eval(client()). client() :- % Send all the test messages from a separate thread switch_thread(), % Use user-id as conversation-id (XID) for partitioning so that each user is processed sequentially sendMsg(user1,async,0,request,login(user1,'10.10.10.10')), java.lang.Thread.sleep(500L), sendMsg(user2,async,0,request,login(user2,'30.30.30.30')), java.lang.Thread.sleep(300L), sendMsg(user1,async,0,request,logout(user1,'10.10.10.10')), sendMsg(user1,async,0,request,login(user1,'20.20.20.20')), java.lang.Thread.sleep(1900L), sendMsg(user2,async,0,request,logout(user2,'30.30.30.30')), sendMsg(user2,async,0,request,login(user2,'40.40.40.40')). switch_thread() :- sendMsgSync(XID,task,0,switch,[]), rcvMsg(XID,task,From,switch,[]).
The last delay of 1900 ms is chosen to be too long so that only one pattern instance will be detected. The server looks like this.
% This prints: % % Pattern detected: [[[user1,async,0,request,[logout,user1,10.10.10.10]], [user1,async,0,request,[login,user1,20.20.20.20]]]] :- eval(server()). server() :- % Start detection on each new login rcvMult(XID,Protocol,From,request,login(User,IP)), server_1(XID). server_1(XID) :- @group(g1) rcvMsg(XID,Protocol,From,request,logout(User,IP)), @group(g1) rcvMsg(XID,Protocol,From,request,login(User,IP2)) [IP2!=IP]. server_1(XID) :- @and(g1) @timeout(2000) rcvMsg(XID,Protocol,From,and,Events), println(["Pattern detected: ",Events]," ").
And that is all, the AND-group 'g1' is given a timeout of 2000 ms, which means that both reactions belonging to group g1, viz., the logout and the following login (from a different IP, according to the guard condition) should occur within this delay from the first login. Only the series of requests from user1 meets these conditions. As the g1 reactions follow each other, the AND-logic actually captures the "follows" composition correctly.