March 19, 2009

Slice configuration on the fly



Slice now has a new feature to add new slices at runtime. Till now, Slice read a META-INF/persistence.xml  during bootstrap to configure all the slices. Now, you can add new slices on-the-fly, even within an active transaction. A new slice can be added on-the-fly via either via EntityManagerFactory or via EntityManager, for slightly different effects. In either case, the method signature is the same.

 

slice-features

/**
* Adds the given slice with the given properties.  
*
* @param name logical name of the to be added slice. Must be different from
* any currently available slices.
*
* @param properties key-value pair of configuration for the slice to be
* added. The keys must have openjpa.slice.<name>.* as prefix.

*/
Slice addSlice(String name, Map properties);

If you add a new slice via EntityManager, the slice becomes immediately available in the transaction. If a new slice is added via EntityManagerFactory, then any EntityManager created by the factory after the call is connected to the new slice.  Consider a distribution policy that stores instances of a simple entity PObject based on its current value. If value is greater than 50, the instance will be stored in a slice, logically named as newslice, that is not initially configured. Otherwise, the instance is stored in one of the configured slices. The following code shows how:

DistributedConfiguration conf = (DistributedConfiguration)emf.getConfiguration();
conf.setDistributionPolicyInstance(new DistributionPolicy() {
    public String distribute(Object pc, List<String> slices, Object context) {
        if (PObject.class.isInstance(pc)) {
            PObject o = (PObject)pc;
            if (o.getValue() > 50) {
                DistributedBroker broker = (DistributedBroker)context; // the broker that invoked persist(pc) 
                Map newProps = new HashMap(); // property keys prefix with openjpa.slice.newslice
                newProps.put("openjpa.slice.newslice.ConnectionURL", "jdbc:derby:target/database/newslice;create=true");
                newProps.put("openjpa.slice.newslice.ConnectionDriverName", "org.apache.derby.jdbc.EmbeddedDriver");
                broker.addSlice("newslice", newProps);
                return "newslice";
            } else {
                return slices.get(o.getValue()%slices.size()); // round-robin based on value
            }
        }
        return null; // unreachable
    }
});

Labels: , ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home