Modified invocation services such that providers are responsible for

delivering their own responses. They now have all the information
necessary to do so which means that they can delay the delivery of a
response until some other asynchronous event has taken place (like a
database load completing). Prior to this, they were required to complete
their service immediately and return the response back to the invocation
manager.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@216 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2001-08-11 00:05:58 +00:00
parent 9f4d4e3ac0
commit a44e552eb8
6 changed files with 86 additions and 61 deletions
@@ -1,5 +1,5 @@
// //
// $Id: ChatProvider.java,v 1.2 2001/08/04 02:54:28 mdb Exp $ // $Id: ChatProvider.java,v 1.3 2001/08/11 00:05:58 mdb Exp $
package com.threerings.cocktail.party.chat; package com.threerings.cocktail.party.chat;
@@ -13,13 +13,13 @@ public class ChatProvider extends InvocationProvider
* Processes a request from a client to deliver a tell message to * Processes a request from a client to deliver a tell message to
* another client. * another client.
*/ */
public Object[] handleTellRequest ( public void handleTellRequest (
BodyObject source, String target, String message) BodyObject source, int invid, String target, String message)
{ {
// look up the target body object // look up the target body object
BodyObject tobj = PartyServer.lookupBody(target); BodyObject tobj = PartyServer.lookupBody(target);
if (tobj == null) { if (tobj == null) {
return createResponse("TellFailed", "m.player_not_online"); sendResponse(source, invid, "TellFailed", "m.player_not_online");
} }
// deliver a tell notification to the target player // deliver a tell notification to the target player
@@ -28,6 +28,6 @@ public class ChatProvider extends InvocationProvider
tobj.getOid(), ChatService.MODULE, ChatService.TELL_NOTIFICATION, tobj.getOid(), ChatService.MODULE, ChatService.TELL_NOTIFICATION,
args); args);
return createResponse("TellSucceeded"); sendResponse(source, invid, "TellSucceeded");
} }
} }
@@ -1,5 +1,5 @@
// //
// $Id: LocationProvider.java,v 1.2 2001/08/04 01:13:36 mdb Exp $ // $Id: LocationProvider.java,v 1.3 2001/08/11 00:05:58 mdb Exp $
package com.threerings.cocktail.party.server; package com.threerings.cocktail.party.server;
@@ -18,14 +18,16 @@ public class LocationProvider extends InvocationProvider
/** /**
* Processes a request from a client to move to a new place. * Processes a request from a client to move to a new place.
*/ */
public Object[] handleMoveToRequest (BodyObject source, int placeId) public void handleMoveToRequest (BodyObject source, int invid,
int placeId)
{ {
// make sure the place in question actually exists // make sure the place in question actually exists
DObject pobj = CherServer.omgr.getObject(placeId); DObject pobj = CherServer.omgr.getObject(placeId);
if (pobj == null || !(pobj instanceof PlaceObject)) { if (pobj == null || !(pobj instanceof PlaceObject)) {
Log.info("Requested to move to non-existent place " + Log.info("Requested to move to non-existent place " +
"[source=" + source + ", place=" + placeId + "]."); "[source=" + source + ", place=" + placeId + "].");
return createResponse("MoveFailed", "m.no_such_place"); sendResponse(source, invid, "MoveFailed", "m.no_such_place");
return;
} }
// acquire a lock on the body object to ensure that rapid fire // acquire a lock on the body object to ensure that rapid fire
@@ -33,7 +35,8 @@ public class LocationProvider extends InvocationProvider
if (!source.acquireLock("moveToLock")) { if (!source.acquireLock("moveToLock")) {
// if we're still locked, a previous moveTo request hasn't // if we're still locked, a previous moveTo request hasn't
// been fully processed // been fully processed
return createResponse("MoveFailed", "m.move_in_progress"); sendResponse(source, invid, "MoveFailed", "m.move_in_progress");
return;
} }
// find out if they were previously in some other location // find out if they were previously in some other location
@@ -63,6 +66,7 @@ public class LocationProvider extends InvocationProvider
// once all these events are processed // once all these events are processed
source.releaseLock("moveToLock"); source.releaseLock("moveToLock");
return createResponse("MoveSucceeded"); // send the response
sendResponse(source, invid, "MoveSucceeded");
} }
} }
@@ -1,5 +1,5 @@
// //
// $Id: MessageEvent.java,v 1.4 2001/08/04 00:32:11 mdb Exp $ // $Id: MessageEvent.java,v 1.5 2001/08/11 00:05:58 mdb Exp $
package com.threerings.cocktail.cher.dobj; package com.threerings.cocktail.cher.dobj;
@@ -66,6 +66,16 @@ public class MessageEvent extends TypedEvent
return _args; return _args;
} }
/**
* Replaces the arguments associated with this message event.
* <em>Note:</em> this should only be called on events that have not
* yet been dispatched into the distributed object system.
*/
public void setArgs (Object[] args)
{
_args = args;
}
/** /**
* Applies this attribute change to the object. * Applies this attribute change to the object.
*/ */
@@ -1,5 +1,5 @@
// //
// $Id: InvocationManager.java,v 1.5 2001/07/19 19:18:07 mdb Exp $ // $Id: InvocationManager.java,v 1.6 2001/08/11 00:05:58 mdb Exp $
package com.threerings.cocktail.cher.server; package com.threerings.cocktail.cher.server;
@@ -135,7 +135,7 @@ public class InvocationManager
} }
// prune the method arguments from the full message arguments // prune the method arguments from the full message arguments
Object[] margs = new Object[args.length-2]; Object[] margs = new Object[args.length-1];
int cloid = mevt.getSourceOid(); int cloid = mevt.getSourceOid();
margs[0] = CherServer.omgr.getObject(cloid); margs[0] = CherServer.omgr.getObject(cloid);
// make sure the client is still around // make sure the client is still around
@@ -145,7 +145,7 @@ public class InvocationManager
", proc=" + procedure + ", cloid=" + cloid + "]."); ", proc=" + procedure + ", cloid=" + cloid + "].");
return true; return true;
} }
System.arraycopy(args, 3, margs, 1, args.length-3); System.arraycopy(args, 2, margs, 1, args.length-2);
// look up the method that will handle this procedure // look up the method that will handle this procedure
String mname = "handle" + procedure + "Request"; String mname = "handle" + procedure + "Request";
@@ -158,26 +158,14 @@ public class InvocationManager
} }
// and invoke it // and invoke it
Object[] rargs = null;
try { try {
rargs = (Object[])procmeth.invoke(provider, margs); procmeth.invoke(provider, margs);
} catch (Exception e) { } catch (Exception e) {
Log.warning("Error invoking invocation procedure " + Log.warning("Error invoking invocation procedure " +
"[provider=" + provider + ", method=" + procmeth + "[provider=" + provider + ", method=" + procmeth +
", error=" + e + "]."); ", error=" + e + "].");
} }
// if there is a response to be delivered, do so
if (rargs != null) {
// fill in the invocation id
rargs[1] = invid;
// and create a message event for delivery to the client
MessageEvent revt = new MessageEvent(
mevt.getSourceOid(), InvocationObject.RESPONSE_NAME, rargs);
// and ship it off
CherServer.omgr.postEvent(revt);
}
return true; return true;
} }
@@ -1,8 +1,12 @@
// //
// $Id: InvocationProvider.java,v 1.3 2001/07/23 21:13:29 mdb Exp $ // $Id: InvocationProvider.java,v 1.4 2001/08/11 00:05:58 mdb Exp $
package com.threerings.cocktail.cher.server; package com.threerings.cocktail.cher.server;
import com.threerings.cocktail.cher.dobj.MessageEvent;
import com.threerings.cocktail.cher.data.ClientObject;
import com.threerings.cocktail.cher.data.InvocationObject;
/** /**
* Invocation providers should extend this class when implementing * Invocation providers should extend this class when implementing
* invocation services. Because the service procedures are identified by * invocation services. Because the service procedures are identified by
@@ -23,8 +27,8 @@ package com.threerings.cocktail.cher.server;
* // provider registered for MODULE should look like: * // provider registered for MODULE should look like:
* public class TestProvider extends InvocationProvider * public class TestProvider extends InvocationProvider
* { * {
* public Object[] handleTestRequest (ClientObject source, * public void handleTestRequest (ClientObject source, int invid,
* String one, int two) * String one, int two)
* { * {
* // ... * // ...
* } * }
@@ -36,7 +40,7 @@ package com.threerings.cocktail.cher.server;
* *
* <p> Invocation procedures must also package up their response in a * <p> Invocation procedures must also package up their response in a
* particular way which is through the use of the * particular way which is through the use of the
* <code>createResponse</code> methods. These take a response identifier * <code>sendResponse</code> methods. These take a response identifier
* (which determines the name of the method that will be invoked on the * (which determines the name of the method that will be invoked on the
* response target object provided in the client) and a variable number of * response target object provided in the client) and a variable number of
* arguments. If a response was created with the identifier * arguments. If a response was created with the identifier
@@ -50,51 +54,70 @@ package com.threerings.cocktail.cher.server;
public class InvocationProvider public class InvocationProvider
{ {
/** /**
* Creates a response array properly configured with the supplied name * Delivers an invocation response properly configured with the
* and no arguments. * supplied name and no arguments.
*/ */
protected Object[] createResponse (String name) protected void sendResponse (ClientObject source, int invid, String name)
{ {
return new Object[] { name, null }; deliverResponse(source, new Object[] { name, new Integer(invid) });
} }
/** /**
* Creates a response array properly configured with the supplied name * Delivers an invocation response properly configured with the
* and single argument. * supplied name and single argument.
*/ */
protected Object[] createResponse (String name, Object arg) protected void sendResponse (ClientObject source, int invid,
String name, Object arg)
{ {
return new Object[] { name, null, arg }; Object[] args = new Object[] { name, new Integer(invid), arg };
deliverResponse(source, args);
} }
/** /**
* Creates a response array properly configured with the supplied name * Delivers an invocation response properly configured with the
* and two arguments. * supplied name and two arguments.
*/ */
protected Object[] createResponse (String name, Object arg1, Object arg2) protected void sendResponse (ClientObject source, int invid,
String name, Object arg1, Object arg2)
{ {
return new Object[] { name, null, arg1, arg2 }; Object[] args = new Object[] {
name, new Integer(invid), arg1, arg2 };
deliverResponse(source, args);
} }
/** /**
* Creates a response array properly configured with the supplied name * Delivers an invocation response properly configured with the
* and three arguments. * supplied name and three arguments.
*/ */
protected Object[] createResponse (String name, Object arg1, Object arg2, protected void sendResponse (ClientObject source, int invid,
Object arg3) String name, Object arg1, Object arg2,
Object arg3)
{ {
return new Object[] { name, null, arg1, arg2, arg3 }; Object[] args = new Object[] {
name, new Integer(invid), arg1, arg2, arg3 };
deliverResponse(source, args);
} }
/** /**
* Creates a response array properly configured with the supplied name * Delivers an invocation response properly configured with the
* and varying number of arguments. * supplied name and varying number of arguments.
*/ */
protected Object[] createResponse (String name, Object[] args) protected void sendResponse (ClientObject source, int invid,
String name, Object[] args)
{ {
Object[] rsp = new Object[args.length+2]; Object[] rargs = new Object[args.length+2];
rsp[0] = name; rargs[0] = name;
System.arraycopy(args, 0, rsp, 2, args.length); rargs[1] = new Integer(invid);
return rsp; System.arraycopy(args, 0, rargs, 2, args.length);
deliverResponse(source, rargs);
}
protected void deliverResponse (ClientObject source, Object[] args)
{
// create the response event
MessageEvent mevt = new MessageEvent(
source.getOid(), InvocationObject.RESPONSE_NAME, args);
// and ship it off
CherServer.omgr.postEvent(mevt);
} }
} }
@@ -1,5 +1,5 @@
// //
// $Id: TestProvider.java,v 1.5 2001/08/07 20:38:58 mdb Exp $ // $Id: TestProvider.java,v 1.6 2001/08/11 00:05:58 mdb Exp $
package com.threerings.cocktail.cher.server.test; package com.threerings.cocktail.cher.server.test;
@@ -14,8 +14,8 @@ import com.threerings.cocktail.cher.server.InvocationProvider;
*/ */
public class TestProvider extends InvocationProvider public class TestProvider extends InvocationProvider
{ {
public Object[] handleTestRequest ( public void handleTestRequest (
ClientObject source, String one, int two) ClientObject source, int invid, String one, int two)
{ {
Log.info("Test request [one=" + one + ", two=" + two + "]."); Log.info("Test request [one=" + one + ", two=" + two + "].");
@@ -25,12 +25,12 @@ public class TestProvider extends InvocationProvider
source.getOid(), TestService.MODULE, "Test", args); source.getOid(), TestService.MODULE, "Test", args);
// and issue a response to this invocation request // and issue a response to this invocation request
return createResponse("TestSucceeded", one, new Integer(two)); sendResponse(source, invid, "TestSucceeded", one, new Integer(two));
} }
public Object[] handleGetTestOidRequest (ClientObject source) public void handleGetTestOidRequest (ClientObject source, int invid)
{ {
int oid = TestServer.testobj.getOid(); int oid = TestServer.testobj.getOid();
return createResponse("GotTestOid", new Integer(oid)); sendResponse(source, invid, "GotTestOid", new Integer(oid));
} }
} }