[interfacekit] Registrar: towards design

Hi,

to have something more concrete to discuss about, here come some ideas 
for the design of registrar and friends accompanied by a couple of 
questions.

First, it seems, that additionally to the tasks listed on our 
RegistrarNotes page (thanks Tyler) the registrar is also responsible 
for the clipboard(s).

The following entities/classes are involved:

app server:
----------

If the registrar runs basically an ordinary BApplication (leave alone 
it's specially named AppLooperPort) there might be nothing special 
about the relation to and communication with the app server.
Do I understand it correctly, that the rcv and snd ports (exclusively=3F) 
serve the communication with the app server=3F


BApplication:
------------

The BApplication constructor sets up a couple of things:

* be=5Fapp: a pointer to itself.

* be=5Fapp=5Fmessenger: a BMessenger to the application itself. It can use 
the "harmless" BMessenger constructor, i.e. the one for local targets: 
BMessenger(BHandler*, BLooper*, bool).

* be=5Froster: a BRoster object simply created via `new BRoster'. 
Afterwards some private BRoster methods are called to register the 
application at the roster service (SetThread/Signature(), 
CompleteRegistration(),...).

* The connection to the app server: <not in the scope of this mail> ;-)

When the BApplication is destroyed, it unregisters from the roster and 
cleans up the local stuff.


BClipboard:
----------

The constructor uses =5Fsend=5Fto=5Froster=5F() to initialize its BMessenger 
member fClipHandler which addresses the BHandler in the registrar 
responsible for the clipboard management. It is used for the subsequent 
communication.
Start/StopWatching() use BRoster::=5FStart/StopWatching().


BMessageRunner:
--------------

Uses =5Fsend=5Fto=5Froster=5F() to communicate with the roster service. Its 
member variable fToken contains a token assigned by the registrar for 
identification purpose.


BMessenger:
----------

Mainly the constructor BMessenger(const char *mime=5Fsig, team=5Fid team, 
status=5Ft *) is of interest, since it might need the roster service. If 
a team id is given, things are relatively harmless, since it can use 
get=5Fnext=5Fport=5Finfo() to find the "AppLooperPort" (BTW, any idea why the 
ports of some applications are called "rAppLooperPort"=3F). The token for 
the application looper handler is certainly fixed (e.g. to 0), so these 
are enough information. If an app signature is given, the roster has to 
be asked (BRoster::GetAppInfo()).

The other methods seem not to be directly related to any registrar 
functionality.


BMimeType:
---------

This has already been discussed: =5Fsend=5Fto=5Froster=5F() is used to 
communicate with the MIME service (I wonder how that function knows 
that it has to target the MIME service and not the roster. Perhaps the 
bool arg=3F See also below.) and Start/StopWatching() call 
BRoster::=5FStart/StopWatching().


BRoster:
-------

Basically consists of two BMessengers:

* fMess: addresses the roster service. It is constructed via the 
private BMessenger constructor BMessenger(team=5Fid team, port=5Fid port, 
int32 token, bool). The team and the port id can be retrieved per well-
known kernel kit functions. token is fixed, say to 0.

* fMimeMess: addresses the MIME service, can be retrieved from the 
roster service.

The header files divides the BRoster methods into three groups:
* "Querying for apps"
* "Launching, activating, and broadcasting to apps"
* "Recent document and app support"
The functionality for (almost=3F) all of them is partially or completely 
implemented by the roster service, so they will merely send a request 
to the registrar which does the dirty work. Some of them are 
implemented via private helper methods like xLaunchAppPrivate() or 
resolve=5Fapp(). We may or may not decide to do it the same way.

We will have to find out, what some of BRoster's intimate friends are 
supposed to do:

* int =5Finit=5Froster=5F(): Inits be=5Froster=3F=3F=3F But that can as well be
 done 
by BApplication as proposed above=3F!

* status=5Ft =5Fsend=5Fto=5Froster=5F(BMessage *, BMessage *, bool): Sends a 
synchronous or asynchronous message to the roster service. Params: 
message, reply and =3F

* friend bool =5Fis=5Fvalid=5Froster=5Fmess=5F(bool): Returns whether
 be=5Froster->
fMess (and fMimeMess=3F) is valid=3F Param: =3F

We also have to think about whether or not we want to implemented the 
notification mechanism the same way:

status=5Ft =5FStartWatching(mtarget t, BMessenger *roster=5Fmess, uint32 
what,
                        BMessenger notify, uint32 event=5Fmask) const;
status=5Ft =5FStopWatching(mtarget t, BMessenger *roster=5Fmess, uint32 what,
                       BMessenger notify) const;
* t: MAIN=5FMESSENGER/MIME=5FMESSENGER for the roster/MIME service as 
target for the request, otherwise USE=5FGIVEN to use roster=5Fmess.
* what: The what field of the request or the notification messages=3F
* notify: The notification target.
* event=5Fmask: Mask identifying the events to be watched.


Implementation:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

After writing this little overview, I think I understand, that our 
original idea first to write a sparse registrar skeleton with complete 
MIME support to be able to implement BMimeType won't work, or will at 
least require a pretty... err... fleshy skeleton ;-) and a partial 
implementation of the classes listed above. Otherwise we would need to 
work around a couple of things on the BMimeType end, which is an idea I 
don't really like that much. Thus I propose a more wholistic approach 
involving most of the classes above.

Originally I thought about linking the registrar against libbe using a 
stable implementation on one end, but it seems to me that this might 
cause some problems -- e.g. our BApplication looper port will have no 
special name (this can be worked around using another port that is 
forwarded to the first one though) and BRoster will talk to Be's 
registrar, which in the harmless case may hide problems until we switch 
to our library. So probably it would be better to directly start using 
the OBOS classes.

However, I promised some rough implementation ideas:

The registrar constructs an own BApplication which is aware of it being 
the registar and names the app looper port respectively. The 
application looper implements the roster functionality (i.e. it 
processes the messages), which consists of:

* basic functionality: management of running applications, BRoster 
functionality.

* clipboard functionality: a special BHandler is added to the 
application looper, that handles the clipboard management.

* timer functionality: BMessageRunner management. B=5FPULSE messages=3F A 
separate thread (timer=5Fthread) is responsible for sending the 
notifications at the right time. An event queue is the common data 
structure.

The MIME functionality implemented in a separate BLooper (main=5Fmime) 
consists of:

* database access: at least writing to and monitoring it, maybe also 
reading.

* sniffing: filename extension comparisson and sniffer rule probing.

* automatic database update: From time to time on low CPU usage a 
thread is started, that walkes through the file systems adding 
unregistered MIME types and updating application MIME types. [can be 
postponed]

It remains the system shutdown chores [can be postponed]. The strategy 
is:
1. Close the roster service for registrations.
2. Display the shutdown window.
3. Tell all registered applications to quit.
4. Send the TERM signal to all teams (save the app and input server).
5. If a team doesn't want to go, ask the user, if it should be killed.
6. Ask the kernel to do whatever it has to do and unmount the file 
systems.
[Ask the user whether to reboot, if shutdown is not supported.]
7. Quit the own BApplication and terminate app and input server.
8. Shutdown/reboot.

Most of the tasks should merely be request driven data management and 
thus relatively simple to implement. E.g. the data structure for the 
management of the running applications is basically a list of 
structures that contain all relevant information for an application. If 
an app registers/unregisters, a structure is added/remove, and query 
requests are served with information from the structures.
Not much difference for the clipboard management. An event queue for 
the timer functionality isn't that complex either.

So what should be done next, is to make a list of all concrete tasks 
and to design communication protocols. Then a concrete design of the 
registrar's data structures follows...

Answers to my questions=3F Comments=3F

CU, Ingo



Other related posts: