You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@river.apache.org by Kúti Zsolt <ku...@prolan.hu> on 2010/07/08 13:24:14 UTC

lease grantor example

Hello,

Can somebody point me to a simple example of a lease grantor?
Outrigger and mahalo seems rather complex for getting hints.

I develop a service that is to offer remote listeners notificiations
on its working.

Thanks!
Zsolt

Re: lease grantor example

Posted by Kúti Zsolt <ku...@prolan.hu>.
Thu, 8 Jul 2010 10:23:16 -0400 -n
"Christopher Dolan" <ch...@avid.com> írta:

> Zsolt,
> 
> Below is a fairly straightforward implementation example from my
> project's code (this email will probably line-wrap it badly...)  This
> example ignores the requested lease duration and uses a fixed value.
> The reaper is not included in this example, but it's implementation
> is trivial: a TimerTask that runs periodically via Timer.schedule()
> and removes expired leases from my Map.  The exposed service that
> allows clients to request initial leases is also not included, but it
> simply invokes getLease() in the code below.

Christopher, thank you for the example!

Zsolt

RE: lease grantor example

Posted by Christopher Dolan <ch...@avid.com>.
Zsolt,

Below is a fairly straightforward implementation example from my project's code (this email will probably line-wrap it badly...)  This example ignores the requested lease duration and uses a fixed value.  The reaper is not included in this example, but it's implementation is trivial: a TimerTask that runs periodically via Timer.schedule() and removes expired leases from my Map.  The exposed service that allows clients to request initial leases is also not included, but it simply invokes getLease() in the code below.



package com.avid.workgroup.notification;

import java.rmi.RemoteException;
import java.rmi.server.ExportException;
import java.util.HashMap;
import java.util.Map;

import net.jini.core.lease.Lease;
import net.jini.core.lease.LeaseDeniedException;
import net.jini.core.lease.UnknownLeaseException;
import net.jini.export.Exporter;
import net.jini.id.Uuid;
import net.jini.id.UuidFactory;

import com.avid.workgroup.notification.NotificationException;
import com.sun.jini.landlord.Landlord;
import com.sun.jini.landlord.LandlordLease;
import com.sun.jini.landlord.LeaseFactory;

class SubscriptionLandlord implements Landlord {
    private final LeasingProducerTopicTable m_producerTopicTable;
    private final Exporter m_exporter;
    private final LeaseFactory m_leaseFactory;
    private final long m_leaseMilliseconds;

    /** constructor for a SubscriptionLandlord.
     * @param producerTopicTable the producerTopicTable into which we'll place subscription info.
     * @param exporter the exporter we should use to export ourselves.
     * @param leaseMilliseconds when we generate or extend a Lease, the number of milliseconds we grant.
     * @throws NotificationException if anything goes wrong.
     */
    SubscriptionLandlord(LeasingProducerTopicTable producerTopicTable, Exporter exporter, long leaseMilliseconds)
            throws NotificationException {

        m_producerTopicTable = producerTopicTable;
        m_exporter = exporter;
        m_leaseMilliseconds = leaseMilliseconds;
        Uuid ourUuid = UuidFactory.generate();
        Landlord proxy;
        try {
            proxy = (Landlord) m_exporter.export(this);
        } catch (ExportException e) {
            throw new NotificationException("Unable to export lease landlord", e);
        }
        m_leaseFactory = new LeaseFactory(proxy, ourUuid);
    }

    /**
     * Get a new lease for a subscription to return to a Notification Consumer.
     * @param topic The topic for the subscription.
     * @param producerLeaseData Data stored about the subscription by the producer.
     * @throws NotificationException if anything goes wrong.
     * @return the lease.
     */
    Lease getLease( Class<? extends AbstractNotification> topic, IProducerLeaseData producerLeaseData ) throws NotificationException {
        Uuid leaseUuid = UuidFactory.generate();
        LandlordLease retLease = m_leaseFactory.newLease(leaseUuid,
                                                         System.currentTimeMillis() + m_leaseMilliseconds);
        // put the lease into the Producer Topic Table
        m_producerTopicTable.addLease( topic, producerLeaseData, retLease);
        return retLease;
    }

