Mutiple Persevere Apps

0 views
Skip to first unread message

Paul Spaulding

unread,
Oct 30, 2009, 11:38:18 AM10/30/09
to Persevere
First of all, my apologies for starting a new thread on this topic vs.
posting to the old thread http://groups.google.com/group/persevere-framework/browse_thread/thread/0a84d7f93e813672#
...the only option was reply to author (don't know if that's because
it is an old thread or what).

I am still trying to figure this out. I've been playing around with
Jetty and trying to understand how contexts work. I think I would
ideally have a single webapp with any number of contexts based on that
webapp that are accessed through different URL mappings, either
http://contextFoo.domain.com (preferable) or http://www.domain.com/contextFoo.
I want them all to run on the same port (80) and the only difference
between them is that they would each have their own separate
JavaScriptDB (or whatever) data store. I would also like to be able
to add new contexts (hot-deploy) without restarting Jetty/Persevere.

Is it possible to configure the base-uri in the web.xml file (or in my
case, an override-web.xml file) as a context-param? My wishful
experiment with this did not work. Is there a better approach? What
is the minimum file duplication I would need to do across each
context?

Does it make sense to have a single instance of Persevere handle
multiple contexts, or is that asking for trouble? Maybe I'm still
trying to approach this from the wrong angle.

Paul Spaulding

unread,
Oct 30, 2009, 11:43:14 AM10/30/09
to Persevere
I should also mention that I tried starting two unique persevere apps
from two different command line shells on the same port but with
different base-uri paths (--base-uri /foo and --base-uri /bar). That
did not work. There were no errors, but whichever instance that was
started first ruled.

Paul Spaulding

unread,
Oct 30, 2009, 4:46:23 PM10/30/09
to Persevere
Similar to the question above, can the database path (as in the --
database command line option) be configured from a web.xml context-
param? I have found that I can get multiple persevere apps running
each in their own webapps directory and using the JETTY-HOME/lib
directory to store the common jar files. However, I have duplicate
files between both webapps when all I really want is a read-only
version of all the common client files and jslib files, and unique
instances of the data/jsdb directory. Also as mentioned above, there
is no opportunity to hot-deploy apps in this manner. Sorry for
rambling on and on.

Paul Spaulding

unread,
Nov 3, 2009, 11:39:14 AM11/3/09
to Persevere
This is my approach so far to run multiple hot-deployable instances of
a shared Persevere application (each with its own datasource) inside
Jetty. This is still not optimal for what I'm after but perhaps this
might help someone.

I used Persevere v1.0 beta 6 and Jetty v6.1.14 and modified jetty as
follows:

- comment out the webapp deployer in etc\jetty.xml (I only wanted hot-
deployable contexts, leave this in if you want standard webapps).
- copy and add the files from persevere\lib to jetty\lib
- copy and add the files from persevere\WEB-INF\lib to jetty\lib
EXCEPT persevere.jar, js.jar, and jline-0.9.94.jar
- for each app to be deployed to the jetty\contexts directory:
- create the application directory (we'll call the instance foo for
this example):

jetty
+ contexts
+ foo
+ static resource directories (css, images, js, etc.)
+ WEB-INF
+ config
+ data
+ jslib
+ lib
js.jar (from persevere\WEB-INF\lib)
persevere.jar (from persevere\WEB-INF\lib)
web.xml (from persevere\WEB-INF)

- create the deployment file contexts\foo.xml:

<?xml version='1.0' encoding='ISO-8859-1'?>
<!DOCTYPE Configure PUBLIC '-//Mort Bay Consulting//DTD Configure//
EN' 'http://jetty.mortbay.org/configure.dtd'>
<Configure class='org.mortbay.jetty.webapp.WebAppContext'>
<Set name='contextPath'>/</Set>
<Set name='resourceBase'><SystemProperty name='jetty.home'
default='.'/>/contexts/foo</Set>
<Set name='extractWAR'>false</Set>
<Set name='copyWebDir'>false</Set>
<Set name='descriptor'><SystemProperty name='jetty.home'
default='.'/>/contexts/foo/WEB-INF/web.xml</Set>
<Set name='defaultsDescriptor'><SystemProperty name='jetty.home'
default='.'/>/etc/webdefault.xml</Set>
<Set name='tempDirectory'><SystemProperty name='jetty.home'
default='.'/>/contexts/foo/WEB-INF/data</Set>
<Set name='virtualHosts'>
<Array type='String'>
<Item>foo.mydomain.com</Item>
</Array>
</Set>
</Configure>

