Added: websites/staging/ooo-site/trunk/content/udk/java/ref/overview-tree.html ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/java/ref/overview-tree.html (added) +++ websites/staging/ooo-site/trunk/content/udk/java/ref/overview-tree.html Sun Nov 27 23:16:00 2011 @@ -0,0 +1,49 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<link href="/css/ooo.css" rel="stylesheet" type="text/css"> + +<title></title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + +</head> + +<body> + <div id="banner"> + <div id="bannerleft"><a alt="Apache OpenOffice.org (incubating)" href="/"> + <img id="ooo-logo alt="Apache OpenOffice.org (Incubating)" src="/images/ooo-logo.png"/></a></div> + <div id="bannerright"><a alt="Apache Incubator" href="http://incubator.apache.org"> + <img id="asf-logo" alt="Apache Incubator" src="/images/apache-incubator-logo.png"/></a></div> + <div id="bannercenter"><br/>(incubating) | The Free and Open Productivity Suite</div> + </div> + <div id="clear"></div> + + <div id="content"> + + + + </div> + + <div id="footera"> + <div id="poweredbya"> + <p><img src="/images/feather-small.gif"/><br/>Powered by the Apache CMS.</p> + </div> + <div id="copyrighta"> + <p> + Apache "OpenOffice.org" is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator. + Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and + decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is + not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has + yet to be fully endorsed by the ASF.</p> + <p> + <a href="/contact.html">Contact Us</a> | + <a href="/terms.html">Terms of Use</a> + <br />Apache and the Apache feather logos are trademarks of The Apache Software Foundation. + <br />OpenOffice.org and the seagull logo are registered trademarks of The Apache Software Foundation. + <br />Other names appearing on the site may be trademarks of their respective owners. + </p> + </div> + </div> + +</body> +</html>
Added: websites/staging/ooo-site/trunk/content/udk/java/ref/package-list ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/java/ref/package-list (added) +++ websites/staging/ooo-site/trunk/content/udk/java/ref/package-list Sun Nov 27 23:16:00 2011 @@ -0,0 +1,4 @@ +com.sun.star.comp.helper +com.sun.star.lib.uno.helper +com.sun.star.tools.uno +com.sun.star.uno Added: websites/staging/ooo-site/trunk/content/udk/java/ref/packages.html ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/java/ref/packages.html (added) +++ websites/staging/ooo-site/trunk/content/udk/java/ref/packages.html Sun Nov 27 23:16:00 2011 @@ -0,0 +1,49 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<link href="/css/ooo.css" rel="stylesheet" type="text/css"> + +<title></title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + +</head> + +<body> + <div id="banner"> + <div id="bannerleft"><a alt="Apache OpenOffice.org (incubating)" href="/"> + <img id="ooo-logo alt="Apache OpenOffice.org (Incubating)" src="/images/ooo-logo.png"/></a></div> + <div id="bannerright"><a alt="Apache Incubator" href="http://incubator.apache.org"> + <img id="asf-logo" alt="Apache Incubator" src="/images/apache-incubator-logo.png"/></a></div> + <div id="bannercenter"><br/>(incubating) | The Free and Open Productivity Suite</div> + </div> + <div id="clear"></div> + + <div id="content"> + + + + </div> + + <div id="footera"> + <div id="poweredbya"> + <p><img src="/images/feather-small.gif"/><br/>Powered by the Apache CMS.</p> + </div> + <div id="copyrighta"> + <p> + Apache "OpenOffice.org" is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator. + Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and + decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is + not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has + yet to be fully endorsed by the ASF.</p> + <p> + <a href="/contact.html">Contact Us</a> | + <a href="/terms.html">Terms of Use</a> + <br />Apache and the Apache feather logos are trademarks of The Apache Software Foundation. + <br />OpenOffice.org and the seagull logo are registered trademarks of The Apache Software Foundation. + <br />Other names appearing on the site may be trademarks of their respective owners. + </p> + </div> + </div> + +</body> +</html> Added: websites/staging/ooo-site/trunk/content/udk/java/ref/serialized-form.html ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/java/ref/serialized-form.html (added) +++ websites/staging/ooo-site/trunk/content/udk/java/ref/serialized-form.html Sun Nov 27 23:16:00 2011 @@ -0,0 +1,49 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<link href="/css/ooo.css" rel="stylesheet" type="text/css"> + +<title></title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + +</head> + +<body> + <div id="banner"> + <div id="bannerleft"><a alt="Apache OpenOffice.org (incubating)" href="/"> + <img id="ooo-logo alt="Apache OpenOffice.org (Incubating)" src="/images/ooo-logo.png"/></a></div> + <div id="bannerright"><a alt="Apache Incubator" href="http://incubator.apache.org"> + <img id="asf-logo" alt="Apache Incubator" src="/images/apache-incubator-logo.png"/></a></div> + <div id="bannercenter"><br/>(incubating) | The Free and Open Productivity Suite</div> + </div> + <div id="clear"></div> + + <div id="content"> + + + + </div> + + <div id="footera"> + <div id="poweredbya"> + <p><img src="/images/feather-small.gif"/><br/>Powered by the Apache CMS.</p> + </div> + <div id="copyrighta"> + <p> + Apache "OpenOffice.org" is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator. + Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and + decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is + not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has + yet to be fully endorsed by the ASF.</p> + <p> + <a href="/contact.html">Contact Us</a> | + <a href="/terms.html">Terms of Use</a> + <br />Apache and the Apache feather logos are trademarks of The Apache Software Foundation. + <br />OpenOffice.org and the seagull logo are registered trademarks of The Apache Software Foundation. + <br />Other names appearing on the site may be trademarks of their respective owners. + </p> + </div> + </div> + +</body> +</html> Added: websites/staging/ooo-site/trunk/content/udk/java/ref/stylesheet.css ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/java/ref/stylesheet.css (added) +++ websites/staging/ooo-site/trunk/content/udk/java/ref/stylesheet.css Sun Nov 27 23:16:00 2011 @@ -0,0 +1,29 @@ +/* Javadoc style sheet */ + +/* Define colors, fonts and other style attributes here to override the defaults */ + +/* Page background color */ +body { background-color: #FFFFFF } + +/* Table colors */ +.TableHeadingColor { background: #CCCCFF } /* Dark mauve */ +.TableSubHeadingColor { background: #EEEEFF } /* Light mauve */ +.TableRowColor { background: #FFFFFF } /* White */ + +/* Font used in left-hand frame lists */ +.FrameTitleFont { font-size: 10pts; font-family: Helvetica, Arial, san-serif } +.FrameHeadingFont { font-size: 10pts; font-family: Helvetica, Arial, san-serif } +.FrameItemFont { font-size: 10pts; font-family: Helvetica, Arial, san-serif } + +/* Example of smaller, sans-serif font in frames */ +/* .FrameItemFont { font-size: 10pt; font-family: Helvetica, Arial, sans-serif } */ + +/* Navigation bar fonts and colors */ +.NavBarCell1 { background-color:#EEEEFF;}/* Light mauve */ +.NavBarCell1Rev { background-color:#00008B;}/* Dark Blue */ +.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;} +.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;} + +.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;} +.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;} + Added: websites/staging/ooo-site/trunk/content/udk/prj/build.lst ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/prj/build.lst (added) +++ websites/staging/ooo-site/trunk/content/udk/prj/build.lst Sun Nov 27 23:16:00 2011 @@ -0,0 +1,3 @@ +uw udkwww : udkapi cppuhelper bridges autodoc NULL +uw udkwww usr1 - all uw_mkout NULL +uw udkwww\util nmake - all uw_util NULL Added: websites/staging/ooo-site/trunk/content/udk/prj/d.lst ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/prj/d.lst (added) +++ websites/staging/ooo-site/trunk/content/udk/prj/d.lst Sun Nov 27 23:16:00 2011 @@ -0,0 +1,9 @@ +..\%__SRC%\bin\udk*.zip %_DEST%\bin%_EXT%\udk*.zip +..\%__SRC%\bin\udk*.tar.gz %_DEST%\bin%_EXT%\udk*.tar.gz + +..\%__SRC%\lib\lib*static*.dylib %_DEST%\lib%_EXT%\lib*static*.dylib +..\%__SRC%\misc\*staticdatamembers.cxx %_DEST%\inc%_EXT%\*staticdatamembers.cxx +..\%__SRC%\misc\*staticdatamembers.h* %_DEST%\inc%_EXT%\*staticdatamembers.h* + +dos: sh -c "if test %OS% = MACOSX; then create-bundle %_DEST%\lib%_EXT%\*.dylib; fi" +dos: sh -c "if test %OS% = MACOSX; then create-libstatic-link %_DEST%\lib%_EXT%; fi" Added: websites/staging/ooo-site/trunk/content/udk/python/download/pyuno-linux-x86-0.9.2.tar.gz ============================================================================== Binary file - no diff available. Propchange: websites/staging/ooo-site/trunk/content/udk/python/download/pyuno-linux-x86-0.9.2.tar.gz ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: websites/staging/ooo-site/trunk/content/udk/python/download/pyuno-linux-x86-0.9.3.tar.gz ============================================================================== Binary file - no diff available. Propchange: websites/staging/ooo-site/trunk/content/udk/python/download/pyuno-linux-x86-0.9.3.tar.gz ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: websites/staging/ooo-site/trunk/content/udk/python/download/pyuno-win32-0.9.2.zip ============================================================================== Binary file - no diff available. Propchange: websites/staging/ooo-site/trunk/content/udk/python/download/pyuno-win32-0.9.2.zip ------------------------------------------------------------------------------ svn:executable = * Propchange: websites/staging/ooo-site/trunk/content/udk/python/download/pyuno-win32-0.9.2.zip ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: websites/staging/ooo-site/trunk/content/udk/python/download/pyuno-win32-0.9.3.zip ============================================================================== Binary file - no diff available. Propchange: websites/staging/ooo-site/trunk/content/udk/python/download/pyuno-win32-0.9.3.zip ------------------------------------------------------------------------------ svn:executable = * Propchange: websites/staging/ooo-site/trunk/content/udk/python/download/pyuno-win32-0.9.3.zip ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: websites/staging/ooo-site/trunk/content/udk/python/images/customized_setup.png ============================================================================== Binary file - no diff available. Propchange: websites/staging/ooo-site/trunk/content/udk/python/images/customized_setup.png ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: websites/staging/ooo-site/trunk/content/udk/python/images/mode_component.png ============================================================================== Binary file - no diff available. Propchange: websites/staging/ooo-site/trunk/content/udk/python/images/mode_component.png ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: websites/staging/ooo-site/trunk/content/udk/python/images/mode_ipc.png ============================================================================== Binary file - no diff available. Propchange: websites/staging/ooo-site/trunk/content/udk/python/images/mode_ipc.png ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: websites/staging/ooo-site/trunk/content/udk/python/images/modes.sxd ============================================================================== Binary file - no diff available. Propchange: websites/staging/ooo-site/trunk/content/udk/python/images/modes.sxd ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: websites/staging/ooo-site/trunk/content/udk/python/images/optional_components.png ============================================================================== Binary file - no diff available. Propchange: websites/staging/ooo-site/trunk/content/udk/python/images/optional_components.png ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: websites/staging/ooo-site/trunk/content/udk/python/libpyuno.so.gz ============================================================================== Binary file - no diff available. Propchange: websites/staging/ooo-site/trunk/content/udk/python/libpyuno.so.gz ------------------------------------------------------------------------------ svn:executable = * Propchange: websites/staging/ooo-site/trunk/content/udk/python/libpyuno.so.gz ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: websites/staging/ooo-site/trunk/content/udk/python/makefile.mk ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/python/makefile.mk (added) +++ websites/staging/ooo-site/trunk/content/udk/python/makefile.mk Sun Nov 27 23:16:00 2011 @@ -0,0 +1,51 @@ +PRJNAME=udkwww +PRJ=.. + +.INCLUDE : settings.mk +.INCLUDE : pyversion.mk + +ROOT=$(MISC)$/pyuno-doc +SCRIPTRT_VERSION=0.1.0 + +FILES=\ + $(ROOT)$/python-bridge.html \ + $(ROOT)$/images$/customized_setup.png \ + $(ROOT)$/images$/mode_component.png \ + $(ROOT)$/images$/mode_ipc.png \ + $(ROOT)$/images$/optional_components.png \ + $(ROOT)$/samples$/swriter.py \ + $(ROOT)$/samples$/swritercomp.py \ + $(ROOT)$/samples$/ooextract.py \ + $(ROOT)$/samples$/oomerge.py \ + $(ROOT)$/samples$/biblioaccess.py \ + $(ROOT)$/samples$/swritercompclient.py \ + $(ROOT)$/samples$/hello_world_pyuno.zip \ + $(ROOT)$/samples$/hello-framework-python.sxp \ + $(ROOT)$/scriptrt4python-$(SCRIPTRT_VERSION).zip + +$(MISC)$/pyuno-doc.zip : $(FILES) + -rm -f $@ + cd $(MISC) && zip -r pyuno-doc.zip pyuno-doc + +$(ROOT)$/samples$/hello_world_pyuno.zip : samples$/hello_world_comp.py samples$/Addons.xcu + -+$(MKDIRHIER) $(@:d) + -rm -f $@ + zip $@ $< + +$(ROOT)$/scriptrt4python-$(SCRIPTRT_VERSION).zip : \ + scriptingframework/runtime.py scriptingframework/Scripting.xcu + -+$(MKDIRHIER) $(@:d) + -rm -f $@ + zip $@ $< + +$(ROOT)$/samples$/hello-framework-python.sxp : scriptingframework/HelloFramework.py scriptingframework/parcel-descriptor.xml + -+$(MKDIRHIER) $(@:d) + -rm -f $@ + +cd scriptingframework && zip ..$/$@ HelloFramework.py parcel-descriptor.xml + +$(ROOT)$/% : % + -+$(MKDIRHIER) $(@:d) + -rm -f $@ + cat $? > $@ + + Added: websites/staging/ooo-site/trunk/content/udk/python/oood/index.html ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/python/oood/index.html (added) +++ websites/staging/ooo-site/trunk/content/udk/python/oood/index.html Sun Nov 27 23:16:00 2011 @@ -0,0 +1,377 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<link href="/css/ooo.css" rel="stylesheet" type="text/css"> + + +<title>oood.py - a simple daemon for OpenOffice.org</title> + + +</head> + +<body> + <div id="banner"> + <div id="bannerleft"><a alt="Apache OpenOffice.org (incubating)" href="/"> + <img id="ooo-logo alt="Apache OpenOffice.org (Incubating)" src="/images/ooo-logo.png"/></a></div> + <div id="bannerright"><a alt="Apache Incubator" href="http://incubator.apache.org"> + <img id="asf-logo" alt="Apache Incubator" src="/images/apache-incubator-logo.png"/></a></div> + <div id="bannercenter"><br/>(incubating) | The Free and Open Productivity Suite</div> + </div> + <div id="clear"></div> + + <div id="content"> + + + +<h1>oood.py - A simple daemon for OpenOffice.org</h1> + +<p>oood.py is a daemon, which controls a pool of 'anonymous' office instances +(workers). +<p> +The workers can be used as backend for Java/python/C++ batch +processes for document conversion, mail merges, etc. You don't need to rewrite your current scripts, +a client connects to a daemon-controlled office just as if would connect to a normal office. Up to +now, I only checked the functionality for batch clients, for server clients (e.g. a tomcat or zope), +there may be some problems, you should simply try it. + +<p>The daemon ensures, that only one client at a time is connected to one OpenOffice instance +(because one OOo instance in general can't cope with more than one scripter). Workers +get restarted after a certain amount of uses or after office crashes. + +<p>A client can connect to a daemon as if it would connect to a normal 'non-daemoned' office, +so you don't need to adapt your scripts. + +<p> oood.py has been implemented in pure python, but it +uses some office components. This should make it easy to modify the daemon +to your needs if desired. + +<p> +Download: <a href="oood-0.1.0.zip">oood-0.1.0.zip</a> (less than 10k): +<h1> State </h1> +The daemon comes in version 0.1.0. It is in a alpha state, it has +currently only be tested on Linux x86. It may run on other Unix +platforms, but it is definitely known <strong>not to run on windows</strong>. Simply try +out to check if it is useful for you (after carefully reading this manual). + +<p> +The daemon and this document is targeted at experienced OOo script developers. + +<h1> Security</h1> +The daemon and its usage is in general <strong>INSECURE</strong>. Everyone, who can connect +to the daemon can use the underlying office instances and thus +has full access to the machine (with the daemon's user rights) and +via socket communication to other machines accessible via sockets +from the worker machine. + +All worker instances run under the same (= the daemon's userid) meaning +that a menace user may spy other worker office instances. + +<p> + +However, some simple limitations can be done. +<ul> +<li> Limiting the access to the daemon.<br/> + You can use the connection string to limit the access to a certain network interface. + E.g. using + + socket,host=localhost,port=2002;urp + + means, that the daemon (and the underlying office instances) can only be accessed + from the same machine, where the daemon is running on. + + One may easily extend the daemon source to limit access e.g. to certain hosts. + + There is no user administration. + +<li> User rights <br/> + Create a special user for running the office instances. Limit the + user's rights to the absolute minimum. +</ul> + +You should use this solution only in a trustworthy environments. + +<h1>Installation</h1> + +<h2> Office installation</h2> +It is assumed, that you use an office from the 1.1.x series. +The office daemon works on an arbitrary number of office user installations, which +must have been created from the same network installation with a single system user. + +Ideally you create a new system user (e.g. oood) therefor, but if you just +want to try it out, you can use your normal system user. + +(The following description is more or less copied from a mail by J. Barfurth +in [email protected]). + +First do a new multi-user installation ( start + +$ setup -net + +) from the downloaded installation set. + +Afterwards, create multiple single user installations by starting +<p> +(use 01 instead of XX) +<p> + +$ setup -d /home/oood/ooo1.1_srvXX + +<p> +from within the office/program directory. +After the setup run, edit ~/.sversionrc file and replace +"OpenOffice.org 1.1.0" with "OpenOffice.org 1.1.0_srvXX". . + +Repeat these steps with XX = 02, 03, ... . You need as many installations +as you expect concurrent users. You may also start with a low number +and add instances later on. + +Afterwards, your .sversionrc file should look like + +<pre> +[Versions] +OpenOffice.org 1.1 srv01=file:///home/oood/ooo1.1_srv01 +OpenOffice.org 1.1 srv02=file:///home/oood/ooo1.1_srv02 +OpenOffice.org 1.1 srv03=file:///home/oood/ooo1.1_srv03 +</pre> + +<h2> Daemon installation</h2> +Switch to the OpenOffice.org's program directory and +extract the oood-0.1.0.zip file. Open the oood-0.1.0/oood-config.xml file +in a text editor and add the paths of every worker instances with a + +<user-installation url="file:///home/oood/ooo1.1_srv01" /> + +tag. For a start, just add one or two instances to see how the daemon is working. +All other settings in oood-config.xml can be left untouched. The meaning +of the other settings are documented in the comments. + +<h1>Daemon administration</h1> +<h2>Starting</h2> +The daemon must be started with OpenOffice.org's python from within the OOo's program +directory. +<p> + + +$ ./python oood-0.1.0/oood.py -c oood-0.1.0/oood-config.xml run + +</p> +You get the log on the stdout blocking the shell. Depending on the number of +workers you have configured, it may +take quite a while to start. When you get a + +<p> +Accepting on <your-connection-string> +</p> + +the daemon is ready to serve requests. + +<h2>Stopping</h2> + +From a different shell, start +<p> +$ ./python oood-0.1.0/bin/oood.py -c oood-0.1.0/config/oood-config.xml stop + +<p> + +Signals the daemon to terminate all running workers and itself. + +The daemon can only be stopped this way after a successful startup. + +<h2>Requesting status information</h2> +<p> +$ ./python oood-0.1.0/oood.py -c oood-0.1.0/oood-config.xml status +<p> +Gives you a list of workers and their state. + +<h1> Usage patterns </h1> +You can now connect to the daemon with an arbitrary (Java, C++, python) +client program in exactly the same way as you connect to a normal +OpenOffice.org. + +<p>The daemon delegates your request to one of its worker offices. For the +time of usage, this worker office is exclusively used by your client program. +The end of usage is detected by the daemon through a breakdown +of the interprocess bridge (which occurs, when the last +reference is gone, the client explicitly disposes the remote bridge or +the client process terminates). + +<h1> Performance</h1> +All requests to the office are tunneled through the daemon process. This +means an additional load on the server machine and a performance overhead +for every request. This is typically neglectable when your call frequency +is low (say less than 10 Calls/s), but becomes a significant overhead +for higher call frequencies. + +<h1>Logging</h1> +<h2> Log level</h2> +<p>There is 3 log levels.</p> + +<table border="3" summary="Log levels"> +<tr><td>SERIOUS</td><td>Only startup information and errors get written into the log</td></tr> +<tr><td>INFO</td><td>information about every connect and disconnect get logged (default)</td></tr> +<tr><td>DETAIL</td><td>Log level mostly sensible for debugging</td></tr> +</table> + +<p>Level INFO includes SERIOUS, DETAIL includes INFO and HIGH.</p> + +<h2> Log format </h2> +Every line, that gets logged, has the following format + +<pre> +current-time [loglevel] : Logtext +</pre> + +The numbers in curly brackets (e.g. {2/5}) in the logtext signals +the free/total number of worker processes in the pool . + +<h2> Startup log </h2> +A typical startup log looks as follows ( on INFO loglevel) +<pre> + +Wed Nov 26 19:11:19 2003 [SERIOUS]: Started on pid 674 +Wed Nov 26 19:11:19 2003 [INFO ]: Starting office workers ... +Wed Nov 26 19:11:19 2003 [INFO ]: Worker-0:<oood.OfficeProcess + file:///home/joergl/OpenOffice.org1.1.0_instance-0; + pid=692;connectStr=pipe,name=oood-instance-0,usage=0> started +Wed Nov 26 19:11:59 2003 [INFO ]: {2/2} WorkerAll instances started +Wed Nov 26 19:11:59 2003 [SERIOUS]: Accepting on socket,host=localhost,port=2002;urp + +</pre> +First line gives the pid of the daemon process (in case +you want to terminate the process during startup). Then follows for +every worker process, that gets started a line showing the used +home directory and connection string. + +<h2> Working log </h2> +Below you can see a typical log of a single connect attempt: +<pre> +Wed Nov 26 19:24:02 2003 [INFO ]: {1/2} -> Worker-0(1 uses) serves localhost:32770 +Wed Nov 26 19:24:13 2003 [INFO ]: localhost:32770 disconnects from Worker-0(1 uses) (used for 10.7s) +Wed Nov 26 19:24:13 2003 [INFO ]: {2/2} <- Worker-0(1 uses) reenters pool + +</pre> + +First line states that out of the pool Worker-0 1is used to serve the incoming +request from localhost:32770. The {1/2} indicates, that there one free worker +left is in the pool. + +Second line states, that the interprocess bridge between the daemon +and the requesting process has broken down. Additionally, +the number of uses and the duration of the last use in seconds is shown. + +In case, the number of uses is less than the max-usage-count-per-instance, +the process is simply added to the pool of available offices again (as it +documented by the third line. The {2/2} states, that there are now exactly +two workers in the pool again. + +In case the max-usage-count-per-instance is exceeded, this worker instance is automatically +terminated and a fresh instance is restarted. This shall tide up memory leaks. + +When there is no free worker left anymore and a client request comes in, +the request is rejected and a line like the following gets logged: +<pre> +Sat May 22 22:28:46 2004 [SERIOUS]: {0/2} localhost:32776 rejected +</pre> + +The client script simply gets a empty reference instead of the requested object. +<p> +<font size="-2"> +Note: Preferably it would receive a RuntimeException with an appropriate +message, but a bug somewhere around pyuno, the scripting components +and the remote bridge currently prevents this (the daemons crashes +quite fast). +</font> + +<h2> Termination log </h2> +Once daemon termination has been initiated, the log should look like the following: +<pre> +Sat May 22 22:33:00 2004 [SERIOUS]: Accepting on socket,host=localhost,port=2002;urp stopped, waiting for shutdownthread +Sat May 22 22:33:00 2004 [INFO ]: Admin thread terminating +Sat May 22 22:33:00 2004 [INFO ]: terminating Worker-0(1 uses) +Sat May 22 22:33:00 2004 [INFO ]: Worker-0(1 uses) terminated +Sat May 22 22:33:00 2004 [INFO ]: terminating Worker-1(1 uses) +Sat May 22 22:33:00 2004 [INFO ]: Worker-1(1 uses) terminated +Sat May 22 22:33:00 2004 [SERIOUS]: Terminating normally +</pre> +<h1> Robustness </h1> +Robustness and stability is certainly a key feature of a daemon. The following +situations are currently handled: + +<ul> +<li> Running out of workers <br/> +In case all worker instances are busy and the pool is empty, every new +connection attempt is rejected, the client receives an empty reference +instead of the servicemanager or componentcontext object. + +<p> +<font size="-2"> +Note: Preferably it would receive a RuntimeException with an appropriate +message, but a bug somewhere around pyuno, the scripting components +and the remote bridge currently prevents this (the daemons crashes +quite fast). +</font> + +<p> +The connection attempt gets logged appropriately. +<li> A worker office crashes or deadlocks <br/> +Before a worker reenters the pool, it is checked, whether +it is still responsive and it checks whether a deadlock +with the solarmutex blocks the whole office. In case +such a situation occurred, the worker is killed and a fresh +instance is started and added again to the pool. + +<p> +The check is currently quite rudimentary, it may +be improved in future. +</li> + +<li> Worker processes are restarted after a certain amount of client uses. This ensures, +that an ill office instance will die sooner or later. +</li> + +<li> Note: In case the daemon itself crashes (I am currently not aware of such a situation), + the worker instances don't + terminate, an admin needs to kill the instances by hand and restart the daemon. +</li> + +</ul> + +<h1> License </h1> +As you are used to when using OOo, this program is LGPL. + +<h1> Feedback</h1> +Please give feedback through [email protected] mailing list. + + +<h1> Author </h1> +The daemon has been developed by <a href="mailto:[email protected]">Joerg Budischewski</a>. +I'd very much welcome patches for an improved daemon and would even very much welcome someone +taking over maintenance for the daemon. + + + + </div> + + <div id="footera"> + <div id="poweredbya"> + <p><img src="/images/feather-small.gif"/><br/>Powered by the Apache CMS.</p> + </div> + <div id="copyrighta"> + <p> + Apache "OpenOffice.org" is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator. + Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and + decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is + not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has + yet to be fully endorsed by the ASF.</p> + <p> + <a href="/contact.html">Contact Us</a> | + <a href="/terms.html">Terms of Use</a> + <br />Apache and the Apache feather logos are trademarks of The Apache Software Foundation. + <br />OpenOffice.org and the seagull logo are registered trademarks of The Apache Software Foundation. + <br />Other names appearing on the site may be trademarks of their respective owners. + </p> + </div> + </div> + +</body> +</html> Added: websites/staging/ooo-site/trunk/content/udk/python/oood/makefile.mk ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/python/oood/makefile.mk (added) +++ websites/staging/ooo-site/trunk/content/udk/python/oood/makefile.mk Sun Nov 27 23:16:00 2011 @@ -0,0 +1,26 @@ +PRJNAME=udkwww +PRJ=../.. + +.INCLUDE : settings.mk +.INCLUDE : pyversion.mk + +VERSION=0.1.0 + +ROOT=$(MISC)$/oood-$(VERSION) + +FILES=\ + $(ROOT)/oood.py \ + $(ROOT)/index.html \ + $(ROOT)/oood-config.xml + + +$(ROOT).zip : $(FILES) + -rm -f $@ + cd $(MISC) && zip -r oood-$(VERSION).zip oood-$(VERSION) + md5sum $@ + + +$(ROOT)/% : % + -+$(MKDIRHIER) $(@:d) + rm -f $@ + cat $< > $@ Added: websites/staging/ooo-site/trunk/content/udk/python/oood/oood-0.1.0.zip ============================================================================== Binary file - no diff available. Propchange: websites/staging/ooo-site/trunk/content/udk/python/oood/oood-0.1.0.zip ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: websites/staging/ooo-site/trunk/content/udk/python/oood/oood-config.xml ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/python/oood/oood-config.xml (added) +++ websites/staging/ooo-site/trunk/content/udk/python/oood/oood-config.xml Sun Nov 27 23:16:00 2011 @@ -0,0 +1,38 @@ +<?xml version="1.0"?> +<oood-config> + <!-- uncomment this to allow connects from all hosts --> + <!--acceptor value="socket,host=0,port=2002;urp"--> + + <!-- allow connects from this machine only --> + <acceptor value="socket,host=localhost,port=2002;urp"/> + + <!-- is used to shutdown and retrieve information from the daemon --> + <admin-acceptor value="socket,host=localhost,port=2001;urp"/> + + <!-- path to user installations --> + <user-installation url="file:///home/joergl/OpenOffice.org1.1.0_instance-0" /> + <user-installation url="file:///home/joergl/OpenOffice.org1.1.0_instance-1" /> +<!-- + <user-installation url="file:///home/joergl/OpenOffice.org1.1.0_instance-2" /> +--> + <!-- number of seconds, that are given an OpenOffice.org worker instance to start. + In case the time is exceeded, daemon will terminate (and thus signaling, + that there is something wrong with the overall setup) + --> + <tolerated-startuptime-per-instance value="180"/> + + <!-- a concrete OOo instances gets sick with time (e.g. memory leaks, inconsistencies, + aborted scripts which left documents opened, etc. ). Attribute max gives the + number upper number of 'uses' by + a client, after which the office instance gets restarted. As a fixed + limit tends to lead to load peaks on certain points of time, this limit can + be randomized with the random attribute. + --> + <usage-count-per-instance max="10" random="3"/> + + <!-- The verbosity of the daemon. + Can be high (errors only), + info (proposed, gives some useful administration information), + detail (for debugging) --> + <logging level="info"/> +</oood-config> Added: websites/staging/ooo-site/trunk/content/udk/python/oood/oood.py ============================================================================== --- websites/staging/ooo-site/trunk/content/udk/python/oood/oood.py (added) +++ websites/staging/ooo-site/trunk/content/udk/python/oood/oood.py Sun Nov 27 23:16:00 2011 @@ -0,0 +1,678 @@ +#************************************************************************* +# +# $RCSfile: oood.py,v $ +# +# $Revision: 1.1 $ +# +# last change: $Author: jbu $ $Date: 2004/10/03 17:41:40 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (the "License"); You may not use this file +# except in compliance with the License. You may obtain a copy of the +# License at http://www.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Joerg Budischewski +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): Joerg Budischewski +# +#************************************************************************* +import uno +import unohelper +import os +import time +import sys +import signal +import threading +import random + +from com.sun.star.bridge import XInstanceProvider +from com.sun.star.connection import NoConnectException, ConnectionSetupException +from com.sun.star.io import XStreamListener +from com.sun.star.lang import IllegalArgumentException +from com.sun.star.uno import RuntimeException +from com.sun.star.xml.sax import XDocumentHandler, InputSource +from com.sun.star.io import XInputStream +from com.sun.star.container import XNameAccess +from com.sun.star.beans import NamedValue + +SERIOUS = 0 +INFO = 1 +DETAIL = 2 +LEVEL2STRING = { SERIOUS : "SERIOUS", INFO : "INFO " , DETAIL : "DETAIL " } +COMMANDS = ( "run", "stop" , "status" ) +cmd = None +configfile = None + +def usage(): + print "usage: oood.py -c config-file run|stop|status" + print " daemon for openoffice" + + +i = 1 +while i < len(sys.argv): + if sys.argv[i] == "-c": + i = i + 1 + configfile = sys.argv[i] + elif sys.argv[i] in COMMANDS: + cmd = sys.argv[i] + else: + usage() + os._exit(1) + i = i + 1 + +if cmd == None or configfile == None: + usage() + os._exit(1) + + +class FileInputStream( XInputStream, unohelper.Base ): + def __init__( self, path ): + self.f = file( path ) + + def closeInput( self): + self.f.close() + + def skipBytes( self, nByteCount ): + self.f.read( nByteCount ) + + def readBytes( self, retSeq, nByteCount ): + s = self.f.read( nByteCount ) + return len( s ) , uno.ByteSequence( s ) + + def readSomeBytes( self, retSeq , nByteCount ): + #as we never block ! + return self.readBytes( retSeq, nByteCount ) + + def available( self ): + return 0 + +class Config: + def __init__( self ): + self.acceptor = "" + self.userInstallation = () + self.toleratedStartupTimePerInstance = 180 + self.maxUsageCountPerInstance = 10 + self.randomUsageCountPerInstance = 3 + self.loglevel = INFO + + def __str__(self): + return "acceptor="+self.acceptor+", userInstallation="+str(self.userInstallation) + \ + ", toleratedStartupTimePerInstance=" + str( \ + self.toleratedStartupTimePerInstance ) + ", maxUsageCountPerInstance="+ \ + str( self.maxUsageCountPerInstance ) + ", randomUsageCountPerInstance=" + \ + str( self.randomUsageCountPerInstance ) + ",loglevel= "+ str(self.loglevel) + +class ConfigHandler( XDocumentHandler, unohelper.Base ): + def __init__( self ): + pass + + def startDocument( self ): + self.config = Config() + + def endDocument( self ): + pass + + def startElement( self , name, attlist): + if name == "acceptor": + self.config.acceptor = attlist.getValueByIndex(0 ) + elif name == "admin-acceptor": + self.config.adminAcceptor = attlist.getValueByIndex(0 ) + elif name == "user-installation": + self.config.userInstallation = self.config.userInstallation + ( + attlist.getValueByName( "url" ), ) + elif name == "tolerated-startuptime-per-instance": + self.config.toleratedStartupTimePerInstance = int( + attlist.getValueByName( "value" ) ) + elif name == "usage-count-per-instance": + self.config.maxUsageCountPerInstance = int( + attlist.getValueByName( "max" ) ) + self.config.randomUsageCountPerInstance = int( + attlist.getValueByName( "random" ) ) + elif name == "logging": + l = attlist.getValueByName( "level" ) + if l == "info": + self.config.loglevel = INFO + elif l == "serious": + self.config.loglevel = SERIOUS + elif l == "detail": + self.config.loglevel = DETAIL + else: + raise RuntimeException( "Unknown loglevel " + l , None ) + + def endElement( self, name ): + pass + + def characters ( self, chars ): + pass + + def ignoreableWhitespace( self, chars ): + pass + + def setDocumentLocator( self, locator ): + pass + +def readConfiguration( path, parser ): + h = ConfigHandler() + parser.setDocumentHandler( h ) + parser.parseStream( + InputSource( FileInputStream( path ) , "", path, path ) ) + return h.config + +def namedValueTupleToMap( t ): + m = {} + for i in t: + m[ i.Name ] = i.Value + return m + +ctx = uno.getComponentContext() +config = readConfiguration( + configfile,ctx.ServiceManager.createInstance("com.sun.star.xml.sax.Parser")) + +if cmd == "stop": + uno.getComponentContext().ServiceManager.createInstance( + "com.sun.star.bridge.UnoUrlResolver").resolve( + "uno:"+config.adminAcceptor+";oood.Shutdown" ) + os._exit(0) +elif cmd == "status": + status = uno.getComponentContext().ServiceManager.createInstance( + "com.sun.star.bridge.UnoUrlResolver").resolve( + "uno:"+config.adminAcceptor+";oood.Status" ) + + if status == None: + print "Couldn't resolve status object" + print "Instances in daemon (free/total): " +str(status.getByName( "available" )) + \ + "/" + str( status.getByName( "poolsize" ) ) + + workers = status.getByName( "workers" ) + print "Worker\tpid\tin use\tusages\tduration\tuser-directory" + for i in workers: + out = "" + m = namedValueTupleToMap( i ) + inuse = " " + duration = " \t" + if m["usage-time"] > 0: + inuse = "x" + duration = str( round(m["usage-time" ],2) ) + "s \t" + + print str( m["index"]) + "\t" + \ + str( m["pid"] ) + " \t" + \ + inuse +"\t" + \ + str( m["usage"] ) + "\t" + \ + duration +\ + str( m["user-dir" ] ) + os._exit(0) + +NULL_DEVICE = "/dev/null" +processPool = None + + +class PoolAdderThread( threading.Thread ): + def __init__( self, process ): + threading.Thread.__init__( self ) + self.process = process + + def run( self ): + try: + if not self.process.restartWhenNecessary(): + logger.log( SERIOUS, "FATAL: could not restart worker " + + str(self.process) + ", terminating now !" ) + os._exit(1) + processPool.append( self.process ) + logger.log( INFO, processPool.getStateString()+" <- "+str(self.process)+ + " reenters pool" ) + except Exception,e: + logger.log( SERIOUS, str(e) ) + + +class Status( unohelper.Base, XNameAccess ): + def __init__( self, processList ): + self.map = {} + self.map[ "poolsize" ] = len( processList ) + available = 0 + workers = [] + for i in processList: + v = None + if i.timestamp == None: + v = NamedValue( "usage-time" , 0 ) + available = available + 1 + else: + v = NamedValue( "usage-time", time.time() - i.timestamp ) + + t = NamedValue( "pid", i.pid ), \ + NamedValue( "usage", i.usage ), \ + v, \ + NamedValue( "user-dir" , i.userid ), \ + NamedValue( "index", i.index ) + workers.append( t ) + self.map[ "workers" ] = tuple( workers ) + self.map[ "available" ] = available + + def getByName( self, name ): + if self.map.has_key( name ): + return self.map[ name ] + raise NoSuchElementException( "unknown element " + name, self ) + + def getElementNames( self ): + return tuple( self.map.keys() ) + + def hasByName( self , name ): + return self.map.has_key( name ) + + def getElementType( self ): + return Type() + + def hasElements( self ): + return True + +class ProcessPool: + def __init__( self ): + self.lst = [] + self.mutex = threading.Lock() + + def append( self , item ): + self.mutex.acquire() + self.lst.append( item ) + self.mutex.release() + + def initializationFinished( self ): + self.all = tuple( self.lst ) + + def size( self ): + return len( self.lst ) + + def terminate( self ): + for i in self.all: + i.terminate() + + def pop( self ): + ret = None + while ret == None: + self.mutex.acquire() + if len(self.lst) == 0: + self.mutex.release() + break + ret = self.lst.pop(0) + self.mutex.release() + if not ret.isResponsive(): + # process has died inbetween + PoolAdderThread( ret ).start() + ret = None + return ret + + def waitTillReady( self ): + for i in self.lst: + if not i.waitTillReady( + self.size() * config.toleratedStartupTimePerInstance ): + os._exit(1) + def getStateString( self): + global config + return "{" + str(self.size()) + "/" + str(len(config.userInstallation)) + "}" + +class Logger: + def __init__( self , out, level ): + self.out = out + self.level = level + + def log( self, level , text ): + if level <= self.level: + self.out.write( + time.asctime() + " ["+ + LEVEL2STRING[level] +"]: " + text + "\n") + +processPool = ProcessPool() +random.seed() +logger = Logger( sys.stdout, config.loglevel ) +shutdownThread = None + +acceptor = ctx.ServiceManager.createInstance( + "com.sun.star.connection.Acceptor" ) +bridgefactory = ctx.ServiceManager.createInstance( + "com.sun.star.bridge.BridgeFactory" ) +connector = ctx.ServiceManager.createInstance( + "com.sun.star.connection.Connector" ) + +def getConnectString( index ): + return "pipe,name=oood-instance-" + str(index) + +class AdminInstanceProvider( unohelper.Base, XInstanceProvider ): + def getInstance( self, name ): + object = None + if name == "oood.Shutdown": + global shutdownThread + shutdownThread = threading.Timer( 1.0, shutdown , (0,processPool) ) + shutdownThread.start() + elif name == "oood.Status": + object = Status( processPool.all ) + else: + logger.log( DETAIL, "AdminInstanceProvider: Unknown object " +name ) + return object + +class AdminAcceptorThread( threading.Thread ): + def __init__( self , ctx, acceptString ): + threading.Thread.__init__(self) + self.ctx = ctx + self.acceptString = acceptString + self.acceptor = self.ctx.ServiceManager.createInstance( + "com.sun.star.connection.Acceptor") + + def run( self ): + logger.log( INFO, "Admin thread started" ) + while True: + c = self.acceptor.accept( self.acceptString ) + if c == None: + break + logger.log( DETAIL, "Accepted admin connection from "+ + extractContactInfo(c.getDescription())) + bridgefactory.createBridge( "", "urp", c, AdminInstanceProvider() ) + + logger.log( INFO, "Admin thread terminating" ) + + def cancel( self ): + self.acceptor.stopAccepting( ) + +class TerminateThread( threading.Thread ): + def __init__( self, ctx ): + threading.Thread.__init__( self ) + self.ctx = ctx + + def run( self ): + try: + self.ctx.ServiceManager.createInstance( "com.sun.star.frame.Desktop").terminate() + except Exception: + pass + +class ResponsivenessChecker( threading.Thread ): + def __init__( self, process ): + threading.Thread.__init__(self) + self.process = process + self.responsive = False + + def isResponsive( self ): + self.join( 4 ) + return self.responsive + + def run( self ): + try: + # still alive ? + smgr = self.process.ctx.ServiceManager + desktop = smgr.createInstance( "com.sun.star.frame.Desktop" ) + + # check for typical solar-mutex deadlock + desktop.getCurrentComponent() + + # more checks may be added + self.responsive = True + + except Exception,e: + logger.log( SERIOUS, "responsiveness-check for " + str( self.process) + + " failed: " + str(e) ) + +def calculateMaxUsageCount(): + return config.maxUsageCountPerInstance + \ + ( 1. - 2*random.random()) * config.randomUsageCountPerInstance + +def shutdown( returncode , pool ): + acceptor.stopAccepting() + pool.terminate() + +class OfficeProcess: + def __init__( self , userid, index): + self.userid = userid + self.index = index + self.pid = None + self.usage = 0 + self.timestamp = None + self.bridge = None + self.ctx = None + + def start(self): + self.pid = os.spawnlp( + os.P_NOWAIT, + "soffice", + "" , # what is this for a string ? + "-env:UserInstallation="+self.userid , + "-headless", + "-norestore", + "-invisible", + "-accept="+getConnectString(self.index)+ ";urp;" ) + + def kill( self ): + if self.pid: + os.kill( self.pid, signal.SIGKILL ) + logger.log( INFO, str( self ) + " killed" ) + + def isAlive( self ): + return os.system( "ps -p " + str( self.pid ) + " >" + NULL_DEVICE ) == 0 + + def terminate( self ): + if self.ctx: + t = TerminateThread( self.ctx ) + logger.log( INFO, "terminating " +str( self ) ) + t.start() + t.join( 4 ) + if t.isAlive(): + logger.log( + SERIOUS, repr( self ) + " did not react on terminate, killing instance" ) + self.kill() + else: + logger.log( INFO, str( self ) + " terminated" ) + self.ctx = None + + def terminateAndRestart( self ): + self.terminate() + time.sleep( 4 ) + self.start() + if not self.waitTillReady( config.toleratedStartupTimePerInstance ): + logger.log( SERIOUS, "could not restart instance "+str(self)+", terminating" ) + return False + self.usage = 0 + return True + + def tryConnect( self ): + try: + con = connector.connect( getConnectString( self.index ) ) + self.bridge = bridgefactory.createBridge( "", "urp" , con, None ) + self.ctx = self.bridge.getInstance( "StarOffice.ComponentContext" ) + return self.ctx != None + except NoConnectException,e: + logger.log( DETAIL, str(self)+ " not yet responsive" ) + except Exception,e: + logger.log( SERIOUS , "couldn't connect to instance ("+str(e)+")" ) + return False + + def waitTillReady( self , timeout ): + start = time.time() + while not self.tryConnect( ) and time.time()-start < timeout: + time.sleep( 4 ) + + if time.time() - start > timeout: + return False + return True + + def __str__(self): + return "Worker-" + str(self.index) + "("+str(self.usage)+" uses)" + + def __repr__(self): + return "<oood.OfficeProcess %s;pid=%d;connectStr=%s,usage=%d>" % \ + (self.userid,self.pid,getConnectString(self.index),self.usage) + + def startUsage( self ): + self.usage = self.usage + 1 + self.timestamp = time.time() + + def getUsageDuration( self ): + return time.time() - self.timestamp + + def endUsage( self ): + self.timestamp = None + + def isResponsive( self ): + t = ResponsivenessChecker( self ) + t.start() + return t.isResponsive() + + def restartWhenNecessary( self ): + if not self.isResponsive(): + logger.log( INFO, "process " + str(self) +\ + " not responsive anymore, restarting" ) + self.usage = 0 + return self.terminateAndRestart() + + if self.usage >= calculateMaxUsageCount(): + logger.log( INFO, "max usage count for instance " + str(self) +\ + " reached, restarting" ) + return self.terminateAndRestart() + return True + + + +class ConnectionListener( unohelper.Base, XStreamListener ): + def __init__( self , officeProcess, conDesc ): + self.officeProcess = officeProcess + self.conDesc = conDesc + + def clear( self ): + if self.officeProcess != None: + logger.log( INFO, self.conDesc + " disconnects from " + + str( self.officeProcess ) + " (used for "+ + str(round(self.officeProcess.getUsageDuration(),1)) +"s) " ) + self.officeProcess.endUsage( ) + PoolAdderThread( self.officeProcess ).start() + self.officeProcess = None + + def started( self ): + pass + + def closed( self ): + self.clear() + def terminated( self ): + self.clear() + def error( self , exception ): + self.clear() + + +class OfficeInstanceProvider( unohelper.Base, XInstanceProvider ): + def __init__( self, office ): + self.office = office + + def getInstance( self, name ): + logger.log( DETAIL, "resolving name " +name ) + object = self.office.bridge.getInstance( name ) + return object + +class EmptyPoolInstanceProvider( unohelper.Base, XInstanceProvider ): + def getInstance( self, name ): + return None +# raise RuntimeException( "No office instance available, try later" , None ) + +def extractContactInfo( namevalue ): + lst = namevalue.split( "," ) + host = "" + port = "" + for i in lst: + if i.startswith( "peerHost" ): + host = i.split("=")[1] + elif i.startswith( "peerPort" ): + port = i.split("=")[1] + return host + ":" + port + + +logger.log( SERIOUS, "Started on pid " + str( os.getpid() ) ) + + +index = 0 +logger.log( INFO, "Starting office workers ..." ) + +for i in config.userInstallation: + office = OfficeProcess( i , index ) + office.start() + logger.log( INFO, "Worker-" +str(index) + ":" + repr(office) +" started") + processPool.append( office ) + index = index + 1 + +processPool.waitTillReady() +processPool.initializationFinished() + +adminThread = AdminAcceptorThread( ctx, config.adminAcceptor ) +adminThread.start() + +logger.log( INFO , processPool.getStateString()+ " WorkerAll instances started" ) +logger.log( SERIOUS, "Accepting on " + config.acceptor ) + +while True: + con = acceptor.accept( config.acceptor ) + if con == None: + break + + conDesc = extractContactInfo(con.getDescription()) + logger.log( INFO , "Incoming request for a worker from " + conDesc ) + process = processPool.pop() + if process == None: + logger.log( SERIOUS, processPool.getStateString()+" " + conDesc + + " rejected, all workers are busy" ) + bridgefactory.createBridge( + "", "urp", con , EmptyPoolInstanceProvider( ) ) + else: + process.startUsage() + logger.log( INFO, processPool.getStateString()+" -> " + + str(process) +" serves "+conDesc) + + con.addStreamListener( ConnectionListener(process,conDesc) ) + bridgefactory.createBridge( + "", "urp", con , OfficeInstanceProvider( process ) ) + +logger.log( SERIOUS, "Accepting on " + config.acceptor + + " stopped, waiting for shutdownthread") + +adminThread.cancel() + +if shutdownThread != None: + shutdownThread.join() + +if adminThread != None: + adminThread.join() + +logger.log( SERIOUS, "Terminating normally") + +