    /**
     * get rid of any resources being held by this landlord.
     * <p>
     * Note that this method unexports the
     * exporter even if there are pending remote calls to it.  The caller (the Notification Consumer)
     * must be prepared for this (I would guess it results in RemoteExceptions).
     * </p>
     */
    void dispose() {
        m_exporter.unexport(true);
    }

    /**
     {@inheritDoc}
     */
    public long renew(Uuid uuid, long duration) throws LeaseDeniedException, UnknownLeaseException, RemoteException {
        // whatever they ask for, we renew for m_leaseMilliseconds.
        return m_producerTopicTable.renewLease(uuid, m_leaseMilliseconds);
    }

    /**
     {@inheritDoc}
     */
    public void cancel(Uuid uuid) throws UnknownLeaseException, RemoteException {
        m_producerTopicTable.removeLease(uuid);
    }

    /**
     {@inheritDoc}
     */
    public RenewResults renewAll(Uuid[] uuids, long[] durations) throws RemoteException {
        long[] granted = new long[uuids.length];
        Exception[] denied = new Exception[uuids.length];

        for (int i = 0; i < uuids.length; i++){
            try {
                granted[i] = renew(uuids[i], durations[i]);
                denied[i] = null;
            } catch (Exception e) {
                granted[i] = -1;
                denied[i] = e;
            }
        }
        return new Landlord.RenewResults(granted, denied);
    }

    /**
     {@inheritDoc}
     */
    @SuppressWarnings("unchecked") // jini 2.1 doesn't support generics
    public Map cancelAll(Uuid[] uuids) throws RemoteException {
        Map<Uuid, Exception> failures = new HashMap<Uuid, Exception>();
        for (Uuid uuid : uuids) {
            try {
                cancel(uuid);
            } catch (Exception e) {
                failures.put(uuid, e);
            }
        }
        // cancelAll is supposed to return null, not an empty Map, if no cancel fails
        return failures.isEmpty() ?  null : failures;
    }
}

-----Original Message-----
From: Kúti Zsolt [mailto:kuti.zsolt@prolan.hu] 
Sent: Thursday, July 08, 2010 7:45 AM
To: river-user@incubator.apache.org
Subject: Re: lease grantor example

Thu, 8 Jul 2010 13:24:14 +0200 -n
Kúti Zsolt <ku...@prolan.hu> írta:

> Hello,
> 
> Can somebody point me to a simple example of a lease grantor?
> Outrigger and mahalo seems rather complex for getting hints.
> 
> I develop a service that is to offer remote listeners notificiations
> on its working.
> 
> Thanks!
> Zsolt

OK, in the meantime I figured out what seems to be the essence for my
case:
- use LandLord and implementations around it to back up the Lease
  instance returned in EventRegistration
- organize own service implementation so that lease operations happen
  via the service remote reference
- apply additional application specific logic in Lease methods, if
needed, in the above own service implementation
- use a reaper thread to expunge expired leases

I hope this is it.

Zsolt

Re: lease grantor example

Posted by Kúti Zsolt <ku...@prolan.hu>.
Thu, 8 Jul 2010 13:24:14 +0200 -n
Kúti Zsolt <ku...@prolan.hu> írta:

> Hello,
> 
> Can somebody point me to a simple example of a lease grantor?
> Outrigger and mahalo seems rather complex for getting hints.
> 
> I develop a service that is to offer remote listeners notificiations
> on its working.
> 
> Thanks!
> Zsolt

OK, in the meantime I figured out what seems to be the essence for my
case:
- use LandLord and implementations around it to back up the Lease
  instance returned in EventRegistration
- organize own service implementation so that lease operations happen
  via the service remote reference
- apply additional application specific logic in Lease methods, if
needed, in the above own service implementation
- use a reaper thread to expunge expired leases

I hope this is it.

Zsolt