Hello, one important piece of feedback from the daemon-mode: Project structure discussion is that we need a policy to remove old code again.
So I thought I should write up a bit about the infrastructure and versioning support of the daemon-mode branch I am working on. Basic Assumptions: ================= These are kind of hardcoded into the implementation and hard to change: * There will always be 1 client talking to a server. * Client/Server communicate using JSON messages Implementation Overview: ====================== Basically "daemon-mode" is implemented in the cmServer class. That class uses libuv to receive requests from a client application and to react on those requests. There is nothing that stops the cmServer from also signalling the client about state changes (e.g. CMakeLists.txt files being changed on disc), but that is not implemented at this time. In the constructor of cmServer you can define an arbitrary number of cmProtocolVersion objects, each with a different version number (major/minor numbers). On first connect the cmServer will present the list of supported protocol versions to the client and the client has to pick one of the supported versions. The server will call Activate() (do your initialization here;-) on the cmProtocolVersion object with the selected version number. >From that point on the cmProtocolVersion object is responsible for all further interactions with the client. The cmServer will turn all incoming messages into cmServerRequest objects and pass those to the selected cmProtocolVersion's Process(...) method. This method will return a cmServerResponse object (which can be created from the cmServerRequest), which the cmServer will send on to the client. Proposed Versioning: =================== The protocol version should start at version 1.0. Any time new functionality is made available to daemon-mode, the minor version number will be incremented. This includes new commands becoming available as well as existing commands returning new keys in addition to sending all the old keys. Any time a incompatible change (e.g. removal of functionality, restructuring of responses to requests, etc.) is made, the major version is incremented and the minor is reset to 0. This includes removing existing commands or changing the semantics/return types of keys returned in response to any existing command. If there was already a matching version bump, then there is no need to do another till after the next release of cmake made. So two new functionalities in one development cycle: Still only increase the minor number by one. Requesting Protocol Versions: ========================= Let's assume we are writing a client for cmake-daemon as shipped in cmake 4.2.4. At that time in the future the protocol version for the cmake-daemon is at version 1.4 and that is what we test our application with. Our client should then request daemon mode to use protocol version 1.4 if available. If that is not available, then it should just request the highest minor number for version 1 and use that. That *should* be compatible with version 1.4. If there is no more protocol version 1.x supported the client should abort or at least warn and continue with a higher major version number. Implementing new Protocol Versions: ============================== * minor version bumps: Add a new cmServerProtocol class. Have its Process(...) method implement the new functionality and then forward to an instance of the previous version. The sloppy approach would be to implement the the new functionality in the previous versions class and just bump its number:-) * major version bumps: At that point I would copy the existing code of the previous version into a new cmServerProtocol class and then clean it up. Then implement the changes in the new class. Deprecating old Protocol Versions: ============================ I would remove all the code for one major protocol version in one go. That should be fairly straight forward to do (and the reason why I suggested to just copy the code into a new major version of the protocol) and should have little potential for damage. In general I would suggest keeping old major versions around for at least three cmake releases, but I would not put hard rules here: If some old major version does not cost maintenance, then I'd suggest keeping it longer. On the other hand, if some changes require a major cmake version bump (e.g. changing the cmake language in incompatible ways, etc.) so that major user interaction is required during an update, then I would also dump all old protocol versions immediately. Such fundamental changes will probably also reflect deeply in the cmake internal structure, which will also reflect in the daemon-mode protocol. I do not think it makes sense to invest heavily into compatibility to old daemon-mode clients in such an event. What do you think? Does this make sense? Best Regards, Tobias -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers