Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Summer of Code 2011 Service Clients
The very first sketch
This is a Service Client sketch illustrating some of the first ideas we had for a libxmmsclient-sc.
First lower level sketch by nesciens
This first sketch illustrates some ideas for the contents of a client-to-client message, a callback for service clients to receive calls and method dispatching:
nano-'s broken approach
This other sketch adheres more strictly to the idea of using broadcasts to communicate between clients. Doesn't allow synchronous communication.
Second sketch by nesciens
A sketch of the changes needed in libxmmsclient and the basic idea behind libxmmsclient-sc.
A more detailed sketch for libxmmsclient-sc
This one builds upon the previous paste and considers a few issues that may arise now that the server-side implementation took shape.
Implement message-passing in ipc.c
It seems to be simpler and cleaner to implement message-passing between the clients through the server in ipc.c rather than creating a new object.
This could be accomplished by storing client ids in the corresponding xmms_ipc_client_t and adding a new command (XMMS_IPC_CMD_C2C_MSG) to the XMMS_IPC_OBJECT_SIGNAL, which, in process_msg, would be processed by calling a new method xmms_ipc_c2c_msg_write.
This xmms_ipc_c2c_msg_write method would locate and contact the destination client by searching for the client with the destination id (which should also be registered for a c2c broadcast in the regular way) in much the same way it happens in xmms_ipc_broadcast_cb.
A new object in the server
A new object could be introduced in the server, providing methods to forward messages and replies between clients. This object would be roughly a dumber version of the Service object and the IPC Pending Pool in puzzles' implementation.
This object (let's call it XMMS_IPC_OBJECT_COURIER for now) would be responsible for passing messages between the clients and matching replies with the corresponding queries, by keeping its own registry of pending messages.
It would be closely related to the main IPC object, in that it would use some of its data structures and functions to pass messages to clients. Specifically, it could use the list of IPC servers and clients in the IPC object to locate the destination of a message and then use xmms_ipc_client_msg_write to actually send it.
The xmms_ipc_client_St struct should be extended with a new field, "id", which represents the client's unique id. This id could easily be generated by the server when the client connects, and would be used to identify clients when sending messages.
This XMMS_IPC_OBJECT_COURIER would have two methods: xmms_courier_send_message and xmms_courier_reply, which are mostly compatible with nesciens' last sketch for the client-side.
xmms_courier_send_message (xmms_ipc_client_t *client, int dest, int expect_reply, xmmsv_t *payload, uint32_cookie)
Formats a c2c message in the form of a dict:
"sender" : client->id "dest" : dest "payload" : payload "expect_reply" : expect_reply
If the message expects a reply (i.e., expect_reply == 1), generates a unique id for the message, stores it in the dict and records this message as pending in the pool of pending messages. It is sufficient to record the message, sender and destination ids, along with the cookie. Might make sense to record id = 0 in the c2c message does not accept replies.
Then looks up the destination client's xmms_ipc_client_t using its id in the list of clients kept by the IPC object, and uses xmms_ipc_client_msg_write to actually send the message to the destination client, using the cookie stored in its xmms_ipc_client_t (i.e., the one it uses for receiving the broadcast with messages).
xmms_courier_reply (xmms_ipc_client_t *client, int msg_id, int expect_reply, xmmsv_t *payload, uint32 cookie)
Looks for the destination using the provided msg_id in the pool of pending messages (and, once found, removes the entry corresponding to this id). Checks if the original message was really sent to the client which is trying to answer.
Proceeds similarly to send_message, with one fundamental difference: this time the ipc message sent should contain the cookie that was stored in the pool of pending messages instead of the one in the destination's xmms_ipc_client_t.
In order to delegate replies to clients that call service methods until the service actually responds, thus associating a xmmsc_result_t to the result of the method call, the courrier object would need to be special-cased in process_msg in ipc.c, maybe like XMMS_IPC_OBJECT_SIGNAL currently is. The ipc message's cookie is passed along to both methods in process_msg so that it can be used to send back replies to clients.
- The current c2c notifiers aren't really extensible when it comes to adding new metadata to c2c messages.
Maybe we want a c2c-extended version with a dict instead of extra arguments (too)?
That will be easier if we want to extend the metadata passed around. (For instance a flag that several replies can be expected, for some kind of c2c-broadcast.)
How about deserializing c2c messages into structs and handing those to the callback? It's extensible and doesn't make clients parse the messages: xmmsc_c2c_message_t
- Maybe versions of c2c_send and c2c_reply that unref the payload, so the client can just pass the return value of the xmmsv_*_new to them without intermediary variables?