head	1.16;
access;
symbols;
locks; strict;
comment	@# @;


1.16
date	2001.05.21.21.06.01;	author leonardr;	state dead;
branches;
next	1.15;

1.15
date	2001.04.20.15.30.21;	author dlr;	state Exp;
branches;
next	1.14;

1.14
date	2001.04.12.05.19.46;	author dlr;	state Exp;
branches;
next	1.13;

1.13
date	2001.04.12.04.41.06;	author leonardr;	state Exp;
branches;
next	1.12;

1.12
date	2001.04.12.00.25.58;	author dlr;	state Exp;
branches;
next	1.11;

1.11
date	2001.04.11.20.15.37;	author dlr;	state Exp;
branches;
next	1.10;

1.10
date	2001.04.11.10.50.58;	author dlr;	state Exp;
branches;
next	1.9;

1.9
date	2001.04.11.03.31.23;	author dlr;	state Exp;
branches;
next	1.8;

1.8
date	2001.04.10.00.01.02;	author dlr;	state Exp;
branches;
next	1.7;

1.7
date	2001.04.06.23.47.11;	author dlr;	state Exp;
branches;
next	1.6;

1.6
date	2001.04.06.21.51.49;	author dlr;	state Exp;
branches;
next	1.5;

1.5
date	2001.04.06.21.50.48;	author dlr;	state Exp;
branches;
next	1.4;

1.4
date	2001.04.06.20.27.42;	author leonardr;	state Exp;
branches;
next	1.3;

1.3
date	2001.04.06.20.09.35;	author dlr;	state Exp;
branches;
next	1.2;

1.2
date	2001.04.06.19.04.14;	author dlr;	state Exp;
branches;
next	1.1;

1.1
date	2001.04.06.18.12.18;	author dlr;	state Exp;
branches;
next	;


desc
@@


1.16
log
@Moved clustering features out of RMI and into the database.
@
text
@/* ================================================================
 * Copyright (c) 2001 CollabNet.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 * any, must include the following acknowlegement: "This product includes
 * software developed by CollabNet <http://www.collab.net/>."
 * Alternately, this acknowlegement may appear in the software itself, if
 * and wherever such third-party acknowlegements normally appear.
 *
 * 4. The hosted project names must not be used to endorse or promote
 * products derived from this software without prior written
 * permission. For written permission, please contact info@@collab.net.
 *
 * 5. Products derived from this software may not use the "Tigris" or
 * "Helm" names nor may "Tigris" or "Helm" appear in their names without
 * prior written permission of CollabNet.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL COLLABNET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of CollabNet.
 */

package org.tigris.helm.tool.cache;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import org.apache.turbine.util.Log;

import org.tigris.helm.tool.cluster.ClusterObject;
import org.tigris.helm.tool.cluster.ClusterMediator;
import org.tigris.helm.tool.cluster.ClusteredColleague;
import org.tigris.helm.tool.cluster.MediatedEvent;
import org.tigris.helm.tool.cluster.PollEvent;
import org.tigris.helm.tool.cluster.PollTarget;

/**
 * The manager of cache registries within a cluster.  Reflects cache
 * invalidation events to all known cache registries.
 *
 * @@author <a href="mailto:dlr@@collab.net">Daniel Rall</a>
 * @@author <a href="mailto:leonardr@@collab.net">Leonard Richardson</a>
 */
public class CacheRegistryManager extends UnicastRemoteObject
    implements CacheRegistryManagerSpec
{
    /**
     * The key used to reference a remote instance of this class.
     */
    public static final String CLUSTER_KEY = "org.tigris.helm.tool.cache";

    private List colleagueRegistry;

    public CacheRegistryManager()
        throws RemoteException
    {
        colleagueRegistry = new ArrayList();
    }

    public void register(ClusteredColleague colleague)
        throws RemoteException
    {
        synchronized (colleagueRegistry)
        {
            colleagueRegistry.add(new PollTarget(colleague));
        }
    }

    public void unregister(ClusteredColleague colleague)
        throws RemoteException
    {
        synchronized (colleagueRegistry)
        {
            colleagueRegistry.remove(colleague);
        }
    }

    public void handleEvent(MediatedEvent event)
        throws RemoteException
    {
        if (event instanceof PollEvent)
        {
            // Extract the answering colleague and handle its poll response.
            synchronized (colleagueRegistry)
            {
                ClusteredColleague polled =
                    (ClusteredColleague) ((PollEvent) event).getSource();
                getRegistryEntry(polled)
                    .setTimePolledAt(PollTarget.NOT_WAITING);
            }
        }
        else if (event instanceof CacheInvalidationEvent)
        {
            // Invalidate the caches of all registered colleagues.
            sendEvent(event);
        }
        else
        {
            Log.warn("Unhandled cluster event sent to CacheRegistryManager: " +
                     event.toString());
        }
    }

    public void sendEvent(MediatedEvent event)
        throws RemoteException
    {
        for (Iterator iter = colleagueRegistry.iterator(); iter.hasNext(); )
        {
            PollTarget entry = (PollTarget) iter.next();
            entry.getTarget().handleEvent(event);
        }
    }
        
    private final PollTarget getRegistryEntry(ClusteredColleague colleague)
    {
        for (Iterator iter = colleagueRegistry.iterator(); iter.hasNext(); )
        {
            PollTarget entry = (PollTarget) iter.next();
            if (entry.equals(colleague))
            {
                return entry;
            }
        }
        return null;
    }
}
@


