Flushing objects

The com.kabira.platform.CacheManager.CacheFlusher.flush() method can be used to explicitly flush objects from shared memory. Support is provided for flushing:

Replica objects cannot be flushed since this would break the application redundancy guarantees. Attempting to flush a replica object does nothing.

When an object is flushed from shared memory all object and index data is removed.

Flushing a local object is equivalent to deleting the object. This implies that any delete triggers (see the section called “Triggers”) will also be called.

[Warning]

Applications that flush objects, must be designed to ensure that the object data is consistently available whether it was flushed or not. This can be accomplished using distributed queries and ensuring that objects are fetched from secondary stores as required.

A flush notifier can be installed to control whether or not an object should be flushed. Flush notifiers extend com.kabira.platform.flusher.Notifier<T> and implement the abstract isFlushable method. They are installed with the com.kabira.platform.flusher.FlushManager.setNotifier(...) method. Returning true from the isFlushable method allows the flush to complete. Returning false from the isFlushable method cancels the object flush. If a flush notifier is not installed, objects are always flushed.

Objects can be flushed from a flush notifier. Flushing an object in a flush notifier does not cause any installed flush notifiers to be called.

The Example 5.26, “Object flushing” snippet shows local objects being flushed with one of the flush attempts being cancelled by a flush notifier.

Example 5.26. Object flushing

//     $Revision: 1.1.2.2 $
package com.kabira.snippets.managedobjects;

import com.kabira.platform.CacheManager;
import com.kabira.platform.ManagedObject;
import com.kabira.platform.Transaction;
import com.kabira.platform.annotation.Managed;
import com.kabira.platform.flusher.Notifier;

/**
 * Flushing objects from shared memory
 * <p>
 * <h2> Target Nodes</h2>
 * <ul>
 * <li> <b>domainnode</b> = A
 * </ul>
 */
public class ObjectFlushing
{
    @Managed
    private static class A
    {
        A(final String name)
        {
            m_name = name;
        }

        String getName()
        {
            return m_name;
        }
        private final String m_name;
    };

    private static class FlushNotifier extends Notifier<A>
    {
        FlushNotifier(Class<A> a)
        {
            super(a);
        }

        @Override
        public boolean isFlushable(A a)
        {
            boolean flushable = a.getName().equals(_DO_NOT_FLUSH) != true;
            System.out.println("INFO: Notifier called for " + a.getName() + ":" + flushable);
            return flushable;
        }

    }

    /**
     * Main entry point
     *
     * @param args not used
     */
    public static void main(String[] args)
    {
        //
        //    Install a flush notifier and create a local object
        //
        new Transaction("Initialize")
        {
            @Override
            protected void run() throws Rollback
            {
                CacheManager.CacheFlusher.setNotifier(new FlushNotifier(A.class));

                new A(_DO_NOT_FLUSH);
                new A("Flush away!");
            }
        }.execute();

        //
        //    Flush the objects
        //
        new Transaction("Flush Objects")
        {
            @Override
            protected void run() throws Transaction.Rollback
            {
                for (A a : ManagedObject.extent(A.class))
                {
                    System.out.println("INFO: Flushing " + a.getName());
                    CacheManager.CacheFlusher.flush(a);
                }
            }
        }.execute();

        //
        //    Report what is still in shared memory
        //
        new Transaction("Report")
        {
            @Override
            protected void run() throws Transaction.Rollback
            {
                for (A a : ManagedObject.extent(A.class))
                {
                    System.out.println("INFO: " + a.getName());
                }
            }
        }.execute();
    }

    static final String _DO_NOT_FLUSH = "Do not flush";
}

When this snippet is run it outputs (annotations added):

    #
    #    Flush object
    #
    INFO: Flushing Do not flush

    #
    #    Notifier called - cancel flush by returning false
    #
    INFO: Notifier called for Do not flush:false

    #
    #    Flush object
    #
    INFO: Flushing Flush away!

    #
    #    Notifier called - allow flush by returning true
    #
    INFO: Notifier called for Flush away!:true

    #
    #    Only the Do not flush object is left in shared memory
    #
    INFO: Do not flush