Hi,

we are currently implementing a protocol handler (let's say for a schema
"map") somewhat similar to the one for "resource" URIs. For an URI like
"map:foo" the channel (a `mapChannel') looks up "foo" in some table,
where it is mapped to, say, "http://bar.com/". So the mapChannel
constructs an auxiliary channel for "http://bar.com/". This happens in
mapChannel::Init(). Most of the other methods simply call the
corresponding methods of the auxiliary channel.

Exceptions:

- mapChannel::AsyncOpen(...) calls AsyncOpen(...) of the auxiliary
  channel, but it passes itself as the listener rather than the
  "outside" listener received as an argument. (The outside listener is
  remembered in a member variable of the mapChannel.) Thus listener
  calls (OnStartRequest, OnStopRequest, OnDataAvailable) from the
  auxiliary channel are sent to the mapChannel, which forwards these
  calls to the outside listener, however passing itself rather than the
  received channel (which would typically be the auxiliary channel).

- mapChannel::GetURI() returns the original URI ("map:foo") rather than
  asking the auxiliary channel for its URI ("http://bar.com/").

The modification of AsyncOpen(...) and the implementation of the
listener interface by mapChannel has essentially the purpose to force
the outer listener to ask the mapChannel rather than the auxiliary
channel for its URI.

So far everything is quite standard and we think that we more or less
understand it. It works. Now there is a somewhat more complex situation
for which I would ask for your advice.

Actually the mapping table is not readily available for lookup. We
rather have a socket connection to some "map server". We can write the
original URI ("map:foo" or just "foo") to that socket and tell the
socket's input listener to perform some callback action when the
translated URI arrives from the server.

That is, we have only some sort of "asynchronous" access to the mapping
table and we are not sure how to adapt the implementation of mapChannel
to that.

- One idea is to use threads and event queues to provide a synchronous
  interface to the "mapping service" (i.e., a function call returning
  the mapped URI rather than a callback).

  However, this might be overkill. It might also block important threads
  if not done properly. Furthermore, we would have to learn a lot about
  threads and event queues. (Is there any up-to-date documentation
  available?)

- Another idea is to stick with the callback-style interface of the
  mapping service: The mapChannel sends "foo" to the mapping service,
  thereby registering a callback that will eventually create the
  auxiliary channel.

  The problem with this approach is that we do not know how to deal with
  method calls to the mapChannel before the auxiliary channel is
  available. So we cannot simply forward them to the auxiliary channel.
  Well, for certain methods we can do something sensible, but still we
  would like to simply forward most method calls in order to make our
  layer as transparent as possible.

  Fortunately, it looks like many channel methods are not invoked before
  a channel has called OnStartRequest(...) at its listener. (After that
  time we know that the auxiliary channel exists and we can forward
  mapChannel method calls to it.) Can we rely on this? Is there some
  (written or implicit) specification that tells when which channel
  method may be legally invoked?

  Furthermore we have no idea how to implement mapChannel::Open() with
  this approach.

Any hints are appreciated,

Heribert.

Reply via email to