Performance profile

Hi – I’‘m attempting to switch to jabber for interapplication comms, and am interested in performance profiles. I’‘ve tried both Messenger and jabberd 1.4.2 as servers, using the Smack lib for my client suppport. I’'ve sampled thruput between two local accounts, both running in the same process (on my HP NC8000 laptop) at various payload sizes from 10 bytes to 10K bytes.

Summary - jabberd maxes out at about 6K msgs/sec, at 10 bytes each, or 275 msgs/sec at 10K bytes each. Messenger gets about the same thruput with the 10K byte payloads, but seems limited to 500 msgs/sec with the smaller payloads.

SIZE JABBERD MESSENGER

10 6000/sec 500/sec

100 5000/sec 500/sec

1000 2000/sec 500/sec

10000 275/sec 230/sec

Any ideas? Is there an ‘‘event/sec’’ limiter? In all tests, the cpu is maxed out. For jabberd, the cpu usage is about evenly split between the server and the client processes, but for messenger the server uses >90%.

Thanks for any advice/hints/etc –

/bob

Bob,

A couple of questions:

  1. Can you send the test scripts you’'re using so that we can try to verify your numbers?

  2. What OS are you on? If on Windows, there may be some simple JVM performance tuning you need to do.

Regards,

Matt

I’‘m on WinXP Pro, using j2sdk1.4.2_04 for the client’'s jvm. Not sure what jvm the server would be running – I just installed Messenger 2.1.2 ‘‘as is’’ and started it up – great job, by the way!! Looks great, easy to setup (no xml editting… ), nice admin console.

I’'ll post client code in next reply.

Thanks,

Bob

import org.jivesoftware.smack.*;

import org.jivesoftware.smack.packet.*;

import java.util.*;

public class JabberTest {

public static void main(String[] args) {

JabberId from = new JabberId(“test1@btravislap”);

JabberId to = new JabberId(“test2@btravislap”);

to.connect();

from.connect();

send(from, to, 10000, 1000); // try 1000 msgs of 1000 bytes payload…

read(to); // see what we got…

to.disconnect();

from.disconnect();

}

public static void send(JabberId from, JabberId to, int size, int howmany) {

StringBuffer msgbuf = new StringBuffer();

int i = 0;

while (msgbuf.length() < size)

msgbuf.append("line " + (i++) + “\n”);

i = 0;

JabberMessage msg = new JabberMessage();

msg.bodyLine(msgbuf.toString());

msg.to(to);

msg.from(from);

while (i < howmany) {

i++;

msg.subject(“message:” + i);

msg.send();

}

}

public static void read(JabberId me) {

try {

int size = 0;

boolean timeout = false;

while (!timeout) {

int sleepMax = 5; // num secs of no activity to cause timeout

size = me.receivedCount();

System.out.println(“received " + size + " messages”);

do {

Thread.sleep(1000);

} while (me.receivedCount() == size && --sleepMax >0);

timeout = (sleepMax == 0);

}

System.out.println(me.lastPacket().getClass().getName());

System.out.println(me.lastPacket().toXML());

} catch (InterruptedException e) {

;

}

}

public static class JabberId implements PacketListener {

String jabberId,userId,hostName;

int sentCounter = 0;

XMPPConnection conn;

String password = “test”;

int recCounter = 0;

public JabberId(String id) {

jabberId = id;

int at = jabberId.indexOf(’’@’’);

hostName = jabberId.substring(at+1);

userId = jabberId.substring(0,at);

}

public synchronized int receivedCount() {

return recCounter;

}

private XMPPConnection newConnection() {

try {

return new XMPPConnection(hostName);

} catch (XMPPException e) {

System.out.println("no connection to " + hostName);

throw new RuntimeException(e);

}

}

public void connect() {

conn = this.newConnection();

try {

conn.login(userId, password);

} catch (XMPPException e) {

System.out.println("Unable to login " + jabberId + "; "

  • e.toString());

throw new RuntimeException(e);

}

conn.addPacketListener(this, null);

}

public void disconnect() {

conn.close();

conn = null;

}

public void send(Packet packet) {

conn.sendPacket(packet);

sentCounter++;

}

public synchronized void processPacket(Packet packet) {

recCounter++;

lastPacket = packet;

packet.setProperty(“received”,System.currentTimeMillis());

}

private Packet lastPacket;

public Packet lastPacket() {

return lastPacket;

}

}

public static class JabberMessage {

public JabberMessage() {

};

Packet packet;

long stamp;

public JabberMessage(Packet packet, long stamp) {

this.stamp = stamp;

this.packet = packet;

}

private List toList = new ArrayList();

private JabberId from;

private String subject;

private StringBuffer body = new StringBuffer();

public void to(JabberId to) {

this.toList.add(to);

}

public void from(JabberId from) {

this.from = from;

}

public void bodyLine(String txt) {

body.append(txt);

body.append(’’\n’’);

}

public void body(String txt) {

body = new StringBuffer(txt);

}

public void subject(String sub) {

subject = sub;

}

public Message getPacket() {

Message packet = new Message();

packet.setBody(body.toString());

if (subject != null)

packet.setSubject(subject);

return packet;

}

public void send() {

if (from == null)

throw new IllegalArgumentException(“No from identity”);

if (toList.isEmpty())

throw new IllegalArgumentException(“No to list”);

for (int i = 0; i < toList.size(); i++) {

// create packet

Packet packet = getPacket();

packet.setTo(((JabberId)toList.get(i)).jabberId);

from.send(packet);

}

}

}

}

