views:

28

answers:

1

Scenario:

  • Client C connects to Server S via RMI
  • C asks S to create a handler H, S returns H to C
  • C then talks to H

Now I could do this in two ways:

  • Make the handler a Remote and let S return the stub to it, so C can directly talk to that (h.say(String msg);)
  • Give the handler an ID and return that to C. C will talk to H via S (s.sayToHandler(int id, String msg);)

The first is nicer OO, but what about the performance? Will an extra TCP connection be opened, or is the existing connection between S and H used?

A: 

I don't know about the implementation. I don't think a new connection is made. But what I know is the more objects you share remotely the more objects that depends on remote dereference to get garbage collected (so there will be more objects living longer, not good).

Alternative approach

I'll recommend a mixed approach. Use the nice approach for the client but implement it the not-so-nice-way internally:

interface Server {

  public Handler getHandler(...);
}

interface Handler extends Serializable {
  // it gets copied!
  public X doThis(...);
  public Y doThat(...);
}

class HandlerImpl implements Handler {
  public X doThis(...) {
    backDoor.doThis(this, ...);
  }
  public Y doThat(...) {
    backDoor.doThat(this, ...);
  }

  private BackDoor backDoor;
}

interface BackDoor {
  public X doThis(Handler h, ...);
  public Y doThat(Handler h, ...);
}

class ServerImpl imlpements Server, BackDoor {
  public Handler getHandler(...) {
    return /*a handler with a self reference as backdoor, only ONE remote obj shared via TWO interfaces */
  }
  ...
  // it does everything
  // it receives the handler
}

BackDoor and Handler are sync'ed interfaces. The first has the methods with Handler as argument, the later has the pure methods. I don't think it's a big deal. And the two different interfaces let you work cleanly without the client know nothing and allowing the thin serializable Handler's do the dirty work.

Hope you like it!

helios
I used this approach for giving a GWT-client (google web toolkit, so indeed it's javascript) "tickets" for getting paged data. The main query method (getCustomers) returns a ticket, and the client can ask the ticket for partial data (retreive from X to Y). The ticket internaly does: `pageddataservice.retrieve(this, X, Y)`. The pageddataservice (a well known service) finds the original data provider for the ticket (a central registry) and does provider.retrieve(ticket, X, Y). Seems complicated but for the client is near magical.
helios
If you don't mind you can fusion Server and Backdoor letting the user invoke `myServer.doThis(handler, ...)` or invoke the nicer `handler.doThis(...)`. It simplifies a little the implementation at the cost of publishing the handler-receiving methods.
helios