Package org.rioproject.impl.event

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

/*
* 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.core.event.EventRegistration;
import net.jini.core.event.RemoteEventListener;
import net.jini.core.lease.Lease;
import net.jini.core.lease.LeaseDeniedException;
import org.rioproject.event.EventDescriptor;
import org.rioproject.event.EventHandler;
import org.rioproject.impl.service.LandlordLessor;
import org.rioproject.impl.service.LeasedListManager;
import org.rioproject.impl.service.ServiceResource;
import org.rioproject.impl.watch.StopWatch;
import org.rioproject.impl.watch.Watch;
import org.rioproject.impl.watch.WatchDataSourceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
* The EventHandler is an abstract class that handles the basic event plumbing.
* The EventHandler sets up a LandLordLessor for the event type and creates
* leased event registrations for event registrants
*
* @author Dennis Reedy
*/
public abstract class AbstractEventHandler implements EventHandler {
    protected EventDescriptor descriptor;
    protected LandlordLessor landlord;
    protected int sent = 0;
    protected long sktime, ektime;
    protected float tmp;
    protected StopWatch responseWatch = null;
    protected WatchDataSourceRegistry watchRegistry = null;
    protected LeasedListManager resourceMgr;
    public static final String RESPONSE_WATCH = "Response Time - ";
    protected long t0, t1, sendTime;
    static final Logger logger = LoggerFactory.getLogger(EventHandler.class);
    /**
     * The sequence number is an increasing value that will act as a hint to the
     * number of occurrences of an event type. The sequence number should differ
     * if and only if the RemoteEvent objects are a response to different
     * events. The sequence number should be increased only after an event has
     * been sent
     */
    protected long sequenceNumber = 0;

    /**
     * Use this constructor to create an EventHandler for a given
     * EventDescriptor with a LandlordLessor created with default values used
     * for LeasePeriodPolicy
     *
     * @param descriptor EventDescriptor for the event to handle
     *
     * @throws IOException If a landlord lease manager cannot be created
     */
    public AbstractEventHandler(EventDescriptor descriptor) throws IOException {
        this(descriptor, net.jini.config.EmptyConfiguration.INSTANCE);
    }

    /**
     * Use this constructor to create an EventHandler for a given
     * EventDescriptor with a LandlordLessor created with specific values used
     * for LeaseDurationPolicy. If either of the values specified for the lease
     * duration are null defaults will be used to create the LandlordLessor.
     *
     * @param descriptor EventDescriptor for the event to handle
     * @param config A Configuration object
     *
     * @throws IOException If a landlord lease manager cannot be created
     */
    public AbstractEventHandler(EventDescriptor descriptor, Configuration config) throws IOException {
        if(descriptor == null)
            throw new IllegalArgumentException("descriptor is null");
        this.descriptor = descriptor;
        resourceMgr = new LeasedListManager();
        landlord = new LandlordLessor(config);
        landlord.addLeaseListener(resourceMgr);
    }

    /**
     * Registers a RemoteEventListener for this event type. This method will be
     * delegated from the EventProducer#register method invocation <br>
     *
     * @param eventSource The event source
     * @param listener RemoteEventListener
     * @param handback MarshalledObject
     * @param duration Requested EventRegistration lease <br>
     * @return EventRegistration <br>
     *
     * @throws LeaseDeniedException If the lease manager denies the lease
     */
    public EventRegistration register(Object eventSource,
                                      RemoteEventListener listener,
                                      MarshalledObject handback,
                                      long duration) throws LeaseDeniedException {
        EventRegistrationResource resource = new EventRegistrationResource(listener, handback);
        ServiceResource sr = new ServiceResource(resource);
        Lease lease = landlord.newLease(sr, duration);
        EventRegistration registration = new EventRegistration(descriptor.eventID, eventSource, lease, sequenceNumber);
        if(logger.isTraceEnabled())
            logger.trace("Total registrations for {} {}", descriptor.toString(), getRegistrantCount());
        return (registration);
    }

