1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
@chapter Xnee Internals
@cindex Xnee Internals
This chapter is intended to explain the internal design of libxnee.
Hopefully this will lead to a better understanding of how to use Xnee
and why some features exist and why some don't.
@section Synchronisation
@cindex Synchronisation
We will try to go through the basics of how Xnee implements synchronisation
and try to tell you, by using examples, why synhronisation is important.
@subsection Why synchronise
@cindex why synchronise
To understand why synchronisation during replay is needed an example is given.
In this example only mouse and keyboard events are recorded. Think of a session with a web browser.
During record the following is done:
@itemize @bullet
@item Start galeon (or another web browser) via the GNOME panel
@item Press Ctrl-O which pops up a window
@item Press the left button in the textfield of the popup window
@item Enter the URL you want to enter (e.g @url{http://www.gnu.org})
@item Click on the OK button
@item Then click on another URL (e.g GNU Documentation)
@item Then click on another URL (e.g On-Line Documentation)
@end itemize
When replaying this session it is often useful to synchronise the recorded session with what's happening "right now" on the display since sometimes (or rather always) there can be different response times from the same URL.
During replay the following is done:
@itemize @bullet
@item Galeon is started
@item Ctrl-O is typed which pops up a window
@item Press the left button in the textfield of the popup window
@item Enter the URL you want to enter (e.g @url{http://www.gnu.org})
@item Click on the OK button
@item ... due to an enormous amount of visitors the GNU web server can't respond as quick as it did when recording. So when the next thing happens
@item Then click on another URL (e.g GNU Documentation)
@item ... the page hasn't been loaded and when the next event is replayed
@item Then click on another URL (e.g On-Line Documentation)
@item ... the link isn't there and we're really out of sync with the recorded session
@end itemize
@subsection How to synchronise
@cindex how to synchronise
Instead we could record some more data than just the mouse and keyboard events.
During record the following is done:
@itemize @bullet
@item Start galeon (or another web browser) via the GNOME panel
@item Record some X data that tells us that a window has been created
@item Press Ctrl-O which pops up a window
@item Record some X data that tells us that a window has been created
@item Press the left button in the textfield of the popup window
@item Enter the URL you want to enter (e.g @url{http://www.gnu.org})
@item Click on the OK button
@item Record some X data that tells us that a window has been destroyed
@item Then click on another URL (e.g GNU Documentation)
@item Record some X data that tells us that a some text has been displayed in a window
@item Then click on another URL (e.g On-Line Documentation)
@item Record some X data that tells us that a some text has been displayed in a window
@end itemize
The non-mouse-or-keyboard events recorded (window created & text displayed) are record for synchronisation purposes.
During replay the following is done:
@itemize @bullet
@item Start galeon (or another web browser) via the GNOME panel
@item wait for: the recorded X data to be sent again
@item Press Ctrl-O which pops up a window
@item wait for: the recorded X data to be sent again
@item Press the left button in the textfield of the popup window
@item Enter the URL you want to enter (e.g @url{http://www.gnu.org})
@item Click on the OK button
@item wait for: the recorded X data to be sent again
@item Then click on another URL (e.g GNU Documentation)
@item wait for: the recorded X data to be sent again
@item Then click on another URL (e.g On-Line Documentation)
@item wait for: the recorded X data to be sent again
@end itemize
@subsection Synchronisation is needed
So by recording more data than just the events to be replayed we can synchornise what was recorded with what is going on when replaying. But the data has to be chosen with respect to that the data:
@itemize @bullet
@item differs from different sessions (Gimp and Xterm are really different)
@item slows down the replay session if there are too many
@item is hard to choose since the X protocol is rich
@item differs (comparing record and replaying)
@item can have different ordering (comparing record and replaying)
@end itemize
@subsection Different data for different kind of sessions
If we record an xterm session with all data being recorded and compare that to a recorded GIMP session with all data being recordr we can see that the data to use as synchronisation data differs. AS an example there aren't so many windows created/destryed during an xterm session.
The solve to the the problem of finding out what data to use as synchronisation data one can:
@itemize @bullet
@item use the project files delivered with Xnee
@item analyse the application (using Xnee's @code{--human-printouts} option) and do some "trial and error"
@end itemize
@subsection Slow replay session due to too many synchronise data
The synchronisation itself doesn't take much time but there are timeouts that makes Xnee paues for a short while (see above). If there are many such timeouts it will lead to a slow or shaky replaying session.
@subsection X protocol is rich and asynchronous
For an end user (with no X expertise) it is hard to read the X protocol specification and make assumptions on what data to use.
@subsection Different data sent
Even if one starts up a machine from scratch (reboot) when recording and from scratch when replaying there is no guarantee that the data is sent in the same order or that exactly the same amount of data is sent.
@subsection Buffers and timeouts
To enable synchronisation Xnee buffers data:
@itemize @bullet
@item that was read in the session file but hasn't been sent during replay
@item that was sent during replay but hasn't been seen in the session
file being replayed
@end itemize
For every data read from session file (during replay) that isn't replayable
(i e device event) Xnee stores the data in a buffer. Xnee also stores the
data sent from the X server during playback. The data received from the server
make the buffer entry for that specific data be decremented. If, on the other
hand, the same data was read from file the buffer entry for that data is
incremented.
Before replaying any replayable event Xnee makes sure it is in sync. If Xnee
is in sync the replaying
continues. If Xnee is out of sync it will look for its thresholds and see
if it is inside a user specified range. There are three thresholds:
@itemize @bullet
@item @b{positive maximum} nr data read from session file
@item @b{negative minimum} nr of data sent from X server
@item @b{absolute total maximum} sum of the absolute values above
@end itemize
If Xnee read one data from file (e.g the event MapNotify) Xnee checks if the
buffer entry for the specific data is bigger than the positive maximum value
(after having incremented the buffer value).
If Xnee receives one data from the X server (e.g the event MapNotify) it
checks if the buffer entry for the specific data is bigger than the
negative minimum value (after having decremented the buffer value).
Xnee also checks if the absolute sum of the differences for every entry
in the buffer is higher the a total threshold.
If Xnee is getting out of sync it slows down the speed a bit and tries to
continue. However after a while it may happen that Xnee considers that it
no use to continue since we are too much out of sync.
@*
Xnee compensates for the delay during replay that is caused when being out of
sync.
@*
It is possible to tweak the thresholds using the @code{--maximum-threshold},
@code{--negative-threshold} and @code{--total-diff-threshold} options. Is is
also possible to turn off synchronisation completely using the @code{-ns}
option.
|