1.15
log
@Added semi-selective cache invalidation which invalidates particular caches on a write instead of all the caches.
@
text
@@


1.14
log
@Corrected debug trace.
@
text
@a108 1
        Log.debug("Received " + event + " event");
a122 2
            Log.debug("CacheRegistryManager sending CacheInvalidationEvent " +
                      "event");
a137 1
            Log.debug("Handling target " + entry);
@


1.13
log
@Added debugging code and moved RARPeer and ProjectPeer to the new caching system.
@
text
@d124 2
a125 1
            Log.debug("Sending event.");
@


1.12
log
@Added some debugging trace.
@
text
@d124 1
d140 1
@


1.11
log
@Implement the real Remote interface.
@
text
@d109 1
@


1.10
log
@Refactored internal RegistryEntry class into cluster.PollTarget, and
replaced uses appropriately.
@
text
@d73 1
a73 1
    implements ClusterMediator
@


1.9
log
@Added CLUSTER_KEY constant for use during RMI lookups.
@
text
@d63 1
d93 1
a93 1
            colleagueRegistry.add(new RegistryEntry(colleague));
d116 2
a117 1
                getRegistryEntry(polled).timePolledAt = -1;
d137 2
a138 2
            RegistryEntry entry = (RegistryEntry) iter.next();
            entry.colleague.handleEvent(event);
d142 1
a142 1
    private final RegistryEntry getRegistryEntry(ClusteredColleague colleague)
d146 1
a146 1
            RegistryEntry entry = (RegistryEntry) iter.next();
a152 28
    }

    class RegistryEntry
    {
        ClusteredColleague colleague;

        /**
         * The system time that the colleague was polled at (in milliseconds).
         * <code>-1</code> indicates not waiting on poll response.
         */
        int timePolledAt;

        RegistryEntry(ClusteredColleague colleague)
        {
            this.colleague = colleague;
            timePolledAt = -1;
        }

        public boolean equals(Object colleague)
        {
            return (colleague instanceof ClusteredColleague &&
                    this.colleague.equals(colleague));
        }

        public int hashCode()
        {
            return colleague.hashCode();
        }
@


1.8
log
@Extended java.rmi.server.UnicastRemoteObject, the class defining a
non-replicated remote object whose references are valid only while the
server process is alive.
@
text
@d74 5
@


1.7
log
@* Introduced RegistryEntry private inner class to keep track of
polling information.

* Implemented handling of PollEvents.
@
text
@d54 1
d71 2
a72 1
public class CacheRegistryManager implements ClusterMediator
d77 1
@


1.6
log
@Since we use Iterator, we must import it.  ;-)
@
text
@d84 1
a84 1
            colleagueRegistry.add(colleague);
d102 7
a108 1
            // TODO: Handle the poll response.
d127 43
a169 2
            ClusteredColleague colleague = (ClusteredColleague) iter.next();
            colleague.handleEvent(event);
@


1.5
log
@Implemented sendEvent() and handling for CacheInvalidationEvents.
@
text
@d49 2
a51 1
import java.util.ArrayList;
@


1.4
log
@Added unregister method to interface.
@
text
@d105 2
a106 1
            // TODO: Invalidate the caches on all registered JVM colleagues.
d118 5
a122 1
        // TODO
@


1.3
log
@The handleEvent() method should take action when a poll response comes
in other than repolling.
@
text
@d87 9
@


1.2
log
@Event handling changes.  Now properly handling PollEvents.
@
text
@d56 1
d92 1
a92 2
            // Respond to the poll.
            sendEvent(new PollEvent(this, event));
@


1.1
log
@Cross JVM communication services.
@
text
@d91 2
a92 1
            // TODO
d96 1
@

