Is it possible to byte code enhance the classes in a way that does not tie each class to a specific L1? Enhance the class so that instances of that class can contain the L1 data but don't set that data at class load time. Instead, set the data when an instance of the class is actually associated with an L1. That would allow the same class to be used for objects across all L1s. If you can do that then you can use the instrumentation agent, do compile time instrumentation (maybe an annotation processor?), and/or use a custom class loader. The custom class loader would be nice for integration into containers that want to support Terracotta out of the box and remove the need for the agent or compile time options.
>> From: Geert Bevin <gbe...@terracottatech.com> >> Date: May 19, 2010 9:13:31 AM CDT >> To: tc-dev <tc-dev@lists.terracotta.org> >> Subject: [tc-dev] Toolkit and custom types for app devs >> Reply-To: tc-dev@lists.terracotta.org >> >> Hi, >> >> As we've discussed on various occasions, we're looking at allowing people to >> use the toolkit with their own types in express mode. >> >> >> Let's summarize the current design: >> >> The Terracotta clustering toolkit works by isolating itself through a >> dedicated classloader hierarchy in which it can perform byte-code >> instrumentation and launch an L1 client. This isolation is performed through >> the StandaloneClusteringProvider for the application developers and TIM >> developers are supposed to create a similar class loading gateway >> (StandaloneTerracottaClusteredInstanceFactory for tim-ehcache), but the >> latter is out of scope for this discussion. >> >> This context is private and supposed to be responsible for loading all the >> classes that enter it for several reasons: >> >> * byte-code manipulation at class definition time requires control of the >> class loading process >> >> * these classes can't be accidentally loaded by several classloaders >> >> * classes refer back to the active L1 that was started for this context and >> this allows multiple L1s to be started or shared for an application context >> (when an express client is started with the same L2 URL, it will be shared >> amongst express modules, otherwise it's isolated) >> >> To ensure this, the toolkit runtime exposes public types outside of the >> StandaloneClusteringProvider only as interfaces and the implementations are >> actually stored as a separate jar within the runtime jar. This prevents the >> classes to be loaded by the application classpath and developers to >> accidentally instantiated them. The express toolkit classloader is able to >> find this embedded jar and properly get the required types out of there. It >> also knows about the public interface types and always delegates the loading >> to the application classloader. >> >> So to create a new instance of a particular clustered toolkit type, >> application developers now do: >> >> BlockingQueue queue = clusteringProvider.getBlockingQueue(name) >> >> Which BlockingQueue is such a public interface and the name is used to keep >> track of the identity of the instance across the cluster. >> >> >> The problem: >> >> The queue instance above functions perfectly as a clustered queue, but it >> can only store literal types or objects that were instantiated through the >> clustered provider. Obviously, app devs would like to be able to store their >> own types in there. An important question for this is: >> >> What are real-world use-cases to use the express toolkit like this? >> >> Here are a couple of possible technical ideas to make this possible, but >> they only serve as a starting point for the discussion. >> >> * require app devs to bundle their custom types in a dedicated jar also and >> to only reference them through interfaces, allow us to use the same approach >> as the one we're currently using >> >> => the huge downside is that they'll most like have to restructure their >> data structures and most importantly they will have to go through a generic >> factory method and not be in control of the lifecycle of instances of these >> types >> >> * create an instrumentation agent that can instrument the byte-code of the >> classes without having to use a classloader >> >> => the problem here is that these types currently can find their relevant >> L1 client for the clustering logic, maybe some creative ideas here might >> make this possible, not sure >> >> * forget about cluster-wide object identity and create a generic >> serialization/deserialization approach that would allow types that aren't >> serializable per-se to still be clustered >> >> => this would obviously lose cluster identity but also be limited to >> whatever we support in this serialization/deserialization logic, it might >> also introduce one more concept of app devs that they need to understand >> >> * ... >> >> >> Thanks for reading this far and I hope this made some sense. Please don't >> hesitate to ask further questions and please shoot out your ideas and >> use-cases! >> >> Thanks, >> >> Geert >> >> >> -- >> Geert Bevin >> Terracotta - http://www.terracotta.org >> >> _______________________________________________ >> tc-dev mailing list >> tc-dev@lists.terracotta.org >> http://lists.terracotta.org/mailman/listinfo/tc-dev
_______________________________________________ tc-dev mailing list tc-dev@lists.terracotta.org http://lists.terracotta.org/mailman/listinfo/tc-dev