Task #1914
closedGeneralize retransmission action (currently in BestRoute v.2 strategy)
0%
Description
Processing of retransmitted Interests is general operation that should be (optionally) added to any strategy.
Therefore, it should be abstracted to a "pluggable" strategy module.
Option 1: using templated inheritance (just to give an idea, I don't really like this one)¶
For example, we can define
template<typename Strategy>
class RetxInterestsProcessor : public Strategy
{
public:
virtual bool
afterReceiveInterest(const Face& inFace,
const Interest& interest,
shared_ptr<fib::Entry> fibEntry,
shared_ptr<pit::Entry> pitEntry);
};
And then in all strategies ensure that we call parent's afterReceiveInterest
and stop processing if the return value is false.
NOTE: this proposal includes change in Strategy interface: all virtual methods will return bool instead of void to indicate that further actions in child class method need to be aborted.
Drawbacks: code "bloat", all combinations of strategies and pluggable modules need to be enumerated at compile time
Option 2: Define new module interface and chain processing of modules¶
We can define a new strategy-like interface for strategy processing modules:
class StrategyProcessor : noncopyable
{
public:
virtual bool
afterReceiveInterest(const Face& inFace,
const Interest& interest,
shared_ptr<fib::Entry> fibEntry,
shared_ptr<pit::Entry> pitEntry) =0;
virtual bool
beforeSatisfyPendingInterest(shared_ptr<pit::Entry> pitEntry,
const Face& inFace, const Data& data);
virtual bool
beforeExpirePendingInterest(shared_ptr<pit::Entry> pitEntry);
private:
Strategy* m_strategy; // or shared_ptr, or weak_ptr
};
Note that the Interface is the same with exception that return value are boolean, instead of void.
We also would amend Strategy
interface to include list of strategy processors, which can be instantiated either during compile time or during strategy installation time (if we implement strategy options).
After that, we can implement RetxInterestsProcessor
class as in option 1, but it will not need to be templated anymore.
Inside each strategy (or we can try to do some renaming and abstracting these actions into the strategy itself) we invoke the corresponding method of the processor from the strategy processor list before executing actual strategy actions. If at any point, a processor returns false, further processing needs to be aborted.
Technically, the strategy itself may be changed to be just one of the strategy processors and Strategy
class would become just a container that will be instantiated with a specific list of processors to implement specific strategy.
(Not directly related: The same strategy processor approach could be taken to implement NDNLP segmenting)