Project

General

Profile

AD-hoc groovy scripts and clustering

Steffen Larsen
Added almost 5 years ago

Hi Guys,

I've been doing a lot of different scripting lately and I have a question regarding my groovy scripts and when I am in clustering mode.

In many of my scripts I am using the session for a given user to see if he is active, to get his presence etc. Like so:

@XMPPSession session = sessions.get(BareJID.bareJIDInstanceNS(userJid))

List conns = session.getActiveResources()

for (XMPPResourceConnection con: conns) {

// do stuff

}@

My question is:

1) Do this work in a cluster? E.g. if my REST call hits server 1 and executes the given groovy script, and the user is on server 2, will I be able to see the active connection?

2) If not, how do I solve this, so I can call any server and get back the session of the user? (traverse the cluster.getAllNodes() and see for a session?.. an example would be great)

-Cheers!

/Steffen


Replies (13)

Added by Wojciech Kapcia TigaseTeam almost 5 years ago

Unfortunately all scripts are executed on the node do which you are connected while executing them. Currently, a number of scripts circumvents this shortcoming by sending a copy of command packet to the other nodes and executing it there (e.g.: BroadcastToOnline.groovy) however it's not ideal.

Added by Steffen Larsen almost 5 years ago

hmmm yes thats what I thought.

Then how do I actually know all of my sessions and being able to traverse them. The Broadcast groovy script only shows how to send stanzas to every node and every jid on that node. But how do I get all the session data of the full cluster? Is there an IQ ad hoc command for that or?

/Steffen

Added by Wojciech Kapcia TigaseTeam almost 5 years ago

Right now, using default strategy - you can't. If you are using ACS strategy you could use tigase.cluster.strategy.ClusteringStrategyIfc.getConnectionRecords(tigase.xmpp.BareJID):java.util.Set<E> method to obtains cached information about user connections on all nodes as well as presence of such connection.

Avatar?id=6023&size=32x32

Added by Artur Hefczyc TigaseTeam almost 5 years ago

Steffen Larsen wrote:

hmmm yes thats what I thought.

Then how do I actually know all of my sessions and being able to traverse them. The Broadcast groovy script only shows how to send stanzas to every node and every jid on that node. But how do I get all the session data of the full cluster? Is there an IQ ad hoc command for that or?

My suggestion is not to do this. Please consider an alternative solution which does not require you full knowledge about all connected users and resources on a single cluster node. If you base your logic on such a requirement you restrict long term scalability of your service. The best way to scale the service is to develop logic which can distribute processing so online users "are processed" on the node to which they are connected.

Added by Steffen Larsen almost 5 years ago

Hi Artur,

I tried different angles. My first tryout was to build a simple XMPPProcessor that "grabbed" the connection and watched the size of the session, but that of course also suffer from not working in a cluster, right?

Because its also using XMPPResourceConnection which I also tried to use in my Groovy scripts.

So different solutions exists if I need the knowledge of every session for a specific JID (all the resources):

  • Do an active ping towards the client (the ping is initiated from a REST call and only done periodically for getting the resources of a JID)

  • Use Wojciechs getConnectionRecords

  • Ugly solution: use XMPPProcessor to put my session into a db (using Couchbase is fast enough for writing and reading)

  • ???

PS: I tried to use getConnectionRecords with cluster and ACS clustering strategy on, but I keep getting null in my Set of ConnectionRecords.

Here is what I tried to do:

if (clusterMode) {
        System.out.println("clusterMode is on!")
        Set<ConnectionRecord> records = clusterStrategy.getConnectionRecords(bareJID)
        if (records==null) {
            System.out.println("The records is null!")
            return ""
        }
        System.out.println("Records is : "  + records.size())
        for (ConnectionRecord record : records) {
            System.out.println("Got some records!")
            System.out.println("[" + bareJID + "] ConnectionRecord: " + record)
            return record
        }
}

Anything wrong in that script?.. I am connected with the JID that I am testing of course. :-)

/Steffen

Added by Wojciech Kapcia TigaseTeam almost 5 years ago

OK, basic question is why you need the knowledge of every user session?

As for the script - it contains information about all user connections on other nodes without local sessions.

Avatar?id=6023&size=32x32

Added by Artur Hefczyc TigaseTeam almost 5 years ago

Steffen,

We know too little about your use-case to suggest best approach and/or solution. Our preferred way to do this is to execute the script on each node for locally connected users. This way you can have access to all user's sessions, however, your processing would be kind of distributed.

Added by Steffen Larsen almost 5 years ago

Hi,

Sorry about this late update of this thread. Sure I can do it pr. node in the cluster, but then I have to know which node are present in the cluster. Is there an adhoc command for that, or do I have to create that my self?

I can see the cludes nodes in mysql (cluster_nodes table), but its show every node that also have been connected. It could be cool to have the current state of the cluster exposed. Is that possible or should I do some extension my self?

-Cheers and thanks for your time guys.

PS: Artur, can you answer my earlier mail when you get the time?.

/Steffen

Added by Wojciech Kapcia TigaseTeam almost 5 years ago

You can access current state of the cluster (i.e. connected nodes) from clustering strategy:

def cluster = (ClusteringStrategyIfc) clusterStrategy
def cl_conns = cluster.getAllNodes()

This is taken from the mentioned earlier BroadcastToOnline.groovy script.

Added by Steffen Larsen almost 5 years ago

DOH! my mistake.. thanks Wojciech!.

Added by Steffen Larsen almost 5 years ago

Hmm whats really strange is that it only returns sess-man@serv1.mydomain.com.

I would expect two JIDs, because I have two nodes in my cluster.

And both of them are working - I can connect to them through my loadblaancer and in mysql I can see both instances (with a recent last_update date).

Added by Wojciech Kapcia TigaseTeam almost 5 years ago

You will all nodes of the cluster with the exception of the node to which you are currently connected. The behaviour is consistent with how cl-comp operate (in service discovery you also see only the remaining nodes).

Added by Steffen Larsen almost 5 years ago

Ahh I see - that makes sense. So the count is always X+1 (the one I am sitting on). :-)

    (1-13/13)