Bob,

We’‘ll try out your code and let you know what we find locally. Since your’‘e on Windows, the biggest gain you’‘d get is switching from the “client VM” to the “server VM”. The installer technology we use doesn’‘t make this totally easy, so I’‘m going to have to dig a bit to figure out how to make that change. I’'ll post a follow-up with more info a bit later.

Thanks,

Matt

Bob,

I was able to run your test. Unfortunately, it doesn’‘t output stats in a way that makes it easy to replicate the general numbers you’'re seeing. Any chance that you could refactor the code to provide better output? It could be something like:

10    500/sec
100   500/sec
1000  500/sec
10000 230/sec

Also, in order for this test to be valid, you need to at least have the reader and writer be on different threads. Ideally, you would have one CPU for each party in the test (one for reader, one for writer, one for server).

Finally, I did some work today to figure out how to make the Hotpot Server VM work under a Windows Jive Messenger installation:

  1. Install JDK 1.5.0 from java.sun.com

  2. Copy the jdk1.5.0\jre\bin\server directory to C:\Program Files\Jive Messenger\jre\bin (assuming that’'s where Jive Messenger is installed).

  3. Restart Jive Messenger and it will be using the server VM, which is much faster for applications like Jive Messenger.

I’'m working to see if we can get the server VM bundled into Jive Messenger by default.

Regards,

Matt

Matt, Thanks very much for taking a look, and for the advice. I’‘ll make a new test program that output the timings more directly, and I’'ll also install the server jvm in the messanger directory, and let you know the results.

By the way, the thread situation should be OK – I believe the Smack lib runs listeners in a separate thread, so we have ‘‘main’’ doing the the writing, and ‘‘listener’’ doing the reading.

/bob

Looks like the server jvm improved perf by about 20%, maybe. Here’'re the latest stats:

............... 10000
............... 20000
................. 30000
......... 32000
MsgSize    Msgs/Sec
   10        634
   100       654
   1000      580
   10000     222

Here’'s the revised test program:


import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*;
import java.util.*; public class JabberTest {
    public static void main(String[] args) {
        JabberId from = new JabberId("test1@btravislap");
        JabberId to = new JabberId("test2@btravislap");
        to.connect();
        from.connect();
        send(from, to, 10, 10000); // try 10000 msgs of 10 bytes payload...
        int rate10 = read(to); // see what we got....
        send(from, to, 100, 10000); // ... 100 bytes
        int rate100 = read(to); // see what we got....
        send(from, to, 1000, 10000); // ... 1000 bytes
        int rate1000 = read(to); // see what we got....
        send(from, to, 10000, 2000); // ... 10000 bytes
        int rate10000 = read(to); // see what we got....
        to.disconnect();
        from.disconnect();
        System.out.println("MsgSize    Msgs/Sec");
        System.out.println("   10        "+rate10);
        System.out.println("   100       "+rate100);
        System.out.println("   1000      "+rate1000);
        System.out.println("   10000     "+rate10000);
    }
        /*
     * pushes stream of time-stamped msgs
     *      */
    public static void send(JabberId from, JabberId to, int size, int howmany) {
        StringBuffer msgbuf = new StringBuffer();
        int i = 0;
        while (msgbuf.length() < size)
            msgbuf.append("line " + (i++) + "\n");
        i = 0;
        JabberMessage msg = new JabberMessage();
        msg.bodyLine(msgbuf.toString());
        msg.to(to);
        msg.from(from);
        while (i < howmany) {
            i++;
            msg.subject("message:" + i);
            msg.send();
        }
    }     /*
     * Collect all msgs from stream, check timestampss
     *      */
    public static int read(JabberId me) {
        int initialSize = me.receivedCount();
        int size = initialSize;
        boolean timeout = false;
        int nsecs = 0;
        try {
            while (!timeout) {
                int sleepMax = 2; // num secs of no activity to cause timeout
                size = me.receivedCount();
                //System.out.println("received " + size + " messages");
                System.out.print(".");
                do {
                    Thread.sleep(1000);
                } while (size==0 || (me.receivedCount() == size && --sleepMax >0));
                nsecs++;
                timeout = (sleepMax == 0);
            }
        } catch (InterruptedException e) {
            return 0;
        }
        System.out.println(" "+size);
        //System.out.println(me.lastPacket().getClass().getName());
        //System.out.println(me.lastPacket().toXML());
        //System.out.println(me.lastPacket().getBody().substring(0,100));
        return (size-initialSize)/nsecs;
    }     /*
     * Stands for a Jabber identity
     *      */
    public static class JabberId implements PacketListener {
        String jabberId,userId,hostName;         int sentCounter = 0;         XMPPConnection conn;         String password = "test";         //List received = new LinkedList(); // received packets
        int recCounter = 0;         public JabberId(String id) {
            jabberId = id;
            int at = jabberId.indexOf(''@'');
            hostName = jabberId.substring(at+1);
            userId = jabberId.substring(0,at);
        }
                public synchronized int receivedCount() {
            return recCounter;
        }         private XMPPConnection newConnection() {
            try {
                return new XMPPConnection(hostName);
            } catch (XMPPException e) {
                System.out.println("no connection to " + hostName);
                throw new RuntimeException(e);
            }
        }
        public void connect() {
            conn = this.newConnection();
            try {
                conn.login(userId, password);
            } catch (XMPPException e) {
                System.out.println("Unable to login " + jabberId + "; "
                        + e.toString());
                throw new RuntimeException(e);
            }
            conn.addPacketListener(this, null);
        }
        public void disconnect() {
            conn.close();
            conn = null;
        }         public void send(Packet packet) {
            conn.sendPacket(packet);
            sentCounter++;
            //System.out.println("sent " + sentCounter + " from " + this.jabberId
              //      + " to " + to.jabberId);
        }         public synchronized void processPacket(Packet packet) {
            //if (packet instanceof Message)
                recCounter++;
            lastPacket = packet;
            packet.setProperty("received",System.currentTimeMillis());
            //System.out.println("received by " +
            // this.jabberId+" at "+System.currentTimeMillis()+              // "\n"+packet.toXML());
            //received.add(new JabberMessage(packet, System.currentTimeMillis()));
        }
        private Packet lastPacket;
        public Packet lastPacket() {
            return lastPacket;
        }
    }     public static class JabberMessage {
        public JabberMessage() {
        };         Packet packet;         long stamp;         public JabberMessage(Packet packet, long stamp) {
            this.stamp = stamp;
            this.packet = packet;
        }         private List toList = new ArrayList();
        private JabberId from;
        private String subject;
        private StringBuffer body = new StringBuffer();         public void to(JabberId to) {
            this.toList.add(to);
        }
        public void from(JabberId from) {
            this.from = from;
        }         public void bodyLine(String txt) {
            body.append(txt);
            body.append(''\n'');
        }
        public void body(String txt) {
            body = new StringBuffer(txt);
        }
        public void subject(String sub) {
            subject = sub;
        }         public Message getPacket() {
            Message packet = new Message();
            packet.setBody(body.toString());
            if (subject != null)
                packet.setSubject(subject);
            return packet;
        }         public void send() {
            if (from == null)
                throw new IllegalArgumentException("No from identity");
            if (toList.isEmpty())
                throw new IllegalArgumentException("No to list");
            for (int i = 0; i < toList.size(); i++) {
                // create packet
                Packet packet = getPacket();
                packet.setTo(((JabberId)toList.get(i)).jabberId);
                // conn.sendPacket(packet);
                from.send(packet);
            }
        }
    }
}

Thanks for the update. We’'ll do testing on our end to see what might be going on and will get back to you.

Regards,

Matt

Strange… I tried both your code and a version of my own, using a main thread and a reading thread… I seem

a) to mess up something, since my numbers are (significantly) worse than the numbers your profile test gives me - but my version needs less time

