<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
  <title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Eli Barzilay schreef:
<blockquote cite="mid17041.10602.906437.410037@mojave.cs.cornell.edu"
 type="cite">
  <pre wrap="">On May 23, Hans Oesterholt-Dijkema wrote:
  </pre>
  <pre wrap="">
This depends on many things like how do you transfer these things to
the work thread, how the work thread uses the db etc.

  </pre>
</blockquote>
At <br>
<br>
<a class="moz-txt-link-freetext" href="http://www.elemental-programming.org/epwiki/Scheme%20Persistent%20ROOS%20-%20Object%20Database">http://www.elemental-programming.org/epwiki/Scheme%20Persistent%20ROOS%20-%20Object%20Database</a><br>
<br>
There's documentation about what I'm doing. Especially interesting is
the <br>
picture of the component design, which can be found by clicking on
"OODB".<br>
What I'm testing right now, is the <i>client handler, </i>i.e. the
whole system, without<br>
client connections. <br>
<br>
One construction rule is that all objects will be accessed through the <i>object
cache</i>.<br>
Only searches are performed directly on the <i>backend-connections.</i>
<br>
<br>
All changes are written to the <i>object cache</i>, and the change is
written to the <i>FIFO</i>, which<br>
is a FIFO between threads (used like a (command) message queue). In
short, I'm performing <br>
the following code:<br>
<br>
<tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; (define (ctest CH C)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (if (= C 0)<br>
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; #t<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; (begin<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; (-&gt; CH lock shared-oid)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; (let ((n (+ (oodb-unmarshall (-&gt; CH get shared-oid
'counters 'n)) 1)))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (-&gt; CH put! shared-oid 'counters 'n (oodb-marshall n))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (let ((n1 (oodb-unmarshall (-&gt; CH get shared-oid
'counters 'n))))<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;(-&gt; CH unlock shared-oid)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; (and<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; (= n n1)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; (ctest CH (- C 1))))))))<br>
</tt><br>
CH is a <i>client handler</i> object. I'm starting this ctest function
with 1 to 15 threads, which results<br>
in 1 to 15 <i>client handlers</i>, 15 <i>backend connections, </i>1
shared <i>object cache</i>, 1 shared&nbsp; <i>object locks<br>
</i>1 shared&nbsp; <i>FIFO</i>. The <i>change handler</i> is running in a
separate thread. The <i>change handler</i> commits<br>
changes put in the <i>FIFO</i> to the backend using its own <i>backend
connection. <br>
<br>
</i>The <i>change handler</i> is a littlebit smart. When it gets time
to work, it will first "snapshot the FIFO by putting<br>
its own command message to the FIFO". Then It will process the snapshot
(a "unit of work"). From this<br>
unit of work, it will only commit the last change of an
object/class/attribute combination to the backend. <br>
<br>
As can be seen from the ctest function, for any number of changes in
the FIFO, in this testcase,&nbsp; this will <br>
result in exactly 1 commit of a change per unit of work. The idea is,
that the backend is slow and the <br>
cache system is fast; so while waiting for the database to commit a
change, other threads should be able<br>
to work on.<br>
<br>
This is what I see happening with one thread: <i>ctest</i> writes
about 150 changes, before the <i>change handler</i> <br>
starts handling them. This is repeated, until all 5000 counts have been
done. With 2 <i>ctest </i>threads, I see about<br>
200 changes per unit of work. With 3 threads, this number starts
dropping fast, until with 15 threads, only<br>
about 2 or 3 changes per unit of work are committed. The database now
takes 75% CPU and mzscheme <br>
doesn't get any time anymore. The performance drop is huge; starting
with 3000 changes/s, dropping to <br>
31 changes/s for 15 threads.<br>
<br>
Now, I put a <b>1 second delay</b> between <i>unit of works</i>. What
I see now, is that about 5000 changes/s can<br>
be committed to the FIFO each second. And, this scales lineairly, i.e.,
with 15 threads it is still 5000 changes/s.<br>
mzscheme gets 100% CPU. <i>I don't like the 1 second delay between
units of work, because with say 200 <br>
changes in a unit of work to commit to the database it probably won't
help.</i><br>
<br>
So, the thread behaviour of mzscheme is not what I've expected. It
looks like the database access is serialized<br>
to whole mzscheme and no thread is running until the database access
has been done. Just when I took so much<br>
care to make sure that all threads had their own database connection
and that all changes are written to the<br>
database asynchronously!<br>
<br>
So there's my question. How can it be that the <i>database connection</i>
blocks all other threads?!<br>
<br>
Thank you in advance for your answer(s),<br>
<br>
Hans Oesterholt-Dijkema<br>
<br>
<br>
<i></i><br>
</body>
</html>