<div dir="ltr"><div>I wanted to ask about integrating the changes I worked on (regarding exposing the remote protocol) and also about replication (which still needs some work, but it's already working).</div><div><br></div><div><div>The remote protocol and replication parts are actually needed so indexation clusters work. Please, if you have any thoughts or ideas about how to get this ball rolling as soon as possible, let me know. I'm very interested in getting those in before the next major release, so I'd love to hear if you have any suggestions or anything so I can work them out.</div></div><div><br></div><div><br></div><div>I also want/need to boost the overall performance in Xapiand, by having a way of making all readers in the same process (different threads) read the same things the writer reads (even before commit)... I do have some some ideas about it (using some sort of "subscription" scheme)... but this is a topic for other thread.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 1, 2015 at 5:03 PM, Germán M. Bravo <span dir="ltr"><<a href="mailto:german.mb@gmail.com" target="_blank">german.mb@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>I have been working in the abstraction of the remote protocol to separate it from the server and the connection.</div><div>The purpose of this is I need to use the Xapian remote protocol in a server we are working on (named Xapiand:</div><div><a href="https://github.com/Kronuz/Xapiand" target="_blank">https://github.com/Kronuz/Xapiand</a>) which is similar to some extent to the `xapian-tcpsrv` in that it also serves</div><div>databases remotely through TCP, using the binary protocol. What is different about it is that it can serve any</div><div>number of databases using an event driven mechanism for receiving and attending clients. Additionally, it also</div><div>serves clients using a custom HTTP protocol which is JSON based and RESTful.</div><div><br></div><div>I have the following commits in my Xapian fork at <a href="https://github.com/Kronuz/xapian/commits/master" target="_blank">https://github.com/Kronuz/xapian/commits/master</a>:</div><div><br></div><div><br></div><div><div>1. Remote protocol with support for selection of database directory</div><div>-------------------------------------------------------------------</div><div><br></div><div>If the user requests to open a remote database server, it can optionally require</div><div>the remote backend to tell the server what database it wants to open, if the</div><div>remote server is configured as a server without a default directory</div><div>(xapian-tcpsrv remains to always have a default directory at the moment).</div><div><br></div><div>The binary protocol was changed in the way that a new command can be sent to</div><div>the server (MSG_SELECT) in case the server tells the client no default directory</div><div>is selected, the server then reacts to this command by opening and selecting the</div><div>requested database as the active database.</div><div><br></div><div><br></div><div>2. Split msg_query and msg_getmset</div><div>----------------------------------</div><div><br></div><div>Originally, `msg_query()` handled two commands by the client: `MSG_QUERY` and</div><div>also `MSG_GETMSET` (which was marked as "used during a conversation"). This</div><div>changes this and makes it so `msg_query()` returns even when the client hasn't</div><div>yet sent a `MSG_GETMSET`, but instead only keeping the current satate of the</div><div>query in the `MatchState` struct and setting the expected `required_type` for</div><div>the next command.</div><div><br></div><div>The purpose of this is that an event based remote protocol server might still</div><div>not yet have the `MSG_GETMSET` message from the client as a response, and it'd</div><div>be bad practice (or catastrophic) to block the thread while the message arrives.</div><div>This blocking (if any) should be handled further up, by the event loop.</div><div><br></div><div><br></div><div>3. Method run() split in two: run() and run_one()</div><div>-------------------------------------------------</div><div><br></div><div>The method run() calls run_one() in a loop, but we don't always want this</div><div>behavior. The reason is, again, event based messaging might decide to start</div><div>attending other clients on the same thread without blocking, thus an infinite</div><div>while for these type of servers is not desired.</div><div><br></div><div><br></div><div>4. Abstract RemoteProtocol class added</div><div>--------------------------------------</div><div>RemoteServer extends from abstract RemoteProtocol, and only implements a few</div><div>members needed by the protocol. This effectively separates the protocol from the</div><div>connection and the server.</div><div><br></div><div>RemoteProtocol with virtual abstract methods for:</div><div><br></div><div>* get_message - Receives a new message (waiting when needed).</div><div>* send_message - Sends a message to the client.</div><div>* get_db - Reserves a database when the class needs to use it.</div><div>* release_db - Releases the database when the class is not using it.</div><div>* select_db - It's called when the protocol needs to select a new database to work on.</div><div>* shutdown - It's called when the protocol requires to shutdown.</div><div><br></div><div>Each command in the RemoteProtocol now do a two additional things:</div><div><br></div><div>1. Use get_db() to reserve and get a read-only or writable database.</div><div>2. Relese the reserved database using release_db()</div><div><br></div><div>Implements RemoteProtocol on the RemoteServer:</div><div><br></div><div>* get_db - Always returns the same database object (db or wdb)</div><div>* release_db - Does nothing in this server (database is never released).</div><div>* get_message and send_message - Call RemoteConnection methods.</div><div><br></div><div><br></div><div>5. RemoteProtocol implementation moved to remoteprotocol.cc</div><div>-----------------------------------------------------------</div><div><br></div><div>Added `remoteprotocol.cc` with the implementation of `RemoteProtocol` and header</div><div>file remoteprotocol.h with added `RemoteProtocol` abstract class definition</div><div>moved to `include/xapian/remoteprotocol.h`</div><div><br></div><div>The reason for this is other projects might want to use the `RemoteProtocol`</div><div>class for implementing a custom remote server. Xapiand is one of these projects.</div><div>(<a href="https://github.com/Kronuz/Xapiand" target="_blank">https://github.com/Kronuz/Xapiand</a>)</div></div><div><br></div><div><br></div><div>Please, any comments and feedback would be appreciated.</div><div><br></div><div>German M. Bravo (Kronuz)</div><div><br></div></div>
</blockquote></div><br></div>