当您有多个服务器版本时,如何构建自动更新桌面应用程序,并在每个服务器版本之间进行重大更改?
How can I structure auto updating a desktop application when you have multiple server versions, with breaking changes between each server version?
结构:
Server - Desktop Application
我想在桌面应用程序上有一个自动更新机制。这可以通过 Squirel.Windows 之类的东西来实现,并且超出了这个问题的范围。请注意,DesktopApp 针对不同的 OS(Mac 和 Windows)有多种变体。
问题是,服务器并不总是最新版本。例如:
Server.v1 - DesktopApp.v1
Server.v2 - DesktopApp.v1
Server.v1 和 Server.v2 具有不同的行为和重大更改。如何以可管理的方式构建 DesktopApp 上的自动更新?
服务器版本也可以突然转到不同的版本,例如从 Server.v2 到 Server.v1。这是我们无法控制的。
注意:服务器不符合 semver,因此次要版本号可能会有重大更改
建议 1)
像这样使 DesktopApp 向后兼容
if(serverVersion == Server.v1) {
MetodOfLogicThatWorksOnV1();
};
if(serverVersion >= Server.v2) {
MetodOfLogicThatWorksOnV2();
};
现在我可以随心所欲地自由更新 DesktopApp.v1,而且它将完全向后兼容。桌面应用程序的用户都使用最新版本。
担心:一段时间后会导致逻辑非常复杂,容易出错
建议 2)
让 DesktopApp 更新机制知道何时应该降级
if(serverVersion == Server.v1) {
DesktopApp.SelfUpdater.Update(v1);
};
if(serverVersion >= Server.v2) {
DesktopApp.SelfUpdater.Update(latest);
};
现在,用户将获得不同的 DesktopApp 版本,具体取决于他们所连接的服务器版本。
担心:用户将不得不 update/downgrade 取决于版本。维护这个更新逻辑会变得复杂。现在必须对 DesktopApp.v1 和 DesktopApp.v2
进行错误修复
建议 3)
为每个服务器版本创建 1 个 DesktopApp
if(serverVersion != clientVersion) {
DesktopApp.SelfUpdater.Update(serverVersion);
};
这意味着我知道服务器的版本将始终针对我使用的 DesktopApp 的确切版本进行设计
苦恼:DesktopApp需要制作的版本非常多,需要部署bug fix到很多版本。
问题:
当您有多个服务器版本并且每个服务器版本之间都有重大更改时,我如何构造自动更新桌面应用程序?
如果您的组织同时控制服务器和桌面应用程序,最好的答案是围绕服务器开发进行纪律处分。您应该明确表示,对服务器协议的频繁不兼容更改会增加应用程序团队的工作量。 Pact 是我(轻微)使用过的一种工具,它可以让你 "record" 客户端的请求和预期的响应,然后 运行 那些作为针对服务器的测试用例,无需完整的端到端测试设置。
如果您控制服务器,另一个更好的选择是让服务器支持旧协议版本。我不使用 docker API directly much, but its API reference 列出所有过去的版本并且有一个更改列表,旧的和新的客户端和服务器可以互操作。 Docker 还实现了您的 "option 1",如果需要,客户端代码可以降级到较旧的协议版本。
否则,从用户的角度来看,你的选项1是唯一好的。经常想要破坏您的工作流程并重新安装自身(选项 2)的应用程序很快就会变得烦人,但如果应用程序在服务器升级时随机停止工作(选项 3),情况会更糟。还有一些常见的部署模式,如 "canary builds" 可以导致旧服务器和新服务器同时 运行,为了支持这些,客户端应用程序需要能够与两者一起工作。
您可以使用定义操作的接口和 "traditional" 工厂方法来实例化正确的实现,而不是开关:
IMyOperations GetMyOperationsFactory(){
var version = Server.GetVersion()
if (version == 1) return new MyOperationsV1();
if (version == 2) return new MyOperationsV2();
throw new InvalidOperationException("Server version " + version + " not supported");
}
那么您至少可以隔离特定于版本的行为。
如果有益,添加传统的面向对象(继承等等)。
结构:
Server - Desktop Application
我想在桌面应用程序上有一个自动更新机制。这可以通过 Squirel.Windows 之类的东西来实现,并且超出了这个问题的范围。请注意,DesktopApp 针对不同的 OS(Mac 和 Windows)有多种变体。
问题是,服务器并不总是最新版本。例如:
Server.v1 - DesktopApp.v1
Server.v2 - DesktopApp.v1
Server.v1 和 Server.v2 具有不同的行为和重大更改。如何以可管理的方式构建 DesktopApp 上的自动更新?
服务器版本也可以突然转到不同的版本,例如从 Server.v2 到 Server.v1。这是我们无法控制的。
注意:服务器不符合 semver,因此次要版本号可能会有重大更改
建议 1)
像这样使 DesktopApp 向后兼容
if(serverVersion == Server.v1) {
MetodOfLogicThatWorksOnV1();
};
if(serverVersion >= Server.v2) {
MetodOfLogicThatWorksOnV2();
};
现在我可以随心所欲地自由更新 DesktopApp.v1,而且它将完全向后兼容。桌面应用程序的用户都使用最新版本。
担心:一段时间后会导致逻辑非常复杂,容易出错
建议 2)
让 DesktopApp 更新机制知道何时应该降级
if(serverVersion == Server.v1) {
DesktopApp.SelfUpdater.Update(v1);
};
if(serverVersion >= Server.v2) {
DesktopApp.SelfUpdater.Update(latest);
};
现在,用户将获得不同的 DesktopApp 版本,具体取决于他们所连接的服务器版本。
担心:用户将不得不 update/downgrade 取决于版本。维护这个更新逻辑会变得复杂。现在必须对 DesktopApp.v1 和 DesktopApp.v2
进行错误修复建议 3)
为每个服务器版本创建 1 个 DesktopApp
if(serverVersion != clientVersion) {
DesktopApp.SelfUpdater.Update(serverVersion);
};
这意味着我知道服务器的版本将始终针对我使用的 DesktopApp 的确切版本进行设计
苦恼:DesktopApp需要制作的版本非常多,需要部署bug fix到很多版本。
问题:
当您有多个服务器版本并且每个服务器版本之间都有重大更改时,我如何构造自动更新桌面应用程序?
如果您的组织同时控制服务器和桌面应用程序,最好的答案是围绕服务器开发进行纪律处分。您应该明确表示,对服务器协议的频繁不兼容更改会增加应用程序团队的工作量。 Pact 是我(轻微)使用过的一种工具,它可以让你 "record" 客户端的请求和预期的响应,然后 运行 那些作为针对服务器的测试用例,无需完整的端到端测试设置。
如果您控制服务器,另一个更好的选择是让服务器支持旧协议版本。我不使用 docker API directly much, but its API reference 列出所有过去的版本并且有一个更改列表,旧的和新的客户端和服务器可以互操作。 Docker 还实现了您的 "option 1",如果需要,客户端代码可以降级到较旧的协议版本。
否则,从用户的角度来看,你的选项1是唯一好的。经常想要破坏您的工作流程并重新安装自身(选项 2)的应用程序很快就会变得烦人,但如果应用程序在服务器升级时随机停止工作(选项 3),情况会更糟。还有一些常见的部署模式,如 "canary builds" 可以导致旧服务器和新服务器同时 运行,为了支持这些,客户端应用程序需要能够与两者一起工作。
您可以使用定义操作的接口和 "traditional" 工厂方法来实例化正确的实现,而不是开关:
IMyOperations GetMyOperationsFactory(){
var version = Server.GetVersion()
if (version == 1) return new MyOperationsV1();
if (version == 2) return new MyOperationsV2();
throw new InvalidOperationException("Server version " + version + " not supported");
}
那么您至少可以隔离特定于版本的行为。 如果有益,添加传统的面向对象(继承等等)。