RH属性的最佳实践

时间:2015-01-23 15:03:46

标签: redhawksdr

关于RH块的最佳实践,我有几个问题。

首先,redhawksdr github中是否有一个块作为一个例子,所有RH块应该遵循如何完成的事情?我在redhawksdr gitub网站上看到很多块,每个块似乎都以不同的方式执行日志记录和错误处理等操作。有些尚未删除默认生成的日志记录语句。

我们应该记录所有房产变更吗?使用1.10中的新属性回调,可以很容易地记录从旧到新的转换。如果是这样,我应该记录哪些日志记录级别(例如DEBUG或INFO)?别人在做什么以及为什么?

如果尝试设置属性,但无法应用新设置,是否应该抛出异常并忽略新设置?我们是否应该记录错误或警告并确保没有异常从我们的组件传播出去?这些消息应该是什么日志级别?我在github上看到一些块打印到cerr并且什么都不做。在实践中已经使用RH的人使用的推荐方法是什么?

一般情况下,我们是否应该创建块,以便属性更改是完全发生的事务,或者块的内部状态根本不会发生更改。在redhawksdr的github上的一些块中,它们将尝试更改属性并打印错误,但此时状态尚未明确定义。这一般是可以接受的,还是我们应该在这方面使一切事务完全安全?

1 个答案:

答案 0 :(得分:2)

当涉及到组件开发的最佳实践时,REDHAWK倾向于强调自由而不是整合。考虑到不同的用例,开发了不同的组件,并且有许多不同的方法来解决REDHAWK中的问题。这说明了您在某些组件之间看到的一些差异。

是否有推荐的REDHAWK组件可用作标准: 总的来说,GitHub上发布的REDHAWK组件试图用于两个目的。它们是用于处理的有用组件的集合。而且,它们是一组其他人可以效仿的例子。

很难选出一个组件作为唯一最好的例子,因为它们每个都有不同的目的,并采用了不同的方法。 HardLimit组件可能是最简单的示例,因此理解开发组件的基础知识会很有帮助。 fastfilter组件更复杂,它演示了一些更高级的概念,例如锁定和属性回调,以及重写配置以验证相互依赖的属性。

记录最佳做法: 简而言之,在开发REDHAWK组件时,最好在system.out / system.error中使用Logging。

更广泛地说,日志记录在REDHAWK中可能是一个难题。确实没有严格的规则。通常,任何“通常”发生的事情(例如 - 在服务功能中接收数据包)都应该在DEBUG或TRACE中记录。任何超出“正常”操作的操作都应记录为WARN。 ERROR用于组件不应具有的意外情况。在决定使用哪个级别时,请随意遵循log4cxx或log4j的指导原则。

一种常见的日志记录做法是在输入Q刷新时记录警告,这在许多组件上都可以看到。 TRACE中的基类实现日志属性更改,因此组件开发人员无需在更高级别自行记录所有单个属性更改。但是,如果他们选择这样做,他们可能会选择在属性Callback中记录重要属性(可能DEBUG或INFO是适当的级别)。

无效的属性配置: 在REDHAWK中,当组件配置不正确时,将抛出无效配置。由开发人员决定他们的组件如何处理有关更新其内部状态的无效属性配置。这是组件开发人员的设计决策。如果要回滚无效属性,则属性回调会提供属性验证机制。对于float属性“myProp”,代码可能如下所示:

void propChanged(const float *oldValue, const float *newValue)
{
    bool valid(true);
    // add custom logic to check the value here and set valid to false
    // For example, here is a check to ensure the property is postive:
    if (value<0)
        valid =false;
    if (!valid)
    {
        LOG_WARN(comp_i, "myProp received invalid value"<< *newValue);
        myProp=*oldValue; //reset property to original value 
        throw std::exception();
        //this causes base class to throw invalidConfiguration
    }

    //any additional logic for updating the component after the change goes here
}

在某些情况下,您可能不希望将值重置为oldValue,您可能希望将其设置为默认值(例如 - 将负数设置为0)。这些都由开发人员自行决定。在某些情况下,您可能希望将值舍入到特定容差(例如舍入到最接近的.001)并且根本不抛出无效配置。

线程安全属性更改: 属性配置期间的线程并发非常重要,应该考虑所有属性。基类使用互斥锁“propertySetAccess”在配置和查询期间锁定,这提供了一种锁定和保持ANY属性不会同时更改为其他处理的简单方法。但是,这不是推荐的行为,因为处理属性并发有不同的方法,并且在大多数情况下锁定所有属性配置更新都是过度的。另外,值得注意的是,当以这种方式锁定时,在属性回调期间保持锁定,因此回调不需要重新获取锁定。

对于某些属性,如果值在处理数据包的过程中发生变化,则无关紧要。一个很好的例子是HardLimit中的“upper_limit”和“lower_limit”。开发人员认为这些值改变中间处理并不重要,并且该组件没有属性并发。

对于某些属性,例如fastfilter中的“fftSize”,设计师决定他们从不希望这个值改变中间处理。因此,他们有一个单独的互斥锁“filterLock_”,以防止这种情况发生。

另一种选择,而不是锁定,是制作属性的本地副本,然后在整个处理过程中使用该副本。在循环中间更改属性时,新值将应用于下一个服务函数。