Package org.rioproject.impl.event

Source Code of org.rioproject.impl.event.RoundRobinEventHandler

/*
* Copyright to the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.rioproject.impl.event;

import net.jini.config.Configuration;
import net.jini.config.EmptyConfiguration;
import net.jini.core.event.RemoteEventListener;
import net.jini.core.event.UnknownEventException;
import org.rioproject.event.EventDescriptor;
import org.rioproject.event.NoEventConsumerException;
import org.rioproject.event.RemoteServiceEvent;
import org.rioproject.impl.service.ServiceResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.rmi.MarshalledObject;
import java.rmi.RemoteException;

/**
* The <code>RoundRobinEventHandler</code> provides an implementation of an
* <code>EventHandler</code> which supports the notification of events using
* round-robin semantic. This event handler will send notification of an event
* to a valid remote event listener (one that has an active lease) is the
* collection of event registrants. For each subsequent notification the next
* listener in the list will be notified.
* <p>
* If remote event listeners are removed from the collection of event
* registrants and the notification ordinal references the removed registrant,
* then the notification ordinal will reference the next registrant in the
* collection.
* <p>
* The sequence number for events is incremented after each subsequent fire
* invocation.
*
* @author Dennis Reedy
*/
public class RoundRobinEventHandler extends AbstractEventHandler {
    static Logger logger = LoggerFactory.getLogger(RoundRobinEventHandler.class);

    /**
     * Construct a RoundRobinEventHandler with an EventDescriptor and default
     * lease maximum and time allocation
     *
     * @param descriptor The EventDescriptor
     *
     * @throws IOException If a landlord lease manager cannot be created
     */
    public RoundRobinEventHandler(final EventDescriptor descriptor) throws IOException {
        this(descriptor, EmptyConfiguration.INSTANCE);
    }

    /**
     * Construct a RoundRobinEventHandler with an EventDescriptor and a
     * Configuration object
     *
     * @param descriptor The EventDescriptor
     * @param config The configuration object
     *
     * @throws IOException If a landlord lease manager cannot be created
     */
    public RoundRobinEventHandler(final EventDescriptor descriptor, Configuration config) throws IOException {
        super(descriptor, config);
    }

    /**
     * Implement the <code>fire</code> method from <code>EventHandler</code>.
     * This method will get the next available listener and send it an event. If
     * there are no event registrants a NoEventConsumerException is thrown
     *
     * @param event The event to send
     *
     * @throws org.rioproject.event.NoEventConsumerException is there are no event registrants to
     * send the event to.
     */
    public void fire(final RemoteServiceEvent event) throws NoEventConsumerException {
        event.setEventID(descriptor.eventID);
        event.setSequenceNumber(sequenceNumber);
        while (true) {
            ServiceResource sr = getNextServiceResource();
            if(sr == null)
                throw new NoEventConsumerException("No event consumers");
            try {
                EventRegistrationResource er = (EventRegistrationResource)sr.getResource();
                RemoteEventListener listener = er.getListener();
                MarshalledObject handback = er.getHandback();
                event.setHandback(handback);
                t0 = System.currentTimeMillis();
                listener.notify(event);
                t1 = System.currentTimeMillis();
                sendTime = t1 - t0;
                if(responseWatch != null)
                    responseWatch.setElapsedTime(sendTime, t1);
                sequenceNumber++;
                sent++;
                printStats();
                break;
            } catch(UnknownEventException uee) {
                // We are allowed to cancel the lease here
                try {
                    resourceMgr.removeResource(sr);
                    landlord.cancel(sr.getCookie());
                } catch(Exception ex) {
                    logger.warn("Removing/Cancelling an EventConsumer from UnknownEventException", ex);
                }
            } catch(RemoteException re) {
                // Not sure if we are allowed to cancel the lease here, but
                // the assumption being made here is that if we cant send the
                // notification to the RemoteEventListener then the
                // RemoteEventListener
                // must not be alive. Therefore, cancel the lease
                try {
                    resourceMgr.removeResource(sr);
                    landlord.cancel(sr.getCookie());
                } catch(Exception ex) {
                    logger.warn("Removing/Cancelling an EventConsumer from RemoteException", ex);
                }
            }
        }
    }
}
TOP

Related Classes of org.rioproject.impl.event.RoundRobinEventHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.