1 2 3 Previous Next 30 Replies Latest reply on Feb 2, 2007 3:01 PM by brian.stansberry Go to original post
      • 15. Re: Issues with passivation of nested SFSBs
        brian.stansberry

         

        "bill.burke@jboss.com" wrote:
        Brian....so, if we attach the lifecycle of the child nested bean to that of its parent, will there be no problems?


        I believe the initial problem that led to this thread (orphaned ProxiedStatefulBeanContext left in cache) was a bug in StatefulTreeCache that can be easily fixed (StatefulTreeCache.remove() wasn't calling Pool.remove() when it should, preventing cleanup of the nested beans.)

        The issue of when to replicate still remains. If we follow Carlo's example where a ref to the nested bean is handed to another in-VM client, if that client causes replication, only the proxy is replicated. If instead, the cache finds the ultimate parent bean and replicates that, then there is the potential problem of the parent getting replicated multiple times as it invokes methods on its children.

        OK - I see the solution to that. Put a ThreadLocalStack in StatefulReplicationInterceptor; push and pop as the invocation proceeds; on the return side only replicate when the stack is empty. Similar to what the web session repl code does with cross-context requests.

        • 16. Re: Issues with passivation of nested SFSBs
          wolfc

          I say we should not attach lifecycle from one SFSB to another. You don't know where a reference ends up and I can always come up with a scenario in which it breaks (we haven't even covered handles yet).

          The bean developer should be responsible for both parent and child lifecycle. We can always have orphaned SFSB, because that's the nature of the beast.

          • 17. Re: Issues with passivation of nested SFSBs
            brian.stansberry

            Can we solve the XPC issue with something along these lines?

            1) XPC is stored in the parent bean context.
            2) Child beans have an independent lifecycle (i.e. bean instance is cached with the context, not in an internal data structure of the parent. Child bean context stores data about location of parent, and vice versa.
            3) When nested bean is invoked, interceptor accesses the parent bean, gets the XPC and injects it into the nested bean instance. On the way out clear the XPC ref from the nested bean. I.e. don't try to maintain a shared ref to XPC across serialization; instead cache it in the parent and inject it into the child as needed.
            4) As part of remove process, check if the bean is a parent. If so, check if any children are still alive. If yes, don't remove context from the cache; instead set a removed flag in the context. If removed flag is set an interceptor will not allow any call to the context (throw NoSuchEjbException). But the context is still cached, so child beans can find the XPC.
            5) As part of remove process, check if bean is a child. If so, have parent re-check if all its children are still alive. If not, parent context can be removed.

            Along with this, in general it would be good to have a background thread that runs to check for and remove orphaned beans. But that's true regardless of the value of the above.

            • 18. Re: Issues with passivation of nested SFSBs
              wolfc

              I finally found the relevant bit in the specs: EJB 3 Persistence 5.6.2.1.

              • 19. Re: Issues with passivation of nested SFSBs
                bill.burke

                I guess that sounds good Brian. That's gonna be one piece of ugly non-modular code.

                • 20. Re: Issues with passivation of nested SFSBs
                  brian.stansberry

                  I didn't see anything in section 5.6.2 about the sharing not applying to beans with an @Remote. But since it's possible such a nested bean isn't even in the same VM, that's probably too much to try to deal with.

                  • 21. Re: Issues with passivation of nested SFSBs
                    bill.burke

                    I'm pretty sure that somehwere it says that XPC PC is not propagated across remote boundaries. That's another think I know we discussed in great detail on the expert group.

                    • 22. Re: Issues with passivation of nested SFSBs
                      wolfc

                      I would rather have the SFSB register themselves as users in the XPC. The XPC then maintains this list. On @Remove SFSB deregisters and if XPC is empty close itself.

                      For injection: any SFSB with an XPC with creates a SFSB propagates the XPC with the exception of @Remote. Hmm... still don't like it, but there is no other way.

                      The final part: orphaned SFSBs must be removed by a reaper as per spec after a timeout.

                      • 23. Re: Issues with passivation of nested SFSBs
                        brian.stansberry

                         

                        "wolfc" wrote:
                        I would rather have the SFSB register themselves as users in the XPC. The XPC then maintains this list. On @Remove SFSB deregisters and if XPC is empty close itself.


                        OK. But only parent context holds a ref to the XPC, yes? Otherwise you have the problem of multiple contexts independently serializing/deserializing the XPC, after which you no longer have a shared reference.

                        The XPC would need to know which context has the ref to it, so as part of the close process it can inform that context it no longer needs to be cached. It's the caching of the parent context that keeps the XPC from being gc'd. Unless we come up with a separate cache for these.

                        Shit, if a call to a child bean triggers replication, the parent bean must be replicated as well, otherwise the XPC isn't. Perhaps separately caching XPCs makes sense. :(

                        For injection: any SFSB with an XPC with creates a SFSB propagates the XPC with the exception of @Remote. Hmm... still don't like it, but there is no other way.


                        Not clear exactly what you mean here. :)

                        • 24. Re: Issues with passivation of nested SFSBs
                          bill.burke

                          no it doesn't...

                          Again, the big problem is managed entities. This is why all the SFSBs and XPC's need to be serialized together.

                          • 25. Re: Issues with passivation of nested SFSBs
                            bill.burke

                            Furthermore, there can be multiple XPCs...I still think the parent owning all the instances makes the most sense and for the child to have the same lifecycle as the parent. I'm not sure there is anything in the spec that forbids us from doing this.

                            What we could do is, when the parent gets removed, pick a new "master" SFSB to hold the references to the other SFSB instances as well as the XPCs.

                            • 26. Re: Issues with passivation of nested SFSBs
                              wolfc

                              Okay, but introduce a new object XPCHolder or something to hold the administration of XPC users. Then there is no "master", parent or child. Just an XPC holder and users. That's more easily to understand (at least to my brain :-) ).

                              • 27. Re: Issues with passivation of nested SFSBs
                                brian.stansberry

                                StatefulBeanContext already has a "removed" field, and already has a ref to all its (non @Remote) children. Those children already have a ref to the parent. So it should be quite easy to just change the caching code to not de-cache the parent while any children are alive. Then StatefulInstanceInterceptor just checks the removed field to ensure the parent is no longer accessible (should probably do that anyway).

                                That seems easier than moving data around from one bean to another. It's a quick and dirty improvement, if such a thing is wanted for RC10/4.2.

                                But, a general problem with making XPCs and managed entities part of the replicated state of any SFSB is the possibility of something like this:

                                1) Parent A has nested children B and C.
                                2) A exposes getters for B and C, and 3 separate clients have refs to A, B and C.
                                3) All 3 clients make concurrent requests that result in a need to replicate.

                                This can result in one thread attempting to serialize the bean instances, calls to @PrePassivate, etc. while another thread is actively operating on the bean. Yuck!

                                Encapsulating the shared state in something like an XPCHolder might help with that, if the XPCHolder could be cached and replicated independently of the bean instances. This assumes that one thread serializing the XPC and managed entities while another thread is using them is not a problem.

                                A separate caching infrastructure for XPCHolder would take quite a bit of time, as I'm sure there are hidden gotchas.

                                Another potential workaround to the concurrent replication problem is to modify StatefulInstanceInterceptor to require a lock on the parent bean before an invocation can proceed. Serialize the requests to A, B, C.

                                • 28. Re: Issues with passivation of nested SFSBs
                                  bill.burke

                                  For a nested structure, again, I think we need the concept of ownership and relatively the same code that already exists with the proxy context.

                                  At first, the parent SFSB owns all the children. If a child is "touched" by an invocation, it must ping the parent to replicate the whole tree: parent and all its children.

                                  If the parent is removed, a child is picked as the new "parent".

                                  As for your concurrency problem. I don't think we should code for this and document that that scenario is not supported. SFSBs are supposed to be used by one client, not multiple clients concurrently. This will make things easier IMO.

                                  • 29. Re: Issues with passivation of nested SFSBs
                                    brian.stansberry

                                     

                                    "bill.burke@jboss.com" wrote:

                                    At first, the parent SFSB owns all the children. If a child is "touched" by an invocation, it must ping the parent to replicate the whole tree: parent and all its children.


                                    Easily encapsulated in the StatefulReplicationInterceptor.

                                    If the parent is removed, a child is picked as the new "parent".


                                    This will be lot of work, for I'm not sure what gain vs. leaving the old parent context in the cache, but marked "removed" and with refs to any unneeded state nulled out. You've got to:

                                    1) Pick a child (ok, trivial)
                                    2) Move the data to the child (not sure if there are any integration issues)
                                    3) Add all of the parent's children to the new "semi-parent".
                                    4) Notify all the children of the new semi-parent
                                    5) Do a lookup of the ProxiedStatefulBeanContext of each of the children (no direct ref to it) and modify it to point to the new parent.
                                    6) Replace the cached context for the new "semi-parent" so it's no longer a ProxiedStatefulBeanContext, but rather a regular one (otherwise any calls to the new parent will fail).
                                    7) Replicate every affected context so the rest of the cluster knows what you did. Probably should do this in a tx.

                                    As for your concurrency problem. I don't think we should code for this and document that that scenario is not supported. SFSBs are supposed to be used by one client, not multiple clients concurrently. This will make things easier IMO.


                                    :-)