I agree with all this, with the caveat that if replacing BeanContext stuff proves too hard, we offer OOTB an option that makes more of a time tradeoff than a space tradeoff. My only real experience with portals came from work with the BEA one, but I do remember that session size was a big issue.

Rich

Eddie O'Neil wrote:
  Apologies for getting back to this late, I was travelling yesterday...

  Few comments on the thread that I'll just summarize here:

- Rich, the difference between my and Daryl's initial proposals was to
avoid adding an API call to the JPF base class to ensure that a CCC
was created.  The goal was to keep the Controls and NetUI APIs loosely
coupled and keep from bleeding them together.  Looks like Daryl
proposed an alternate solution (putting the CCC on a ThreadLocal)
which would take care of this concern.  I was also trying to make the
point that programmatic instantiation of controls should be an
exercise left to the user (it's not hard) given the expense of
creating the container.

- The size of the BeanContext APIs from the JDK is pretty substantial.
 And, that's definitely going to be a hit on performance that we'll
need to look at going forward.  My suggestion would be to look at
writing a lightweight, perhaps unsynchronized control container that
would support interception, eventing, and services like we do today
but without the weight of the Glasgow stuff from the JDK.  That's a
pretty big hierarchy of data structures to maintain...  This could be
something we call Controls 2.0 -- take the programming model and other
features forward, integrate with Spring for wire-up, and go really
lightweight on the rest of the stuff.

  But, for our current ship, I agree that fixing the problem so that
the Controls programming model works correctly in NetUI is the first
priority.  We can work to address the session size issue after 1.0.1.

  My $0.02...

Eddie



On 1/19/06, Daryl Olander <[EMAIL PROTECTED]> wrote:
The CCC is pretty large, no doubt, here are some details of the fields in
the hierarchy.  Obviously, the top two objects are in controls.  The rest if
the Java Beans implementation.  I think this also reflects the overall
complexity and weight of the Java Beans Containment spec.

Link to the JavaBean Containment spec.
http://java.sun.com/products/javabeans/glasgow/beancontext.pdf


CCC:
  boolean
  Stack

ControlBeanContext:
  ControlBean [This is pretty big]
  boolean
  Map(2)
  Vector
  String

BeanContextServiceSupport
  HashMap
  int
  ArrayList
  BCSSProxyServiceProvider [HashMap, int, BCSSProxyServiceProvider,
ArrayList]

BeanContextSupport
  HashMap
  ArrayList
  Locale
  boolean (3)
  ChangeListener (2)

BeanContextChildSupport
  BeanContextChild
  PropertyChangeSupport
  VetoableChangeSupport
  BeanContext
  boolean


On 1/19/06, Rich Feit <[EMAIL PROTECTED]> wrote:

Daryl Olander wrote:
In thinking about Eddie and Rich's objections, I've decided to provide
the
Control Container as an abstraction.  It should actually be an pluggable
interceptor that sits inside the synchronized blocks.  I will abstract
the
Container into a bean that could be configured (eventually) through
Spring
and an interface defining the containers contract.  I will place the
object
on Thread Local so that it can be accessed within a page flow for
programatic use (Eddie's concern).  It will also be possible in the
future
for a "portal" to provide an implementation that can optimize for their
use
cases (space/time tradeoff) and/or implement a different symantic
(Rich's
concern).

Hmm... do we have any idea what kind of implementation in a portal would
make the space issue OK, while still preserving the right behavior?
BTW, I haven't verified this, but I believe in thinking about it, we
never
cleared controls out of the CCC once they were added so we were leaking
all
controls in page flows instances beyond the life of the instance.  In
addition, I would guess this also made the unique id's unstable within
instance of the same page flow.  I'm going to verify this, but I suspect
this is a side affect of the current implementation.

Aren't we doing this currently in JavaControlUtils.uninitJavaControls
(->destroyControl)?
On 1/19/06, Daryl Olander <[EMAIL PROTECTED]> wrote:

Is there an easy way to tell how big an object is?  (The space is
mostly
in the Bean base classes that are part of Java.Beans)

On 1/19/06, Rich Feit < [EMAIL PROTECTED]> wrote:

Ah right, it's not just for requests that go to shared flows.  Well, I
think this will all work.  My biggest concern is the space
requirements
of the CCC, multiplied if this happens in a portal.  It's just
something
we should look at.  Do we know how big the CCC will be?

Daryl Olander wrote:

No, because you have to get access to the "shared flow" lock before

you can

enter user code in onCreate, action invocation and JSP

rendering.  Thus the

statement that we have serialization points for multiple threads

within a

session.

On 1/19/06, Rich Feit <[EMAIL PROTECTED]> wrote:


OK... one other thing: is there still a hole here for direct access

to

the shared flow through a reference in the page flow?

Daryl Olander wrote:


On 1/19/06, Rich Feit <[EMAIL PROTECTED]> wrote:



I can't tell the difference between this and Daryl's option #2, so

I

guess I agree with both of you.  :)

Daryl, I have just a few questions:
    1) The Lock object is session-scoped, right?