b) have a machine problem here… This is “just” my work laptop… 1,7 GHZ Centrino with 1GB RAM, quite fast actually for me - and the results are that low.

This is Windows XP SP 2 here.

My results:

// With your latest profiling code

MsgSize Msgs/Sec

10 139

100 140

1000 129

10000 81

// My version with a thread for reading

MsgSize Msgs/Sec

10 144

100 71

1000 47

10000 37

pondering,

Ben

Hi Ben,

Sounds like your laptop and mine OUGHT to be about the same… mine’‘s also 1.7Ghz and 1GB mem. Is the server you’'re talking to local or remote? (Mine is local…)

/bob

Hey bob.

My server is local as well, I even use “localhost” as domain for this test (test1@localhost -> test2@localhost), so I doubt that anything related to the network could be the cause, BUT…

todays result of your test:

MsgSize Msgs/Sec

10 155

100 146

1000 142

10000 105

todays result of my test:

MsgSize Msgs/Sec

10 165

100 79

1000 52

10000 40

Some numbers (especially your results) are quite a lot better (while still poor). The only difference is, that I’‘m on another network and using a cable instead of WLAN to access the internet. Same code, same server, no configuration settings… But “localhost” is resolved as 127.0.0.1 and is in my %windir%\system32\drivers\etc\hosts file… I’'m clueless right now…

