views:

1064

answers:

3

We're evaluating db4o (an OO-DBMS from http://www.db4o.com). We've put together a performance test for client/server mode, where we spin up a server, then hammer it with several clients at once. It seems like the server can only process one client's query at a time.

Have we missed a configuration switch somewhere that allows for this scenario? Server implementation is below. The client connects, queries (read-only), and disconnects per operation, and operations run one immediately after the other from several worker threads in the client process. We see same behaviour if we spin up one client process with one worker each against the same server.

Any suggestions?

Edit: We've now discovered, and tried out, the Lazy and Snapshot QueryModes, and although this alleviates the blocking server problem (partially), we still see significant concurrency problems when our clients (we run 40 concurrent test-clients that wait 1-300ms before issuing a random operation-request) hammer on the server. There appear to be exceptions emanating from the LINQ provider and from the IO internals :-(


public class Db4oServer : ServerConfiguration, IMessageRecipient
{
    private bool stop;


    #region IMessageRecipient Members

    public void ProcessMessage(IMessageContext con, object message)
    {
     if (message is StopDb4oServer)
     {
      Close();
     }
    }

    #endregion


    public static void Main(string[] args)
    {
     //Ingestion.Do();
     new Db4oServer().Run(true, true);
    }


    public void Run(bool shouldIndex, bool shouldOptimizeNativeQueries)
    {
     lock (this)
     {
      var cfg = Db4oFactory.NewConfiguration();
      if (shouldIndex)
      {
       cfg.ObjectClass(typeof (Sequence)).ObjectField("k__BackingField").Indexed(true);
       cfg.ObjectClass(typeof (Vlip)).ObjectField("k__BackingField").Indexed(true);
      }
      if (shouldOptimizeNativeQueries)
      {
       cfg.OptimizeNativeQueries(true);
      }

      var server = Db4oFactory.OpenServer(cfg, FILE, PORT);
      server.GrantAccess("0", "kieran");
      server.GrantAccess("1", "kieran");
      server.GrantAccess("2", "kieran");
      server.GrantAccess("3", "kieran");
      //server.Ext().Configure().ClientServer().SingleThreadedClient(false);
      server.Ext().Configure().MessageLevel(3);

      server.Ext().Configure().Diagnostic().AddListener(new DiagnosticToConsole());

      server.Ext().Configure().ClientServer().SetMessageRecipient(this);
      try
      {
       if (!stop)
       {
        Monitor.Wait(this);
       }
      }
      catch (Exception e)
      {
       Console.WriteLine(e.ToString());
      }
      server.Close();
     }
    }


    public void Close()
    {
     lock (this)
     {
      stop = true;
      Monitor.PulseAll(this);
     }
    }
}
A: 

where is the client being created? I don't see that in the above code sample

Bless Yahu
You can see the client code at http://developer.db4o.com/forums/post/51714.aspx as well as some more discussion of the use-case.
Peter Mounce
A: 

Have you tried decreasing your message level? It is set to maximum in your example. Did you find a solution?

Kasper Rönning
A: 

Did you ever find a solution?

Robert
No; we stopped evaluating at the time and moved to a relational db :/
Peter Mounce
A very good .NET client/server object oriented database is http://eloquera.com/page/home.aspx. They tell me that they'll have LINQ support very soon.
Robert