Right...

    2) Are you saying that you'd call the CCC's begin/end-context



methods around *every* point that runs user code?  So within a

given

request, you'd potentially do this around onCreate(), the action
invocation, and JSP rendering?



Exactly...These are the three points where we do this.  For the

average

request, it would be just the action invocation and JSP rendering.

Eddie O'Neil wrote:



  Hm...this is a tricky issue.  I'd actually go a different route

and

do two things:

1) only create the CCC for each page flow in the presence of

@Control

annotations
2) explain how to write code to create a CCC and drive it through

its

lifecycle



This is how the JUnit test container works for Controls -- you
can
use

the ControlsTestCase base class or write code that calls
utilities
that provide the CCC and drive it through its lifecycle.

  Seems like this provides the best of both worlds -- uses

metadata to

decide when controls are used but gives application developers a

way

to use controls programmatically without having a
Controls-related
API

exposed on the Page Flow base class.

  Yes, there's a compatibility issue *if* you used JPF from
1.0and
declared controls programmatically, but that's probably not very
common.

Eddie




On 1/19/06, Daryl Olander <[EMAIL PROTECTED]> wrote:




So it turns out, there is indeed a test that creates a control
programmatically in a page flow.  This seems to leave us with
two
alternatives
1) we always create the CCC for every page flow
2) we add an ensureControlContainerContextExists() API (to the

base

PageFlowController) to make sure that it is created and

initialized.

I lean toward 2 because I think this use case is rare.  It is a



backward



compatibility issue with our 1.0 release.

Thoughts?

On 1/18/06, Daryl Olander < [EMAIL PROTECTED]> wrote:




This mail summarizes the proposed design for the Control

container

implementation inside of the page flow runtime.  It is a
summary
of

the



previous threads on this subject.  I'm currently in the process

of

implementing this solution and believe it solves the sets of

issues

brought



up in those emails.  I would really like review of this
solution
and

comments/questions so we can be sure this works.

There are two basic requirements of the Control container
1) All controls have only a single thread in them at a time

(Single

Threaded)
2) The resources a control may acquire are only used for a

single

request.  It is ok if the resources are acquired more than once

for

a


single



request.

In today's implementation, both of these requirements are

violated

by


standard page flows and shared flows (and global app).  These

issues

are



summarized in the previous threads on this subject.

The proposed solution is this,

For a standard page flow (normal page flow, singleton page flow

and

nested



page flow), they have a ControlContainerContext (CCC) for the


controls


that



they contain.  The CCC is only allocated if the page flow

contains a

control.  We will have to probably add an API someplace to

create

this


if a



user wants to create a control programmatically.

For all Shared flows and global app, they will share a single

CCC.

During a request, there are three possible synchronization

points

where



user code can run and call methods on controls
1) during onCreate when a page flow is created
2) during the beforeAction/Action/afterAction cycle
3) during JSP rendering

During any of these, code may access a shared flow and interact

with

controls. For most page flow requests only 2 and 3 are run.

For a the standard page flows, these synchronization points

create a

single threaded model.  For the standard page flow CCC, we will

run

the



beginContext, endContext events which activate the resource



lifecycle.  This



is sufficient to guarantee 1 and 2.

For shared flows, we still have issues if multiple threads are


running


through the session.  To solve this we will do this,
1)  We will create a single Lock object that must be obtained
in
the

synchronization points before we can proceed.
2) Once the lock is obtained, we will run beginContext on the

shared

flows



CCC.
3) We will run the normal user code
4) We will then run the endContext on the shared flows CCC
5) We will release the lock

Rich, please verify this will work...

The result of this, is that we will serialize threads within a


session


through these synchronization points.  The result is that
shared
flows


will



become single threaded (requirement 1 above) and because we run

the

beginContext/endContext that satisfies 2 above.

There is a bit more overhead to this solution because there
will

typically



be two CCC objects active at one time.  Deep nesting and

singletons

will add



more.  The CCC is only created for page flows that have


controls.  The


benefits is that the CCC objects match the lifetime of the

controls

that



they contain.

Please review this and send comments.

Thanks

Daryl









Reply via email to