Ben

These results are interesting to say the least. I ran the tests on a Solaris Sunfire dual cpu machine and got even worse results!. When I ran it a third time the jvm died and

left me a nice log file (see below)

As the developer chat is on today and I was wondering if we could chat about these issues briefly. I would also like to know the minimum h/w spec, prehaps described

in terms of volume capability. e.g. 1000 concurrent users, chatting over 50 rooms, where the requirement is latency < 5 seconds for all users…

Anyone have any figures for this?

log file from jvm.

  1. An unexpected error has been detected by HotSpot Virtual Machine:

  1. SIGBUS (0xa) at pc=0xf8816320, pid=7979, tid=1644

  1. Java VM: Java HotSpot™ Server VM (1.5.0_01-b08 mixed mode)

  2. Problematic frame:

  3. j org.jivesoftware.messenger.disco.IQDiscoInfoHandler.handleIQ(Lorg/xmpp/packet/I Q;)Lorg/xmpp/packet/IQ;+236


T H R E A D


Current thread (0x00388d60): JavaThread “SRT reader” daemon

siginfo:si_signo=10, si_errno=0, si_code=1, si_addr=0xd5cbe367

Registers:

O0=0xef1601d0 O1=0x00800001 O2=0x00000001 O3=0xf8815ca0

O4=0x00000001 O5=0xd400b8a8 O6=0xd227f768 O7=0xf8805d3c

G1=0xd408f498 G2=0x00388d60 G3=0xf8805c78 G4=0x01000000

G5=0xd41e1e80 G6=0x00000000 G7=0xfaae3c00 Y=0x00000000

PC=0xf8816320 nPC=0xf8816324

Top of Stack: (sp=0xd227f768)

0xd227f768: d227f7d0 d471e2fc d471e418 d227f87c

0xd227f778: d227f7d8 00000000 d471f020 00388d60

0xd227f788: d835b3e0 000000b6 d5cbe363 f88161a0

0xd227f798: d461f5f8 d227f818 d227f7f0 f8805874

0xd227f7a8: ef15cb78 00388d60 00000001 ef14d138

0xd227f7b8: 00000000 ef15ffd0 d823e740 ef160180

0xd227f7c8: ef160138 d4c12a48 d474bcc0 ef1601d0

0xd227f7d8: d40fc928 00000000 ef15c778 00000000

Instructions: (pc=0xf8816320)

0xf8816310: 9e 00 ff f8 80 90 00 1a 02 40 00 2d 01 00 00 00