Start jetty: java -Xmx128m -jar start.jar

Notes:
- I intentionally left out jline-0.9.94.jar because you can't have
multiple command lines for each app in the same shell. If you leave
it in, you'll get a js> prompt, but I don't know how to assign it to a
particular webapp. Leaving it out results in harmless warnings. Use
ctrl-c to exit Jetty if running from a command line.

- The deployment file in this case uses a virtual host subdomain to
map contexts. I tried doing this using context paths (<Set
name='contextPath'>/foo/</Set>) but I was getting odd behavior with
Dojo on the client. This could probably work with a little more time
and care than what I was willing to spend. Using the virtual hosts in
this manner also allows me to specify a *.mydomain.com that presents a
login form that always returns an authentication failure. I wanted
this so that a group of users could not detect the presence or absence
of another group by guessing subdomains.

- The tempDirectory setting was the only way I found to trick Jetty/
Persevere into using the correct location for the data\jsdb location.
As a result, Jetty uses this as the working directory and will also
create an empty jsp directory. It can be ignored. I think it would
be really useful to be able to specify this as a context-param inside
the instance web.xml file similar to the way one specifies the
database path from a single instance command line.

- I really wanted a way of having a single copy of the webapp where
each group of users would have their own database based on the
subdomain but everything else was the same. Since I am developing on
Windows, I used the junction utility (http://technet.microsoft.com/en-
us/sysinternals/bb896768.aspx) to create symbolic links to the common
files. This is built into Linux from what I understand. This
requires some care when adding directories so I created a batch file
to create the new context directories, setup the junctions and create
the deployment xml files based on a command line param.

- I tested this with 30 instances of Persevere running. After two or
three instances, I had to supply the -Xmx128m to avoid heap memory
errors. Each test context had its own unique Persevere native
datastore weighing in at 6.6MB for the index.psv + transactions.psv
files. I did not do any load testing, but I did find that each
additional context added an additional ~3MB of memory usage to the
java process...fairly reasonable IMO. The problems start at about 30
instances where I started getting "OutOfMemoryError: PermGen space"
errors. Increasing the -Xmx parameter has no effect on this error,
and Jetty does not accept the -XX:MaxPermSize=???m parameter for some
reason.

I am not crazy about this approach for a shared application because it
consumes system resources unnecessarily. Ideally, a single instance
of Persevere would be able to attach to any datasource on the fly
based on the request object and then continue on with the normal
Persevere processing magic. I may open a new thread on that topic.
However, I think this approach works well for cases where multiple
Persevere apps with distinct code bases need to be deployed on the
same server (probably the case for everyone else except me).

Paul Spaulding

unread,
Nov 3, 2009, 4:23:42 PM11/3/09
to Persevere
I left out a very important detail: Copy core.json from persevere\WEB-
INF\config to jetty\contexts\{instance}\WEB-INF\config. The above
approach will not work without this!

I noticed that the "Object" source in core.json defines a location
property as "$DATA-DIR$/jsdb"...this is probably the key to specifying
a native datastore location per context and would probably be a better
approach than specifying the tempDirectory in the deployment .xml file
as I did above. I have not tested this.

Paul Spaulding

unread,
Nov 6, 2009, 11:50:09 AM11/6/09
to Persevere
I've found that running Jetty using the Oracle Jrockit JVM instead of
the Sun JVM does work better with regard to the PermGen space memory
errors and have been able to run up to 100 Persevere instances within
a single Jetty container. Unfortunately, the instance startup times
bog down severely after about 30 or 40 instances. I have not looked
at performance once the instances have been created.
Reply all
Reply to author
Forward
0 new messages