依赖注入,stuartsierra中的循环依赖/监视组件的组件

时间:2017-04-18 09:12:52

标签: dependency-injection clojure health-monitoring

我的StuartSierra/component组件存在循环依赖问题。

我有:

  • 一个webServer组件
  • 一个Healthcheck组件,它定期遍历系统以查找实现healthcheck协议的组件。这是监测的一部分。
  • 实现healthcheck协议的数据库,作业队列连接等组件。

WebServer也实现了healthcheck协议。

我有一个函数,给定一个系统返回compojure路由,允许查询存储在healthcheck组件中的最后一个healthckeck状态。

所以我现在有了这个循环依赖,在这个函数中有一个变通方法,即将系统作为var并在需要时取消引用它,而不是将其作为值。

但这很不方便,并且意味着在启动期间检查会报告一段不正确的值。

有没有办法在组件中处理这种生命周期?或者这里有设计缺陷吗?

1 个答案:

答案 0 :(得分:1)

与循环依赖关系一样,您可以通过将一些麻烦的功能提取到一个或多个其他组件中来解决此问题,从而打破循环。一种方法是重命名" webserver"组件到" app handler"或者什么,并且它包括除基于监控的路线之外的所有路线。它实际上不应该启动Web服务器本身,只是提供一个可用于启动服务器的环处理程序函数。

此时,添加"监控"当然,依赖于app处理程序的组件很容易,并且它可以为整个系统生成健康状态(除了我们尚未获得的Web服务器本身)。

最后一个新的"网络服务器"组件可以获取应用程序处理程序提供的路由,并启动一个Web服务器,将它们与另外的/monitoring处理程序或其他任何组合在一起,这会询问监视组件的工作情况。如果你愿意,你可以在这里添加关于网络服务器本身的状态,尽管如果网络服务器不健康,你会在很多情况下无法通过网络服务器本身说出任何有用的信息。

总结组件依赖关系图的图表:

  

http://svgur.com/i/1GY.svg

显然Stack Overflow不支持嵌入SVG文件,所以我不得不在外部托管它。

您可以采用的完全不同的方法是让监视组件完全没有依赖关系,而是基于插件/注册。每个其他系统都依赖于监控系统,并且作为其启动的一部分,它将通过提供一些回调来回答问题"我有多健康,并注册自己?"

在某些方面,我认为这违背了Component的精神,因为你向依赖图添加了隐式向后边,但我认为这是一种合理的方法。它的更多证据就是古老的谚语"计算机科学中的所有问题都可以通过另一个层次的间接来解决。在C和这样的语言中,这通常意味着另一级指针;在函数式语言中,它通常意味着用函数替换值。