0xf8816320: d8 06 a0 04 98 83 20 01 98 63 00 00 d8 26 a0 04

Stack: [0xd2200000,0xd2280000), sp=0xd227f768, free space=509k

Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)

j org.jivesoftware.messenger.disco.IQDiscoInfoHandler.handleIQ(Lorg/xmpp/packet/I Q;)Lorg/xmpp/packet/IQ;+236

j org.jivesoftware.messenger.handler.IQHandler.process(Lorg/xmpp/packet/Packet;)V +7

j org.jivesoftware.messenger.IQRouter.handle(Lorg/xmpp/packet/IQ;)V+232

j org.jivesoftware.messenger.IQRouter.route(Lorg/xmpp/packet/IQ;)V+85

v ~C2IAdapter

J org.jivesoftware.messenger.net.SocketReadThread.readStream()V

J org.jivesoftware.messenger.net.SocketReadThread.run()V

v ~I2CAdapter

v ~StubRoutines::call_stub

V

V

V

V

V


P R O C E S S


Java Threads: ( => current thread )

=>0x00388d60 JavaThread “SRT reader” daemon

0x006c67a8 JavaThread “SRT reader” daemon

0x00830c90 JavaThread “SRT reader” daemon

0x00ad6120 JavaThread “SRT reader” daemon

0x00954d60 JavaThread “SocketListener0-1”

0x00954b40 JavaThread “SocketListener0-0”

0x007052d0 JavaThread “Acceptor ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=9090]”

0x00ac2028 JavaThread “SessionScavenger” daemon

0x003b3450 JavaThread “Rollover” daemon

0x00037ab0 JavaThread “DestroyJavaVM”

0x00485240 JavaThread “pool-1-thread-1”

0x002ce0d0 JavaThread “SAT accept” daemon

0x002cdf10 JavaThread “Timer-2”

0x00422c88 JavaThread “JmDNS.SocketListener”

0x00316af8 JavaThread “Timer-1”

0x00303b98 JavaThread “Timer-0”

0x00499f40 JavaThread “Thread-1” daemon

0x0016f9f0 JavaThread “Thread-0” daemon

0x0014a230 JavaThread “Low Memory Detector” daemon

0x00148980 JavaThread “CompilerThread1” daemon

0x00147b18 JavaThread “CompilerThread0” daemon

0x00146cb0 JavaThread “AdapterThread” daemon

0x001458d8 JavaThread “Signal Dispatcher” daemon

0x00139320 JavaThread “Finalizer” daemon

0x001385e8 JavaThread “Reference Handler” daemon

Other Threads:

0x00136130 VMThread

0x0014beb8 WatcherThread

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

Heap

PSYoungGen total 50560K, used 26071K [0xed800000, 0xf2400000, 0xf8400000)

eden space 50496K, 51% used [0xed800000,0xef169dd8,0xf0950000)

from space 64K, 75% used [0xf0e40000,0xf0e4c000,0xf0e50000)

to space 12480K, 0% used [0xf17d0000,0xf17d0000,0xf2400000)

PSOldGen total 61440K, used 48954K [0xd8000000, 0xdbc00000, 0xed800000)

object space 61440K, 79% used [0xd8000000,0xdafceae0,0xdbc00000)

PSPermGen total 28672K, used 13049K [0xd4000000, 0xd5c00000, 0xd8000000)

object space 28672K, 45% used [0xd4000000,0xd4cbe438,0xd5c00000)

Dynamic libraries:

0x00010000 /usr/jdk1.5.0_01/bin/java

0xff360000 /usr/lib/libthread.so.1

0xff39a000 /usr/lib/libdl.so.1

0xff280000 /usr/lib/libc.so.1

0xff390000 /usr/platform/SUNW,Sun-Fire-V240/lib/libc_psr.so.1

0xfe800000 /usr/jdk1.5.0_01/jre/lib/sparc/server/libjvm.so

0xff240000 /usr/lib/libsocket.so.1

0xff210000 /usr/lib/libsched.so.1

0xff1e0000 /usr/lib/libCrun.so.1

0xff190000 /usr/lib/libm.so.1

0xff080000 /usr/lib/libnsl.so.1

0xff260000 /usr/lib/libw.so.1

0xff160000 /usr/lib/libmp.so.2

0xff050000 /usr/jdk1.5.0_01/jre/lib/sparc/native_threads/libhpi.so

