> > 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