[Fresco-devel] Server-resolution/publishing algorithms and proposal

Neil Pilgrim <[email protected]>
Newsgroups gmane.comp.video.fresco.devel
Message-ID <[email protected]>
With the completion of bug80, server resolution and publishing is
hopefully simpler and cleaner. I shouldn't really comment on the current
state since I did most of the refactoring ;) However I'm going to
comment on how we could improve it further (IMO) :)

Tobias mentioned on irc that he hoped we'd document how this all works
at some point, so hopefully this email will give a brief (initial)
summary of how it works at the moment, and a guide of what facilities
are available for (C++) client authors. I'll also go through the server
api too...for those seeking to reimplement what we have already ;)

Introduction
------------
Obtaining a reference to the server can currently be done in a number of
different ways. Currently supported methods are 'nameserver' and 'ior'
(you may see 'corbaloc', but that is not currently working). There is a
set default method, which can be bypassed by using the -R (or
--export-ref) option.

'nameserver' involves using a corba nameservice; in almost all cases
this will be the omniORB nameserver. 'ior' involves using a stringified
version of the server reference, which can be input/output either into a
file in some common directory or via standard-input/output. When using
the 'ior' option an additional option is available (-I or
--ior-file-path), which is used to specify the directory where the
reference-file is stored, or that the ior should be read/written from
"stdin"/"stdout" (which are treated as special keywords, and will not be
treated as a directory).

These options are available for both client and server, and use the same
core code. This means that the options can be uniform, and that default
values (for -R, -i and -I) are easily synchronised.

There are two versions of the publishing/resolving functions. This is so
that app/server writers are not restricted to using Prague::GetOpt, but
can use some other parameter-parsing methods or other ways of selecting
the appropriate options. However in current clients it is far easier and
simpler to just use the GetOpt-enabled functions for now (IMO).

In addition to refactoring and tidying the code, the code has been
extended to deal with multiple servers running on the same machine. For
this to work, there is now an additional option to specify the server-id
(-i or --server-id), either for the server you're just starting, or the
server you want a client to contact. The server-id is used as the name
of the file when using the 'ior' method (and not stdin/stdout, of
course), or is the entry in the nameservice when using the 'nameserver'
method.

Server-publishing
-----------------
To publish the server we call the following three methods, in order
(though not necessarily straight after one another):

a) check export_method is valid, and set method (eg. ior/nameserver
above):
  void set_server_reference_export_method(std::string export_method);
b) get poa to use for creating server in (for corbaloc extension
purposes):
  PortableServer::POA_ptr get_server_poa(CORBA::ORB_ptr orb,
                                         PortableServer::POA_ptr
default_poa);
c) publish server reference
  void publish_server(Fresco::Server_ptr server,
                      std::string server_id,
                      std::string ior_file_path,
                      CORBA::ORB_ptr orb);

NOTE: the interface for this last function is different in the source;
an extra option is there, which is not required (duplication of the
export/transfer-method). I'm preparing a patch now, but the api above is
the desirable one, not the one currently in cvs.

For servers using Prague::Getopt the first two options are still called,
but instead of c) you use:
  void publish_server(Fresco::Server_ptr server,
                      Prague::GetOpt const &getopt,
                      CORBA::ORB_ptr orb);

In addition you call
  void add_resolving_options_to_getopt(Prague::GetOpt &getopt);
to set-up the getopt options, before a).

Clients: resolving
------------------
The client interface is simpler: if not using Prague::GetOpt we use:

  Fresco::Server_ptr resolve_server(std::string server_id,
                                    std::string
reference_transfer_method,
                                    std::string ior_file_path,
                                    CORBA::ORB_ptr orb);

whereas if using Prague::GetOpt we use (as with the server):
  void add_resolving_options_to_getopt(Prague::GetOpt &getopt);
followed later by
  Fresco::Server_ptr resolve_server(Prague::GetOpt const &getopt,
                                    CORBA::ORB_ptr orb);

Environment variables
---------------------
Environment variables are intended as an alternative location to store
the server reference. Their benefit is that they carry over telnet/ssh
easily, so you can start up a display-server, load a terminal, ssh to
your client machine and load an app - the app knows which display to use
via the reference stored in the environment variable.

The current system uses the variable FRESCO_DISPLAY, and stores the
stringified server reference. During publish_server the contents of the
variable are overwritten with the data from the server which is just
loading. During resolve_server, if we find a valid server reference in
FRESCO_DISPLAY, then we *always* use it, instead of using another
method. This works in most cases but is in need of rewriting, eg. to
allow starting of apps from one server which will display in another.

Extending the resolution algorithm
----------------------------------
We've discussed this on irc and have had conflicting ideas of how to
proceed. I hope some of this is simply misunderstanding each other, or
not thinking things through completely (well, for me at least ;), so
here's a summary of some extension ideas that I remember from
discussion.

We seem to agree that if a different -i or -R (or even -I) option is
specified on the command-line, then we should not preferentially choose
a reference stored in the environment variable. That is, using -R to
specify a method explicitly should not (underhandedly!) use the
environment when the user wants to use another method instead.

This brought up whether the environment-variable should be just another
method, to be used instead of 'ior' or 'nameserver', eg 'env_var'.
However we may wish to publish in both the environment and the
nameserver, for example. I suggest we could extend the -R option to take
multiple comma-separated arguments, to allow something like '-R
ior,env_var' for example. For the server this would publish in those
(multiple) locations; for the client it would search those locations for
the best match (see below).

There are differences between 'env_var' and other publishing methods
however: currently the environment only stores *one* reference, the
last-started server. On the other hand the other methods can store
multiple server-id/reference pairs. One way to balance this would be to
allow a series of IORs to be stored in FRESCO_DISPLAY, along with their
associated server-id's, eg.
FRESCO_DISPLAY=FrescoServer,IOR:26713906871349067...;Server2,IOR:11896123895;
The mitigating factor against doing this is that environment variables
are only set in child environments, whereas the other methods publish in
directories which are available from far more processes. However since
environment-variables can be set manually if desired (the manual
(re-)setting on restarting servers should disappear if we use persistent
server references), I don't see this as a major argument against this
extension. In any case, even if we don't use this feature often, that's
no reason for not having the facility there when we want it.

The final point is whether the selection of where to obtain the
server-reference from can be automated in any way. For example, given a
server-id of 'Server0', we might look in the environment, filesystem
(ior) and nameservice for that server-id and find the 'best' match. The
difficulty with doing this is currently twofold: a) I understand there
have been problems with hangs/long-timeouts when testing whether the
nameservice contains a reference (or similar) b) we might pick the
'wrong' server to attach to. Note that for environment-variable storage
to participate in this process we need capability for a multi-server-id
version, as in the previous paragraph, to be able to disambiguate
server-id's. The idea would be to look through each available publishing
method in turn and search for a matching server-id. If multiple (or no)
matches are found, we return a (helpful!) error message. If a single
match is found, we use that server. We could also disable the nameserver
from participating in the automatic search, to avoid problems with
hanging, at least for now.

In summary (I think this is everything), I'd propose we extend the
system such that we:
- have a new 'env_var' option to -R (--export-ref), which enters the
server reference into an environment variable,
- extend the environment variable storage format to allow multiple
server-id/reference pairs to bring it on a par with the other methods,
- allow the -R option to take multiple (eg. comma-separated) arguments;
servers publish in each specified location, clients search in each
location.

Phew. Any comments/questions, please followup here :)

-- 
Neil, awaiting a barrage of analysis.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.