FAQ

I tried to compile the example.h from the coid front page:
coidgen example.h
make

That's the point where I'm stuck. What is supposed to happen here? It's just generating an example_dispatch.o.
Ok, I think this is covered deeper in the documentation, under the 'manual' section - generating communication layer - although maybe we should be really more detailed with these steps.

The coidgen should have generated example_dispatch.cpp, a makefile, and a folder 'client' with client .h and .cpp files.
All these files contain the communication layer generated for the 'example' class. The example_dispatch.cpp file is the server side part, while the client/example_client.h is client side mirror class, a class that is used on the client side.

So what you should do is to create implementation file for server side, to implement methods declared in the example.h class. The coidgen won't do this for you, as it only generates an independent layer for specified class, that dispatches calls to the methods of the class.
So if you basically have your .h and .cpp files working, you can just decorate the declarations of class, and have coidgen generate the layer.

The client side is generated by coidgen as a whole, because it only kind of 'mirrors' the server (or remote) class and you usually don't have to do anything there. So it outputs the .h and .cpp file that you link with your client project, using the class with _client suffix in a way that you would use the original class, if it wasn't remote.

So - create two projects - server and client. To the server project add the example_dispatch.cpp, your custom example.cpp, and build. You should link it with the coid/coidsvc/coidsvc.a coid/comm/comm.a libraries, as it's done in the makefile (the makefile is there for these purposes, anyway). Output file should have the .dev extension, so that the coid would find it and make available for serving.

For the client side, you would probably add a .cpp file that creates the example_client class, connects it, and calls some methods to check that it works. The client project should contain the generated client files, and you should link it coid/comm/comm.a library too.

I use the command:
g++ -Wall -I/usr/local example_client.cpp client.cpp /usr/local/coid/comm/comm.a
I'm getting linker errors
You have to link it with dl and pthread library too, same as with the server side makefile, add
-lpthread -ldl
or add them to the command line, if you like

We don't generate makefile for client, as it's expected to be a part of another (client) project anyway, but we should state the linking requirements somewhere in the documentation.

What is the username and password i need to use the coid console?
username root, empty password

The makefiles work correctly as long as the program is in coid/apps/programname/.
The makefiles are incorrectly generated, they use relative path to coid stuff as in our development environment, instead of the installed directories. That will be fixed in next release, thanks for pointing that out.

devconf: I use this .devconf file:
        port 55099
        directory /usr/local/lib/coid/device
        default all
        service TestClass dir /usr/local/coid/bin/device/TestClass/

Configuring the server using the .devconf file works generally (changing the port, directory), but not the 'service' line. So I have to copy my .dev files always in the /usr/local/lib/coid/device folder, because 'make' puts them into the /usr/local/coid/bin/device folder. Is the 'service' command not working or is there a misconfiguration?
The 'dir' switch after the 'service' command sets the working directory for instances of the service (a custom served class), not the location of the service. The devices to load are specified with the 'directory' line, but coid expects them to be located in their respective subdirectories, like if you specify
    directory /usr/local/lib/coid/device
coid would look for the .dev files in all direct subdirectories of it, for example
/usr/local/coid/bin/device/example/example.dev
would load thusly.

Is there a difference between net_out and net_fetch? When should I use net_fetch?
With net_fetch, the server side method implementation returns a pointer or a reference to an existing object, that should be returned. With net_out, the implementation is expected to copy the result to the argument.
Example:
    opcd func( net_out myclass& x) { x = blabla; }
    opcd func( net_fetch myclass*& x)  { x = &blabla; }

In the first case, dispatcher declares a myclass object, and calls the implementation:
    myclass x; func(x);
Whereas in the second case, dispatcher declares just a pointer:
    const myclass* x; func(x);

Clearly, net_out involves an additional copy constructor call, because the temporary object must be filled, which may be costly if the class is complex. So we could use net_fetch for the dispatcher to retrieve just a pointer to the object.
You can wonder why it's not fetch-way default for net_out. That's because sometimes the implemented method would generate a temporary object by itself, and it cannot return a pointer to it since it dies on stack after exiting from the function. Also, sometimes copying is cheap.

    So general rule is - if the method returns something already contained within the class, that doesn't have trivial copy constructor, fetch it. Otherwise, use net_out.

I have also found a remark that it's possible to link more than one dispatch file to a device. How can I do that? Is there a way to generate a makefile doing that or do I have to do that manually? Is there an advantage to have more classes in one device and not one class per device?
You can just place all .cpp files in one folder - the makefile generated by coidgen includes all .cpp files found. Or you can edit the makefile (the SRC= line) to include files from specified folders where the services you need were generated. With VisualC, just place the .cpp files from all the classes you want into one project outputting the .dev file. The resulting device contains all coid-ified classes.

Your application can have multiple interfaces (that is, classes) accessible from outside, that work on a common kernel. So we have a data server, that has 3 or 4 exported classes - a core server, that spawns it's unique instance at the beginning, that isn't accessed directly by end-user client, but by other servers and by other classes. Then there is a session class, that is created per connected user. Then there's a workspace class, that the session can have multiple open within the same communication channel. All the classes access the same stuff - a data repository, but provide different services, some are for the clients, some for central processing and so.

So, it becomes an advantage when you need it. With bigger projects, the need for this comes almost always.

