View Javadoc

1   /*
2    * Copyright (c) 1998-2002 The Jgroup Team.
3    *
4    * This program is free software; you can redistribute it and/or modify
5    * it under the terms of the GNU Lesser General Public License version 2 as
6    * published by the Free Software Foundation.
7    *
8    * This program is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   * GNU Lesser General Public License for more details.
12   *
13   * You should have received a copy of the GNU Lesser General Public License
14   * along with this program; if not, write to the Free Software
15   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16   *
17   */
18  
19  package jgroup.relacs.rmi;
20  
21  import java.rmi.RemoteException;
22  import java.rmi.server.ExportException;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  
26  import jgroup.core.Callback;
27  import jgroup.core.MemberId;
28  import jgroup.core.View;
29  import jgroup.core.multicast.AckListener;
30  import net.jini.export.Exporter;
31  import net.jini.jeri.BasicILFactory;
32  import net.jini.jeri.BasicJeriExporter;
33  import net.jini.jeri.tcp.TcpServerEndpoint;
34  
35  
36  /**
37   *  Acknowledgement listener for asynchronous invocations, that is
38   *  invocations for which the client does not wait for the reply.
39   *
40   *  @author Alberto Montresor
41   *  @author Hein Meling
42   *  @since Jgroup 0.9
43   */
44  public final class AsynchAckListener
45    implements AckListener
46  {
47  
48    ////////////////////////////////////////////////////////////////////////////////////////////
49    // Fields
50    ////////////////////////////////////////////////////////////////////////////////////////////
51  
52    /** Callback to be notified at the end. */
53    private Callback cb;
54  
55    /** Members from which we are waiting a result or an exception. */
56    private HashSet waiting;
57  
58    /** The BasicJeriExporter used by this AckListener */
59    private Exporter exporter;
60  
61  
62    ////////////////////////////////////////////////////////////////////////////////////////////
63    // Constructor
64    ////////////////////////////////////////////////////////////////////////////////////////////
65  
66    public AsynchAckListener(Callback cb)
67      throws RemoteException
68    {
69      this.cb = cb;
70    }
71  
72    /**
73     *  Get a reference for the remote AckListener.
74     *
75     *  @return
76     *    A remote proxy for the <code>AsynchAckListener</code>.
77     *  @throws ExportException
78     *    Raised if the <code>AsyncAckListener</code> could not be exported.
79     */
80    public AckListener getRemoteAckListener()
81      throws ExportException
82    {
83      exporter =
84        new BasicJeriExporter(TcpServerEndpoint.getInstance(0), new BasicILFactory());
85      return (AckListener) exporter.export(this);
86    }
87  
88  
89    ////////////////////////////////////////////////////////////////////////////////////////////
90    // Methods from the AckListener interface
91    ////////////////////////////////////////////////////////////////////////////////////////////
92  
93    public void notifyView(View view)
94      throws RemoteException
95    {
96      MemberId[] members = view.getMembers();
97      for (int i = 0; i < members.length; i++)
98        waiting.add(members[i]);
99      /*
100      * Do nothing; we don't need to collect results since we are
101      * asynchronous.
102      */
103   }
104 
105 
106   public void ack(MemberId id, int vpos, Object obj)
107     throws RemoteException
108   {
109     waiting.remove(id);
110     if (obj instanceof Exception)
111       cb.exception(id, (Exception) obj);
112     else
113       cb.result(id, obj);
114   }
115 
116 
117   public void viewChange()
118     throws RemoteException
119   {
120     if (!waiting.isEmpty()) {
121       RemoteException remoteException = new RemoteException("Member unreachable.");
122       for (Iterator iter = waiting.iterator(); iter.hasNext(); )
123         cb.exception((MemberId) iter.next(), remoteException);
124     }
125     // Unexport this remote AckListener; no more remote calls should occur
126     exporter.unexport(false);
127   }
128 
129 } // END AsynchAckListener