I have multiple background processes that primarily send and receive data for the web app ( including those that parse xml for insertion, generate xml for remote acounting sytems, take in data on transactions, push out bank deposit files, send information to ach providers, listen to mesaging sytems, generate reports, make graphs, convert images, . . . -- [most of which then deliver cache updates] ). I need some framework for centralizing the control. They are currently running as chron jobs or just manually initialed. I'd like to be able to monitor, start, and restart the from a control center. I'd hate to have them all running in the same vm. I'm running most on one sun 220 but it is swamped. They are well behaved, share an nfs, and I have 3 other machines to start running them on. (I could accept a per machine control, but I'd like something better: some sort of remote control that wouldn't take them down if the controller died.) The complexity of control is becoming challenging. I'd like to pull them together into some sort of service framework. The Turbine service framework may have some application here, if not it still sounds nice for the web app. Some service could start the rmi activation daemon on a machine and then the control could call and spawn each process in its own vm. It could then send monitoring requests and issue shutdown and restart commands. Would this be an ad hoc use of the framework? Does anyone have any suggestions? Aaron -----Original Message----- From: Jason van Zyl [mailto:[EMAIL PROTECTED]] Sent: Thursday, June 14, 2001 4:07 AM To: [EMAIL PROTECTED] Subject: Summary of changes Hi, What follows is a summary of the refactoring that has been done in the Turbine sources. ---------------------------------------------------------- S E R V I C E S ---------------------------------------------------------- (1) All services now use properties in the fully qualified form: services.XYZService.<property> = value The following services have been updated to use fully qualified properties: GlobalCacheService NamingService SchedulerService XmlRpcService XsltService (2) The explicit references to Velocity Configuration class have been removed in all services except for the PullService. The PullService can be changed later, the Configuration class is too handy for placing tools in the context. The Configuration class is still used in the base classes of the services framework and they will remain there until a Configuration interface is created. The ExtendedProperties class in the commons is the new home for the original Velocity Configuration class, but I didn't just want to replace one concrete implementation with another. Some work needs to be done but I think that a Configuration interface can be made and a set of concrete implementations can be made that implement the Configuration interface. Once this is done than we can use the Configuration interface in the base classes of the service framework. (3) All services now get their configuration from the service broker (or service manager as I prefer to call it) via an accessor: String path = getConfiguration().getString("path"); What is happening is the BaseService gets the configuration for a service from the ServiceBroker using the SERVICE_NAME field present in the service interface. All the services now use this method. (4) There is now only a single init() method in all the services. All init(Object o) methods have been removed and are no longer necessary. A service is either lazily initialized, or if the service's 'earlyInit' property is set to true then it is started when the ServiceBroker is initialized. (5) All the Initable code has been removed. There are now the following set of classes: BaseService.java BaseServiceBroker.java InitializationException.java InstantiationException.java Service.java ServiceBroker.java TurbineServices.java And it would be entirely possible to remove the TurbineServices class as it is only there for backward compatibility. We may very likely want to be have more than one instance for a service, especially for subapps. We can be part of the 2.2 discussion. (6) I have tried to separate the services from Turbine proper. There are almost no references to any Turbine specifics in any of services except those that will never be decoupled from Turbine: like the AssemblerBroker and the RunData service. Running Turbine in stand-alone mode should be a lot easier, and in fact the services are pretty much there in terms of being a separate project. This is how the services framework is now initialized from within the Turbine.java class: // Get the instance of the service manager TurbineServices serviceManager = (TurbineServices) TurbineServices.getInstance(); // Set the service managers application root. In our // case it is the webapp context. serviceManager.setApplicationRoot(getApplicationRoot()); // This should eventually be a Configuration // interface so that service and app configuration // can be stored anywhere. configuration = new Configuration( getApplicationRoot() + DEFAULT_TURBINE_RESOURCES); serviceManager.setConfiguration(configuration); // We are using the 'default' category for logging // when a category isn't specified. The 'default' // category must be setup in the TRP. serviceManager.setCategory(Category.getInstance("default")); // The TurbineResourceService needs to access the // whole configuration file because it really has // no configuration of its own. serviceManager.setServiceObject("configuration", configuration); // Initialize the service manager. Services // that have its 'earlyInit' property set to // a value of 'true' will be started when // the service manager is initialized. serviceManager.init(); (7) There are now a set of properties for placing objects in the control of the ServiceBroker that can be made available to Services: setServiceObject(String key, Object value) getServiceObject(String key) I thought I would need these at first for the services that originally needed RunData and Servlet{Config|Context} objects but it turns out that I didn't. I left the properties in there so that the parent application can place objects in storage if they are required in any Services. (8) For services logging you just hand the ServiceBroker a log4j Category. A Category is another name for a logger. So with log4j it's really easy to have to services log to the same file as the rest of the turbine stuff, or you could easily have the services log to a separate file. --- There are still some gunk left in the ServiceBroker left over from getting rid of Initable code, but I just want to get the code in the repository. I think these changes have made the code easier to read and made the services more consistent. I think we can now tackle things like: -> fully pluggable services and packaging them in jars -> implementing restart() so that services can be reconfigured and restarted on the fly without the need to shut down Turbine -> making the services fully self describing in terms of the properties they support and how they are to be configured. for app deployment it would be nice if when a Turbine app was started for the first time a web console could be presented to user where the services defaults could be configured/saved and have the app go on its way. a lot of interested things could be done here. ---------------------------------------------------------- L O G G I N G ---------------------------------------------------------- The LoggingService as it was in 2.1 is completely gone and has been entirely replaced by log4j. Log4j is incredibly powerful and I think we only have things to gain by using it. As it stands I did not implement the logging in the recommended fashion but placed everything within our Log.java class. The same logging methods can be used, but we should definitely discuss how best to use log4j. I think Ceki will be glad to help us as well. I will add back configuration for the SMTP Categories and Appenders in a couple of days. You can basically do whatever you want because we are just using standard log4j properties embedded in our TRP file. If you want use the SMTPAppender in log4j it's just a matter of adding a few lines of configuration. We can fully take advantage of all the Appenders that are present in log4j via setting properties, no code to change. I will put some more examples in the TRP file. Right now I just have a the standard turbine.log and an sql.log that can be flipped on/off by setting the priority. So if you want to see all the SQL generated by the Peers then you just have to change one line and all the SQL will be logged for you. Log4j has some nifty hierachical behavior that we probably want to investigate further. There is also an example of an app server logging system with events in the log4j repository we might want to look at. I just wanted to get us using log4j as it kicks ass! An entire, rather complicated service has been removed and all the logging has been completely off loaded to log4j. I see only a benefit. ---------------------------------------------------------- P R O P E R T I E S C H A N G E S ---------------------------------------------------------- As noted above, many services had there properties fully qualified and there is the addition of the 'earlyInit' property to have a service startup when the ServiceBroker is initialized. The logging configuration is also different. It looks very similiar to what we had, but we are now using standard log4j properties. So the docs on the log4j website will tell you everything you need to know. I'm certainly no log4j expert yet, so feel free to jump in. These property changes are not backward compatible, but I've started making a TurbineAdaptor class that I hope to use to transparently transform a 2.1 TRP file so that 2.1 apps will run with change under 2.2. I don't know how well this will work but I'm going to give it a try. If it works than the changes made so far will be backward compatible. ---------------------------------------------------------- B A C K W A R D C O M P A T I B I L I T Y ---------------------------------------------------------- I have tried to stay 100% backward compatible in the code, but I am expecting GUMP and other Turbine developers to help me out. If you are depending on CVS HEAD than _please_ be patient. I'll fix/adaptor anything to try and make things backward compatible but I only have the TDK to test with and that's not comprehensive yet. I am slowly adding some tests, but unfortunately I've run out of time for this refactoring session. ---------------------------------------------------------- T U R B I N E T H E F A C A D E ---------------------------------------------------------- There is a chunk of code at the bottom of Turbine.java that now provides some standard information to the application. Previously the ServletService was used to get information about the servlet (The ServletService is still there :-)) but it can now be accessed directly from the Turbine.java class. My idea is that we can build up a contract for our users by using Turbine.java itself as a facade. What I added was necessary to allow processes/classes in a Turbine app that have no access to a RunData object to glean info about the service. The example I always use is that of a scheduled job that does some processing and stores thing within the webapp space. This code can be moved somewhere else, but I'm interested in pursing an API that can be based around the Turbine.java class so we can try to close down the gates a bit. I am constantly surprised at things that are overriden that shouldn't be. This would be something similiar to the Velocity helper class. Basically a contract for our users: a single point of access. Maybe this could be possible with some more refactoring, a unified template services ... Ok, I'm going to start checking in the code tomorrow morning because I'm baked right now. So can people lay off committing until later on tomorrow as I have to do some merging before I commit. Everything should be in by tomorrow afternoon. I'll be glad when we can start talking about 2.2! :-) -- jvz. http://tambora.zenplex.org http://jakarta.apache.org/turbine http://jakarta.apache.org/velocity http://jakarta.apache.org/alexandria http://jakarta.apache.org/commons --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