Also, another scenario is that you have a server (non-coid primarily), that contains many internal classes and instances of that classes. Some classes can be decorated, and coid can be added as an additional access gateway. You can then connect through clients to the internal objects and retrieve a debug/status information, or execute methods and so on.
     This creates some interesting possibilities, for example, since the dispatcher works with generic binstream, you can bind to an object with console, and execute methods right from there. And get the formated results back. With the XmlHttpRequest done all through a browser.

The coid stuff can be almost* non-invasive, that means the generated dispatcher is just and additional layer not used by the original server stuff. Although, "almost non-invasive" means that there must be mutex locks to prevent collision between coid accessing the object and other stuff. Coid generates the locks automatically, but only for access through coid, of course.

Another important question especially for huge applications: When are the exported classes getting created? After the request or as soon as the device is loaded? Especially if this class needs big amounts of memory it would make a significant difference. If it was created just on request, there would be the nice possibility to do something like load balancing. If you had a cluster of similar servers, you could load all devices on all servers and implement in the clients a routine to connect always to the server with the lowest load. Is something like that possible?
It depends on the class. Normal classes are created upon request. But if the class contains accept_connect_auto() method, the framework server creates one instance of the object and client can connect using connect_shared() with id 0 to this one. If such class doesn't contain accept_connect, normal create-upon-request behavior is disabled.

Similarly, a presence of accept_spawn() method is understood as a requirement to call the accept_spawn method after creating the instance of class, so the object may execute whatever it needs, even without any client connected (what servers routinely do).

We considered to include load balancing to the coid, but later decided to create a load-balancer service (specific for our project), because the decisions about where to redirect were much more complicated than a simple load criterion.
    Anyway, this balancer does its job: it decides which server would be optimal, opens the service on that server, and returns a NODE_ADDRESS parameter to the client. Using that parameter the client can connect to the chosen target server.

It would be nice if that all could be transparent to the client, so it wouldn't have to know there's a balancer at all in the path. And it definitely can be done if there's strong desire for it. It will need a change the protocol, I think, but maybe it can piggyback with the update on the authentication thing.


Today I tried to compile my test program under windows. I generated the server and client files as usual (coidgen), but what's  to do then? I get the usual Makefile for the server side. Should I use this (and use also gpp under windows) or should I generate the .dev file with Visual C++? If that's the case what settings have to be made?
We do not use the makefile for windows, we create standard projects in VisualC. We could possibly generate .dsp files to make it easier, but then there are also the VC6 and VC7 and VC8 formats ... but I think we should do it anyway, higher versions of VC should do the conversion automatically.

You should make the project output a .dev file, and link the project with the comm library.

In coidc, about the command 'find'. If I type 'find AccountMgr', I get 'requested object not found'. Why that?
This is the ugliness of the console access. COID server uses several internal classes to perform various tasks, such as acceptors, plugin and service wrappers and so on. It keeps instances of these in a tree structure, so there's a parent relation and dependency links between them. This is used to properly kill selected objects and objects depending on them.

Now the .dev files are represented in the hierarchy as PluginCoid objects, their exported classes appear as ServiceCoid objects, and instances of the served classes are listed as ServiceInstanceCoid objects there.

So in the example, AccountMgr is managed class coming as either ServiceCoid or ServiceInstanceCoid (it's been spawned at the start). So proper way is to search for these, but this returns all of ServiceCoid classes.
There are commands finds and findi, that look for services or instances, respectively.
Use 'findi AccountMgr'.

There's one problem though, findi only looks for instances that were automatically spawned when the server had started (these are unique, and findi is internally used to find some core objects). For normal instances you must use find ServiceInstanceCoid <name>

Except that <name> of object is initially the class name, but the instance can rename it to whatever it wants (for example a user name). So it happens that the console instance names itself as "console 2 alpha" and you cannot search for simple class name there then.
The remote console will be redesigned soon to clear these things out.
I'd like to test my demo program in the console. However if I change to the correct node and type 'help', there are not the methods listed as possible commands (like in the account manager for example). Do I have to specially export these methods for the console?
This certainly works but please be aware that you can only call methods on instances, not on the representation of a service (that is of the ServiceCoid - type).

You've probably called help on the service, and not the instance. Connect a client first, so the server creates an instance of your class, and then inspect it with coidc.
 You can even create instances from the console, but just now you still need a ConnectionCoid object on the server to do it on. ConnectionCoid represents one tcp connection, and manages all instances open under it.
But here comes the trick: since the coidc is alone using a console service, so it's got a ConnectionCoid created already. When I did:

find ServiceInstanceCoid
28 LogEntMgr 33 LogEntMgr 7 AccountMgr  (auto)27 console 2 alpha32 console 2 alpha24 HttpServ 0.126
HttpServ 0.123 MudCore  (auto)30 ChatCore 0 alpha (auto)

27 cid
29

29 connect MudPort
ok
15:49:00 camn  35 MudPort  a attaching [ServiceInstanceCoid]    (MudPort)
15:49:00 camn  15 service  i started instance of {MudPort} (35)



There are some bugs here, find* doesn't separate entries with anything; I could not use 'find ServiceInstanceCoid "console 2 alpha"' to find what id has got my console instance, I took it from the list the 'find ServiceInstanceCoid' gave me.
Then I ask for id of its ConnectionCoid object with 'cid'.
On that I can use 'connect' command to create instances of another classes.

As you can see, this gets somewhat complicated because you have to know the internals. And its ugly. But this shouldn't be necessary and the coidc should have be redesigned to make things simpler and elegant. Because of this it hadn't been updated and cleaned much so you have to be somewhat patient with it, sorry.