1 2 Previous Next 17 Replies Latest reply on Dec 14, 2009 6:50 PM by alesj

    Cleanup path for Structure Deployers

    jason.greene

      The thread seems to start here:
      http://lists.jboss.org/pipermail/jboss-cvs-commits/2009-October/109290.html

      and here:
      http://lists.jboss.org/pipermail/jboss-cvs-commits/2009-October/109293.html

      and also here:
      http://lists.jboss.org/pipermail/jboss-development/2009-October/014994.html

      The fundamental problem is that a structure deployer (WAR/JAR/EAR etc) has no cleanup phase, like other deployers. The only way to achieve this with the current design, is to reuse the cleanup call on DeploymentContext. In the above scenario, a structure deployer needs to get a set of mount points it created added to a DeploymentContext for cleanup. These come from the current VFS api as Closables. However, the structure deployer executes before the DeploymentContext exists, so it must be copied to some intermediary data structure. The patch that was recently applied used ContextInfo on StructureMetaData to pass a Runnable which closed the closables.

      Ales mentions in the above threads that ContextInfo should hold no impl details. So the question becomes where else to pass this?

      I assume if ContentInfo can't contain a List<Closable> (or Runnable), then StructureMetaData can't either?

      That means a structure deployer, without changes to the SPI can only use StructureContext as the other option, which does not survive long enough to make it into the DeploymentContext. The only way to change that would be to change the AbstractStructuralDeployers, and AbstractStructureBuilder SPIs to support passing an additional object.

        • 1. Re: Cleanup path for Structure Deployers
          jason.greene

          It seems that mounting has to happen after a structure deployer runs, since a user provided structure skips structure phase (of course!). So nothing from the above approach is valid. This needs to be redone.

          • 2. Re: Cleanup path for Structure Deployers
            dmlloyd

            Okay, after much discussion and gnashing of teeth here's the best approach we can figure out so far.

            In order to accommodate the variety of conditions under which an archive may be mounted, the easiest solution would be to keep a registry of deployments, root or nested, which is the "resource owner" for the various submounts. This way, on undeploy the only information we need to clean everything up is the VirtualFile of the deployment root, which we should always have available if I understand this correctly.

            This registry is lazily populated as deployers need access to archives; this is not unlike the automagic mount facility in VFS2. The difference is that all mounts have a deterministic lifecycle that is tied to deployments in various ways.

            In order to manage references to mounted archives outside of the deployment, this registry would provide a simple refcount-backed mount system. Every deployment using a specific external classpath root would have a reference handle which is associated with the deployment registry mentioned above; when the deployment is removed, the handles will be cleaned up automatically, and any resources whose refcount drops to zero will be unmounted.

            In addition, all mounts inside a deployment are subject to removal when the deployment is removed. In particular, if a refcounted resource later comes to be a part of another deployment for whatever reason, that deployment then assumes automatic ownership of that mount, so if the deployment is removed, the mount is nuked and any outside deployments referring to that resource are SOL.

            This solution should allow deployments to access archive data as needed, including external shared archives, while still making sure that all resources are unmounted once nothing refers to them anymore.

            Hoping this makes sense.

            • 3. Re: Cleanup path for Structure Deployers
              alesj

               

              "david.lloyd@jboss.com" wrote:

              Hoping this makes sense.

              I would actually have to see this "in action" to really understand it.
              Or I'll do a few re-reads in the evening. :-)

              Thinking about how to hack this non-automount approach. ;-)
              e.g.
              Lets say we just have component deployers (probably not gonna happen, but still ...),
              no parsing stuff, nothing that would need to touch resources, hence no VFS usage.
              But we have a bunch of pre-attached component metadatas,
              meaning those component deployers would pick this up and deploy it.
              And one of our services at runtime calls URL.inputStream on a location that is sure it exists, but as an inner resource (double nested jar entry).
              What would happen in this case or how you make sure this is mounted and unmounted?


              • 4. Re: Cleanup path for Structure Deployers
                dmlloyd

                 

                "alesj" wrote:

                Thinking about how to hack this non-automount approach. ;-)
                e.g.
                Lets say we just have component deployers (probably not gonna happen, but still ...),
                no parsing stuff, nothing that would need to touch resources, hence no VFS usage.
                But we have a bunch of pre-attached component metadatas,
                meaning those component deployers would pick this up and deploy it.
                And one of our services at runtime calls URL.inputStream on a location that is sure it exists, but as an inner resource (double nested jar entry).
                What would happen in this case or how you make sure this is mounted and unmounted?


                In this case the service is just not going to work unless the archive is mounted through one of the mechanisms designed to do so:

                - A deployer mounting a deployment
                - A deployer mounting a classpath element
                - User code using the deployer API to mount the resource

                There is one option for auto-loading external JARs like you mention - do some type of archive detection (maybe read the first four bytes to identify whether it's an archive), automount if necessary, and assign the handle to whatever deployment owns the caller's classloader. Of course if no deployment owns the classloader, it won't work. Anyway this would probably be something we could add later?


                • 5. Re: Cleanup path for Structure Deployers
                  johnbailey

                  I would like to open this conversation up again. I will be working on the VFS3 integration full time in the near term. I would like to make sure we are still going to move forward on the registry approach discussed above?

                  Has anyone had any more insight in the past month?

                  • 6. Re: Cleanup path for Structure Deployers
                    johnbailey

                    I am going to need a bit more information on this. Below are a few questions I have.

                    1. Will a StructureDeployer still be responsible for invoking the mount operation and registering it with the registry?

                    2. Does it make sense to duplicate a registry of mounts, since there are already stored in the VFS in the mounts map? Could the VFS be beefed up to support this use as well?

                    3. How will references from outside the deployment get a reference to the mount? What keeps the outside reference from just using the VirtualFile and ignoring the registry?

                    I am assuming the cleanup from a deployment will be easy enough as this will only require a VirtualFile.

                    I may have missed some conversations on this. Just want to make sure I have all the info.

                    • 7. Re: Cleanup path for Structure Deployers
                      alesj

                       

                      "johnbailey" wrote:

                      1. Will a StructureDeployer still be responsible for invoking the mount operation and registering it with the registry?

                      You shouldn't rely on any StructureDeployer to do this, as there might be no StructureDeployer.
                      e.g. pre-configured (VFS)Deployment with StructureMetaData.

                      That's why I proposed some auto-mount, and have proper cleanup in DeploymentContext::cleanup -- similar as we have now.
                      (just that there would be less magic all together ...)

                      • 8. Re: Cleanup path for Structure Deployers
                        dimitris
                        Some concerns by Ales:

                        "(1) VFSHandleRegistry is complete VFS impl detail, and as such, doesn't
                        belong to Deployers
                        (2) like I already mentioned, StructureDeployer(s) might not even be invoked
                        (2a) even if SD(a) are invoked, you don't know which one will be invoked 1st
                        (2b) if none SD gets invoked, who will mount this? (auto-mount?)
                        (3) addition to (2a), this means each SD will have to include this mount
                        code, which is very intrusive
                        (4) addition to (2b), the next step are real deployers, where this code
                        also doesn't belong -- I only wanna think about my logic in my deployer,
                        nothing else

                        VFS3 looks a lot like what we did for previous Deployers (pre AS5),
                        but there one deployer controlled it all, making such mount/unmount easy
                        to add/handle.
                        With "aspectized" deployers, and clean separation of user/dev/server
                        view and structure/real handling and predetermined/vfs, this becomes
                        harder to impl in such a straight way.

                        Apart from being very much intrusive and not actually finding proper
                        place to mount, I only see auto-mounting as a solution.
                        While DeploymentContext::cleanup is already a proper place to unmount."
                        • 9. Re: Cleanup path for Structure Deployers
                          dimitris
                          David's reply:

                          >
                          (1) VFSHandleRegistry is complete VFS impl detail, and as such, doesn't
                          > belong to Deployers

                          It's actually a VFS deployer implementation detail.  VFS doesn't care about
                          it at all.

                          > (2) like I already mentioned, StructureDeployer(s) might not even be invoked

                          That's fine.  Whoever creates the SMD will have the responsibility to
                          register all deployment and classpath roots with the registry.

                          > (3) addition to (2a), this means each SD will have to include this mount
                          > code, which is very intrusive

                          It already includes code to add to the classpath, how is this any different?

                          > (4) addition to (2b), the next step are real deployers, where this code
                          > also doesn't belong -- I only wanna think about my logic in my deployer,
                          > nothing else

                          We're not touching real deployers.

                          > VFS3 looks a lot like what we did for previous Deployers (pre AS5),
                          > but there one deployer controlled it all, making such mount/unmount easy
                          > to add/handle.
                          > With "aspectized" deployers, and clean separation of user/dev/server
                          > view and structure/real handling and predetermined/vfs, this becomes
                          > harder to impl in such a straight way.

                          Indicates a design error to me.

                          • 10. Re: Cleanup path for Structure Deployers
                            alesj

                            > (1) VFSHandleRegistry is complete VFS impl detail, and as such, doesn't
                            > belong to Deployers

                            It's actually a VFS deployer implementation detail.  VFS doesn't care about
                            it at all.

                            Well, it should.

                            What happens when I want to use VFS3 in CL, Weld-int, Seam-int, Snowdrop, ... w/o the help of Deployers?

                            By your definition each of those will need its own VFS handle registry?

                             

                            > (2) like I already mentioned, StructureDeployer(s) might not even be invoked

                            That's fine.  Whoever creates the SMD will have the responsibility to
                            register all deployment and classpath roots with the registry.

                            Creating metadata vs. programmatically mount deployments and register roots seems an awful overhead to me.

                            The user shouldn't need to know the API to do that, where creating metadata should be trivial with some builders help.

                            And it might not even have the handles to do it; e.g. "remote" deployment with pre-attached SMD.

                             

                            > (3) addition to (2a), this means each SD will have to include this mount
                            > code, which is very intrusive

                            It already includes code to add to the classpath, how is this any different?


                            One is using the VFS, the other one is making the VFS work. Totally different to me.

                             

                            > VFS3 looks a lot like what we did for previous Deployers (pre AS5),
                            > but there one deployer controlled it all, making such mount/unmount easy
                            > to add/handle.
                            > With "aspectized" deployers, and clean separation of user/dev/server
                            > view and structure/real handling and predetermined/vfs, this becomes
                            > harder to impl in such a straight way.

                            Indicates a design error to me.

                            Well, you know who to complain to then.

                             

                            I think instead of going straight into the code and hack some half backed solutions,

                            like in 1st Closeable's and 2nd VFS handle registry + modifying structure deployer(s),

                            we (probably mostly John as he's been assigned the task) should do an overview and re-think where this would best fit in.

                            Expose few problems and few solutions and then take it fwd.

                             

                            As you could just recently read on the-core, folks like the lightweight dynamic and plugable nature of Deployers.

                            And this is something that shouldn't be sacrificed for the sake of quick&dirty hack/solution.

                             

                            Or what are the facts against auto-mount?

                            • 11. Re: Cleanup path for Structure Deployers
                              dmlloyd

                              I think instead of going straight into the code and hack some half backed solutions,

                              like in 1st Closeable's and 2nd VFS handle registry + modifying structure deployer(s),

                              we (probably mostly John as he's been assigned the task) should do an overview and re-think where this would best fit in.

                              Expose few problems and few solutions and then take it fwd.

                               

                              As you could just recently read on the-core, folks like the lightweight dynamic and plugable nature of Deployers.

                              And this is something that shouldn't be sacrificed for the sake of quick&dirty hack/solution.

                               

                              Or what are the facts against auto-mount?

                              Well, ignoring the snarky remarks...

                               

                              Auto-mount is what we're doing.  Or at least, as close to it as possible while still maintaining information about what deployment owns a mount.  Because that's what it boils down to - ownership.  If there's a way we can do magical automount, while still maintaining strict ownership information, I'm all ears.  Maybe you can come up with some kind of thread-context-deployment-root or something.  When it comes right down to it, that's all we would need to do some kind of automount.  We could even make a class e.g. "AutoMounter" or something and put the whole registry in there, and expose a static method "AutoMounter.automount(VirtualFile)" which you call before accessing a new deployment root or classpath entry (it would throw an exception if there is no "current" deployment root).  The "current" deployment then becomes the owner of the reference, and in DeploymentContext.cleanup() we'd just call some AutoMounter.cleanup() with the VirtualFile of the deployment root being cleaned up, and everything would be cleaned up magically.

                               

                              I have no philisophical opposition to auto-mounting; it just can't be done as things stand right now.  At this stage I just want to get this change integrated.  If you want to help, great. :-)

                              • 12. Re: Cleanup path for Structure Deployers
                                jason.greene

                                The SMD should be able to come from anywhere as the design is supposed to have the structurAL deployer (not structurRE)  attempt a remount using the SMD info and deployment root as the owner (Although this has not been completed yet).

                                 

                                In regards to the question of what do non-deployers do, the structure scanning/processing phase should ensure that all relevant mounts have been created meaning they work with the vfs handles much as they did before.  If they are to work out of the deployment phase (e.g. standalone code), then they will need some setup and cleanup code to create the mounts.

                                 

                                Also, the deployers framework seems to be the natrual home for the registry, as its whole reason for existence is to serve the complex deployment lifecycle in AS. Although portions of it could be moved to some other module (perhaps VFS tiself), if there was some desire to resuse it.

                                 

                                Finally, the overhead for deterministic resource control to the user is minimal to non-existent. In most cases non-existent since 99.999999% of our users will not be writing structure deployers (there are < 10 structure deployers in existence). In the rare cases where a user is writing a structure deployer, we are talking about a few extra lines of code. That's a small price to pay for reliable resource cleanup.

                                • 13. Re: Cleanup path for Structure Deployers
                                  dmlloyd

                                  david.lloyd@jboss.com wrote:

                                   

                                  [...] Maybe you can come up with some kind of thread-context-deployment-root or something.  [...]

                                  In fact, maybe we could even just make the API deal completely in virtual files, and operate completely statically:

                                   

                                  class Automounter {
                                     public static void automount(VirtualFile owner, VirtualFile target) {...}
                                  
                                     public static void cleanup(VirtualFile owner) {...}}
                                  

                                   

                                  You'd call automount before doing anything with a virtual file, and it would ensure that the owner VF has a reference into whatever the target is, no matter how deeply it might be nested in archives or whatever....

                                  • 14. Re: Cleanup path for Structure Deployers
                                    alesj

                                    In regards to the question of what do non-deployers do, the structure scanning/processing phase should ensure that all relevant mounts have been created meaning they work with the vfs handles much as they did before.  If they are to work out of the deployment phase (e.g. standalone code), then they will need some setup and cleanup code to create the mounts.

                                     


                                    OK, I came to peace with this attempt. :-)

                                    Let's try to impl this in StructureDeployer(s), but as some helper methods in AbstractStructureDeployer.

                                    And we'll see how far this takes us.

                                     

                                    Also, the deployers framework seems to be the natrual home for the registry, as its whole reason for existence is to serve the complex deployment lifecycle in AS. Although portions of it could be moved to some other module (perhaps VFS tiself), if there was some desire to resuse it.

                                    I still don't agree with this, but I'll let you have the benefit of the doubt.

                                    We still have long read ahead -- making all the tests work in various sub-projects -- which will show who's right.

                                    1 2 Previous Next