    /**
     * Terminates this EventHandler. This causes all event registrant leases to
     * be cancelled , and if any watches have been created those watches will be
     * destroyed
     */
    public void terminate() {
        landlord.removeAll();
        landlord.stop(true);
        destroyWatch();
    }

    /**
     * Create a response time watch for this EventHandler, which will track the
     * response time for event consumers, measured by how long each fire()
     * invocation takes
     *
     * @param watchRegistry The WatchRegistry to register the StopWatch
     */
    public void createWatch(WatchDataSourceRegistry watchRegistry) {
        responseWatch = new StopWatch(RESPONSE_WATCH + descriptor.toString());
        if(watchRegistry == null)
            return;
        this.watchRegistry = watchRegistry;
        watchRegistry.register(responseWatch);
    }

    /**
     * Destroys the response time watch. Once this method is called the watches
     * will be rendered useless
     */
    public void destroyWatch() {
        if(watchRegistry != null) {
            watchRegistry.deregister(responseWatch);
        }
        if(responseWatch != null) {
            try {
                responseWatch.getWatchDataSource().clear();
                responseWatch.getWatchDataSource().close();
            } catch(RemoteException e) {
                logger.error("Destroying Watches", e);
            }
        }
        responseWatch = null;
    }

    /**
     * Get the response time watch for this EventHandler
     *
     * @return The response time StopWatch. If the watch was not created this
     * method returns null
     */
    public Watch getWatch() {
        return (responseWatch);
    }

    /**
     * Gets the total number of ServiceResource instances contained by the
     * LandlordLessor used by this EventHandler
     *
     * @return The registrant count
     */
    public int getRegistrantCount() {
        return (landlord.total());
    }

    /**
     * Used to get the next <code>ServiceResource</code> from a
     * <code>LandlordLessor</code>
     *
     * @return The next <code>ServiceResource</code> contained by the
     * <code>LandlordLessor</code>. If there are no
     * <code>ServiceResource</code> instances available in the
     * <code>LandlordLessor</code> then a value a null is returned
     */
    protected ServiceResource getNextServiceResource() {
        ServiceResource sr = null;
        try {
            while (true) {
                sr = resourceMgr.getNext();
                if(sr == null)
                    break;
                if(!landlord.ensure(sr)) {
                    if(logger.isTraceEnabled())
                        logger.trace("Could not ensure resource lease for {}", sr);
                    resourceMgr.removeResource(sr);
                    landlord.remove(sr);
                } else {
                    break;
                }
            }
        } catch(NoSuchElementException e) {
            if(logger.isTraceEnabled())
                logger.trace("No ServiceResource instances");
        }
        return (sr);
    }

    /**
     * Convenience method to print statistics for every thousand events sent.
     * This method will only print result if the
     * <code>-Dorg.rioproject.debug</code> flag is set
     */
    protected void printStats() {
        if(!logger.isTraceEnabled())
            return;
        if(sent == 0)
            sktime = System.currentTimeMillis();
        int m = sent % 1000;
        if(m == 0 && sent > 0) {
            ektime = System.currentTimeMillis();
            tmp = (ektime - sktime) / 1000.f;
            logger.trace("Sent [{}]]\t[1000/{}]\t[{}/Second]", sent, tmp, (1000.f/tmp));
            sktime = System.currentTimeMillis();
        }
    }

    /**
     * Container class for event registration objects that are created and
     * behave as the resource that is being leased and controlled by the
     * ServiceResource
     */
    protected static class EventRegistrationResource {
        private RemoteEventListener listener;
        private MarshalledObject handback;

        public EventRegistrationResource(RemoteEventListener listener,
            MarshalledObject handback) {
            this.listener = listener;
            this.handback = handback;
        }

        /**
         * Returns the event listener.
         *
         * @return The event listener
         */
        public RemoteEventListener getListener() {
            return (listener);
        }

        /**
         * Returns the handback object.
         *
         * @return The handback object
         */
        public MarshalledObject getHandback() {
            return (handback);
        }
    }
}
TOP

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

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.