Discussions

J2EE patterns: The Mother/Nanny Pattern

  1. The Mother/Nanny Pattern (19 messages)

    Here, assuming ExpensiveResource is an object representing some expensive resource such as a databse connection.

    public class MyClass {
      private ExpensiveResource resource;
      private boolean closed;

      public MyClass() {
        closed = false;
      }

      protected void finalize() throws Throwable {
        super.finalize();
        if (!closed) {
          Logger.log(Severity.WARNING, "Resources were not released. Call .dispose() when finished with MyClass object.");
        }
      }

      public void dispose() {
        resource.close();
        closed = true;
      }

      public ExpensiveResource getResource() {
        if (closed) {
          Logger.log(Severity.WARNING, "Cannot access resource. Encapsulating class has been disposed.");
          return null;
        }
        return resource;
      }
    }

    So basically, the finalize() method checks to see if the object was disposed. If it wasn't, it nags the user of the library until they start using .dispose() calls.

    Threaded Messages (19)

  2. The Mother/Nanny Pattern[ Go to top ]

    This is more of an idiom than a design pattern. I have seen it documented in several places, but the one that pops to mind now is Bjarne Stroustrup's Auto_ptr class (see 14.4.2 in "The C++ Programming Language"). This class goes as far as to actually clean up the resource, not just print a message. Of course in C++ this idiom is more appropriate than in Java because destrcutors have clearly defined execution times and semantics (e.g, same thread executes destructor). But it can still work in Java. I would give up closing up resources myself (garbage collector may react slowly), but it is a good safeguard. Also, when closing resources yourself be sure to do it in a "finally" block.

    Gal
  3. The Mother/Nanny Pattern[ Go to top ]

    Weblogic JDBC Connection pool implementation uses the same 'idiom' and goes further and cleans up the resources if no explicit cleanup action was taken. Each JDBC connection object handed out to the client is a wrapper on top of the actual connection in the pool and has a flag to keep track of whether the client closed the connection or not. In the finalize method the state is detected, and if not yet closed, closed and the actual connection is returned to the pool. Of course, all this depends on when the garbage collector runs. The non-deterministic nature of GC makes it risky to forsake programmer responsibility altogether and rely entirely on resouce cleanup during finalization.

    Satadru
  4. In my opinion, it is always a good practice to code some kind of logic to garbage collect your resources (e.g. C++ auto_ptr style) just to safeguard mistakes by a junior developers. An error log message is good but automated cleanup is even better.
    We had developed a set of classes that did just that for database connection pools. It was another layer on top what WebLogic provided (see Satadru's comments). Reason for that is because you never know if the application is ported to a different app server.
  5. There are two basic courses you can chose.

    A) Protect the junior developers from themselves and thereby protect the integrity of the system(s) that they touch. Downside, does not promote the evolution of these junior developers into senior developers.

    B) Philosophically slap the junior developers for doing something wrong. Downside, does not prevent errors.

    Which is the proper course? That depends on your instance situation, but I would be inclined to go with B from a standpoint of improving future development.

    Regards,
  6. Why not protect them from themselves and also log the error so you can philosophically slap them later?

    Gal
  7. just a fyi, (I'm not trolling here) but this is known as using block in C#. When the runtime exits the block it calls the Dispose() method of the resource it was opened. See more information here
  8. The Mother/Nanny Pattern[ Go to top ]

    I would like to raise the worst case scenario. Suppose any application is holding some expensive external resources like data base connections and suddenly application crashes due to some run time error or client disgracefully closes application with Ctrl+C etc. In this case logging in finalize() or cleaning up resources in finalize()will not help.
    Deepak Kapoor
  9. The Mother/Nanny Pattern[ Go to top ]

    On the other hand in the case of db connections, the pool will time them out and quiesce them on its own without your help. If the application has died for some reason, the user bailing ungracefully out of the application, you don't really have much other choice do you???
  10. No on Jrun[ Go to top ]

    That'd be great if it actually worked on a commercial appserver like Jrun :-(
  11. Hi Jason,
    I was little annoyed by your earlier post but lets remain focused.
    The problem of application terminating disgracefully and resources remained booked can be solved to some extent if the resposibility of creating/managing resources like db connections is handeled by seprate application or service.
    DBConnction service can be created and run in seprate jvm and if some application needs db connections it will invoke the service application to get connections i.e. resources.
    Now if client kills application by Ctrl+C, the scheduled observer embedded in service application will notify the service provider of user-exit and the resource will be reclaimed and recycled for future reuse.
    If the service provider is exited with Ctrl+C, the problem remains but still the damage caused by indivisual developers doing Ctrl+C during development or users doing Ctrl+C can be limiting.
    By looking at the types of patterns proposed, I can propose a pattern for this ;)
    DK
  12. Deepak,

    How do you propose the DB connection service would pass the connection to a seperate VM? I don't know of any way to do it using standards (JDBC doesn't support serialization of connections). Even using non-standard code is sounds nearly impossible (many if not all database connections are based on some open socket; If the service and the app are runnning on the same box it may be possible to tranfer that socket from one process to another, but not with Java-level networking API, AFAIK).

    Gal
  13. When I propose looking up service, it does not mean that always resources will be tranferred to calling client, including dbconnections. But what I said was CREATION/MANAGING of resorces including db connections and other sockets/resoucres etc. If some client applications needs to execute (say) some select query on data base, then that client application will serilize its string query to the service provider and service provider, after executing the query can return results in form of java objcets or primitives. Service provider has to iterate the result set and has to cast the resutls to appropriate type. With this client is totaly decoupled of data-base resoucres and if it doed Ctrl+C it will not hang any resources.
    Take example of creating e-mail service. We can create our app email-bean with all informatiom and will serilize this bean to e-mail service provider to create and email. With this client application is totaly decoupled of resources being used for sending the email etc.
    Helper service applications can be created and can be run in seprate jvm's and main application has to lookup these services for any related task.
    DK
  14. Honestly, I don't see the point in what you are describing as far as DB connections are concerned. DB connections will clean themselves up anyway after a while. It sounds to me like theoverhead of going through this external service for every query (and remember some queries return very big chunks of data) by far exceeds the danger of faulty resource management. Also, faulty resource management is something that you can solve during the evolution of the system (as the system gets debugged). Going through an external system places a permanent bottleneck. I also see major issues with transaction management, security, usage of prepared statements, etc. These are all problems you may be able to overcome, but I doubt it's worth the trouble.

    Gal
  15. Gal,
    Incase of data base connections this might be an overkill because db will time out and close connections on its own but again we are relying on db for helping us out. Also db connections is not the only resource we need while application development. Take example of reading a configuration file. For such activities we open I/O streams managed by us only. So we have to ensure that resoucres are used in optimized manner and are freed effectively.
    We may need to do some XSLT and every time user doing Ctrl+C and restarting application will result in reloading the parsers and transformation factories. But if XSLT is run as seprate service stopping application will have minimal or no effect on parsers and will save us memory resources on user's/developer's machine.
    DK
  16. Files will close themselves up as well. I suspect the overhead of passing data through sessions all the time is bigger than the overhead of openning XSLT factories and templates. How many times does an application get closed using ctrl-C? This probably won't happen more than once or twice a day maximum. Unless it happens literally hundreds or thousands of times, I don't think the overhead of loading XSLT factories/templates is worth your trouble.

    Gal
  17. The Mother/Nanny Pattern[ Go to top ]

    There are a lot of ways to manage resources.
    If application needs this kind of workaround it means application has a problem
    with resource management design. Looks like "using" stuff in C# is designed for "bad" design too.
    I use "interceptor" or "dispacher" to solve resource management problems.
  18. The Mother/Nanny Pattern[ Go to top ]

    I really wouldn't rely on the finalizer to do its
    job right at the expected time.
    Not in J2EE Systems.
  19. We also call dispose()[ Go to top ]

    What we've done is precisely this, but we also do the cleanup, so that if we did forget to do a dispose() ourselves, and it isn't caught during development or testing, we try to recover as much as we can if the build goes to production.
    protected void finalize() throws Throwable {
        super.finalize();
        if (!closed) {
          Logger.log(Severity.WARNING, "Resources were not released. Calling dispose().");
        }
        this.dispose();
      }
    We don't rely on this as the primary way of handling closing, but we want to catch our own slips, and logging the warning as proved highly effective in pinpointing coding errors.
  20. The Mother/Nanny Pattern[ Go to top ]

    Here, assuming ExpensiveResource is an object representing some expensive resource such as a databse connection.

    public class MyClass {
      private ExpensiveResource resource;
      private boolean closed;

      public MyClass() {
        closed = false;
      }

      protected void finalize() throws Throwable {
        super.finalize();
        if (!closed) {
          Logger.log(Severity.WARNING, "Resources were not released. Call .dispose() when finished with MyClass object.");
        }
      }

      public void dispose() {
        resource.close();
        closed = true;
      }

      public ExpensiveResource getResource() {
        if (closed) {
          Logger.log(Severity.WARNING, "Cannot access resource. Encapsulating class has been disposed.");
          return null;
        }
        return resource;
      }
    }

    So basically, the finalize() method checks to see if the object was disposed. If it wasn't, it nags the user of the library until they start using .dispose() calls.
    In case of database connection a pattern such as "Data Access Command Bean"
    (EJB Design Pattern, Marinescu) automatically close the connexion. It can be extend to other kind of ressources.

    VM