0xff000000 /usr/jdk1.5.0_01/jre/lib/sparc/libverify.so

0xfefc0000 /usr/jdk1.5.0_01/jre/lib/sparc/libjava.so

0xfefa0000 /usr/jdk1.5.0_01/jre/lib/sparc/libzip.so

0xfb460000 /usr/jdk1.5.0_01/jre/lib/sparc/libnet.so

VM Arguments:

jvm_args: -Dinstall4j.jvmDir=/usr/jdk1.5.0_01 -Dinstall4j.appDir=/usr/local/jive_messenger -Dexe4j.moduleName=/usr/local/jive_messenger/bin/./messenger

java_command: com.install4j.runtime.Launcher start org.jivesoftware.messenger.starter.ServerStarter false false /usr/local/jive_messenger/bin/…/logs/stderror.log /usr/local/jive_messenger/bin/…/logs/stdoutt.log true true false true true 0 0 20 20 Arial 0,0,0 8 500 version 2.1.1 20 40 Arial 0,0,0 8 500 -1 -DmessengerHome=/usr/local/jive_messenger -Dmessenger.lib.dir=/usr/local/jive_messenger/lib start

Environment Variables:

JAVA_HOME=/usr/jdk1.5.0_01

PATH=/usr/sbin:/usr/local:/usr/local/bin:/usr/local/lib:/usr/ccs/bin:/usr/share: /usr/share/bin:/usr/bin:/usr/ucb:/etc:.

LD_LIBRARY_PATH=/usr/jdk1.5.0_01/jre/lib/sparc/server:/usr/jdk1.5.0_01/jre/lib/s parc:/usr/jdk1.5.0_01/jre/…/lib/sparc:/usr/local/lib

SHELL=/sbin/sh

HOSTTYPE=sparc

OSTYPE=solaris2.9

MACHTYPE=sparc-sun-solaris2.9


S Y S T E M


OS: Solaris 9 4/04 s9s_u6wos_08a SPARC

Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.

Use is subject to license terms.

Assembled 22 March 2004

uname:SunOS 5.9 Generic_117171-07 sun4u (T2 libthread)

rlimit: STACK 8192k, CORE infinity, NOFILE 65536, AS infinity

load average:1.62 1.67 0.88

CPU:total 2 has_v8, has_v9, has_vis1, has_vis2, is_ultra3

Memory: 8k page, physical 2097152k(896816k free)

vm_info: Java HotSpot™ Server VM (1.5.0_01-b08) for solaris-sparc, built on Dec 6 2004 20:06:36 by unknown with unknown Workshop:0x550

Conor.

Hey Conor,

That was a JVM error. Are you using the latest Java 1.5 patches for Solaris? See http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/J2SE. Have you installed the latest (and required by Java) Solaris patches?

If the problem still persists and since you are using the Sun JVM I’'d suggest reporting the problem to sun and see what they suggest to do.

Regards,

– Gato

Just for apples/apples purposes, I ran this same program against jabberd 1.4.2 server, but with increased counts for the smaller payloads to get the total elapsed time in range (40K, 30K, 30K, 2K). Here’'s the output on my windows machine running against jabberd:

......... 40003
........ 70003
................. 100003
......... 102003
MsgSize    Msgs/Sec
   10        4444
   100       3648
   1000      1755
   10000     222

mmm I’'m getting

. 11

. 11

. 11

. 11

MsgSize Msgs/Sec

10 0

100 0

1000 0

10000 0

as output from the script, connecting to a local or remote Jive server.

Any ideas?

Hey guys,

So, we have a very interesting update. Gato has been doing profiling and it turns out that the server is doing 96% of all of it’‘s work doing stringprep operations. That is a massive, massive bottleneck that we’‘ll need to cure. It looks like we had a huge performance regression when we added that code and didn’‘t realize it until now. We’'ll keep everyone updated on progress.

Thanks,

-Matt

This test program tries to login as ‘‘test1’’ and ‘‘test2’’, password ‘‘test’’, – are those accounts setup on the server you’‘re connecting to? Unfortunrately, this simple script doesn’‘t check for the kinds of response messages that would indicate problems… Change it to print out the incoming packets, and I’‘m sure you’‘ll see what’'s wrong.

Hey Matt ,

That’'s great news! Nice work, Gato… Anxiously await an update

Thanks,

Bob