Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic Leader ID timeout selection #9032

Closed
wants to merge 25 commits into from

Conversation

mmb-davidsmith
Copy link
Contributor

This commit adds an initial implementation of the proposed change to how the Leader Id propagation trickle timer is managed. It implements the algorithm proposed in SPEC-1167 for automatic management of the maximum advertisement interval with a modification to set the lower bound on the calculated value to 12.

…how the Leader Id propagation trickle timer is managed. It implements the algorithm proposed in SPEC-1167 for automatic management of the maximum advertisement interval with a modification to set the lower bound on the calculated value to 12.
…mer header as it was not implemented or used.
@size-report
Copy link

size-report bot commented May 8, 2023

Size Report of OpenThread

Merging #9032 into main(2f99599).

name branch text data bss total
ot-cli-ftd_1.1 main 470760 760 64220 535740
#9032 470952 760 64220 535932
+/- +192 0 0 +192
ot-cli-mtd_1.1 main 389672 760 54004 444436
#9032 389672 760 54004 444436
+/- 0 0 0 0
ot-ncp-ftd_1.1 main 445172 760 59440 505372
#9032 445364 760 59440 505564
+/- +192 0 0 +192
ot-ncp-mtd_1.1 main 369044 760 49232 419036
#9032 369044 760 49232 419036
+/- 0 0 0 0
ot-rcp_1.1 main 60396 564 19964 80924
#9032 60396 564 19964 80924
+/- 0 0 0 0
libopenthread-cli-ftd.a_1.1 main 52599 0 8003 60602
#9032 52599 0 8003 60602
+/- 0 0 0 0
libopenthread-cli-mtd.a_1.1 main 43379 0 7995 51374
#9032 43379 0 7995 51374
+/- 0 0 0 0
libopenthread-ftd.a_1.1 main 245391 4 38774 284169
#9032 245575 4 38774 284353
+/- +184 0 0 +184
libopenthread-mtd.a_1.1 main 180282 4 28566 208852
#9032 180382 4 28566 208952
+/- +100 0 0 +100
libopenthread-ncp-ftd.a_1.1 main 31539 0 5852 37391
#9032 31539 0 5852 37391
+/- 0 0 0 0
libopenthread-ncp-mtd.a_1.1 main 26541 0 5852 32393
#9032 26541 0 5852 32393
+/- 0 0 0 0
libopenthread-rcp.a_1.1 main 9028 0 4988 14016
#9032 9028 0 4988 14016
+/- 0 0 0 0
libopenthread-radio.a_1.1 main 18287 0 174 18461
#9032 18287 0 174 18461
+/- 0 0 0 0
ot-cli-ftd_1.3 main 493264 760 73716 567740
#9032 493456 760 73716 567932
+/- +192 0 0 +192
ot-cli-mtd_1.3 main 404952 760 55244 460956
#9032 404952 760 55244 460956
+/- 0 0 0 0
ot-ncp-ftd_1.3 main 466588 760 68928 536276
#9032 466780 760 68928 536468
+/- +192 0 0 +192
ot-ncp-mtd_1.3 main 382812 760 50464 434036
#9032 382812 760 50464 434036
+/- 0 0 0 0
ot-rcp_1.3 main 62776 564 20532 83872
#9032 62776 564 20532 83872
+/- 0 0 0 0
libopenthread-cli-ftd.a_1.3 main 55495 0 8003 63498
#9032 55495 0 8003 63498
+/- 0 0 0 0
libopenthread-cli-mtd.a_1.3 main 45681 0 7995 53676
#9032 45681 0 7995 53676
+/- 0 0 0 0
libopenthread-ftd.a_1.3 main 263976 4 47726 311706
#9032 264160 4 47726 311890
+/- +184 0 0 +184
libopenthread-mtd.a_1.3 main 191985 4 29262 221251
#9032 192085 4 29262 221351
+/- +100 0 0 +100
libopenthread-ncp-ftd.a_1.3 main 33377 0 5852 39229
#9032 33377 0 5852 39229
+/- 0 0 0 0
libopenthread-ncp-mtd.a_1.3 main 27907 0 5852 33759
#9032 27907 0 5852 33759
+/- 0 0 0 0
libopenthread-rcp.a_1.3 main 9194 0 4988 14182
#9032 9194 0 4988 14182
+/- 0 0 0 0
libopenthread-radio.a_1.3 main 19204 0 206 19410
#9032 19204 0 206 19410
+/- 0 0 0 0

@codecov
Copy link

codecov bot commented May 8, 2023

Codecov Report

Merging #9032 (798526f) into main (2f99599) will increase coverage by 0.00%.
The diff coverage is 90.76%.

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #9032    +/-   ##
========================================
  Coverage   82.37%   82.38%            
========================================
  Files         546      547     +1     
  Lines       74599    74781   +182     
========================================
+ Hits        61451    61607   +156     
- Misses      13148    13174    +26     
Impacted Files Coverage Δ
src/core/common/trickle_timer.hpp 100.00% <ø> (ø)
src/core/thread/mle_router.hpp 87.50% <ø> (ø)
src/core/thread/mle_types.hpp 100.00% <ø> (ø)
src/core/common/trickle_timer.cpp 91.96% <82.85%> (-4.14%) ⬇️
tests/unit/test_trickle_timer.cpp 91.85% <91.85%> (ø)
src/core/thread/mle_router.cpp 84.24% <100.00%> (+0.13%) ⬆️
src/core/thread/router_table.cpp 93.99% <100.00%> (+0.01%) ⬆️

... and 31 files with indirect coverage changes

Copy link
Member

@jwhui jwhui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mmb-davidsmith , thanks for submitting this. Overall, this looks great. I commented on a number of minor nits.

src/core/common/trickle_timer.hpp Outdated Show resolved Hide resolved
src/core/common/trickle_timer.hpp Outdated Show resolved Hide resolved
src/core/common/trickle_timer.hpp Outdated Show resolved Hide resolved
src/core/thread/mle_router.cpp Outdated Show resolved Hide resolved
src/core/thread/mle_router.cpp Outdated Show resolved Hide resolved
src/core/common/trickle_timer.cpp Outdated Show resolved Hide resolved
src/core/common/trickle_timer.cpp Show resolved Hide resolved
mmb-davidsmith and others added 3 commits May 8, 2023 13:34
…fically covers the following:

- converts `TrickleTimer::GetLastTimerStart` to return a value rather than taking a parameter for return
- makes `TrickleTimer::GetLastTimerStart` private
- removes the unused `TrickleTimer::GetIntervalMin` and `TrickleTimer::GetIntervalMax`
- adjusts the mechanism for iterating over the router table
- moves to use `OT_MIN` and `OT_MAX` for the calculation of the `advertiseIntervalMax` value.
@mmb-davidsmith
Copy link
Contributor Author

@jwhui, in terms of the issues with the pretty action, I can't run the script locally as I don't have the correct version of clang. The things it's complaining about are not in the section of the file which I modified, so I'm not quite sure what fixes need to be made. What's it's proposing seems a little off.

The markdown lint check failed to pull a URL which loads when I go manually, so not sure if there's an adjustment needed there for retries or something in the script.

@jwhui
Copy link
Member

jwhui commented May 8, 2023

@jwhui, in terms of the issues with the pretty action, I can't run the script locally as I don't have the correct version of clang. The things it's complaining about are not in the section of the file which I modified, so I'm not quite sure what fixes need to be made. What's it's proposing seems a little off.

It looks like the added preprocessor statements are tripping up clang-format. We'll want to update it to follow the other OpenThread configs or completely remove it, which should avoid the clang-format issue.

@mmb-davidsmith
Copy link
Contributor Author

I've remove the preprocessor statement but it still seems to be failing. From what I can tell it's now something related to a missing javascript library.

@jwhui
Copy link
Member

jwhui commented May 8, 2023

I've remove the preprocessor statement but it still seems to be failing. From what I can tell it's now something related to a missing javascript library.

The current pretty failures appears to be the same as #8382. I'll kick it again when the job completes.

Copy link
Member

@abtink abtink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mmb-davidsmith.
Some suggestions below.

src/core/thread/mle_router.cpp Outdated Show resolved Hide resolved
src/core/thread/mle_router.cpp Outdated Show resolved Hide resolved
}

uint32_t advertiseIntervalMax = OT_MIN(kAdvertiseIntervalMax, (neighbors + 1) * 4);
advertiseIntervalMax = OT_MAX(12, advertiseIntervalMax);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to define constants for 12 and 4?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll define these in src/core/thread/mle_types.hpp

src/core/thread/mle_router.cpp Outdated Show resolved Hide resolved
src/core/common/trickle_timer.hpp Outdated Show resolved Hide resolved
src/core/common/trickle_timer.cpp Show resolved Hide resolved
src/core/common/trickle_timer.cpp Outdated Show resolved Hide resolved
src/core/common/trickle_timer.cpp Outdated Show resolved Hide resolved
mTimeInInterval = aIntervalMax;
}

TimerMilli::FireAt(newFireTime);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fully agree that if current mInterval is longer than new aIntervalMax we want to emulate as if we used the new aIntervalMax when we scheduled the current interval. But I feel we may need to consider more cases here. Let me work out some cases (using a diagram) and will post here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I am not mistaken, (under mMode == kModeTrickle) if we have mPhase == kBeforeRandomTime and mTimeInInterval < aIntervalMax then the new calculated newFireTime may be incorrect.

An example:

    |<------mInterval = 20 sec --------------------------->|
    |                                         |            | 
    |<------- new aIntervalMax = 15 sec ----->|            |
    |                              |          |            |
    |<-- mTimeInInterval=11 sec -->|          |            |
    |                              |                       | 
                 ^
                 Now 
  • mInterval = 20 sec, mTimeInInterval = 11 sec, new aIntervalMax = 15 sec
  • Since mTimeInInterval < aIntervalMax we keep mTimeInInterval as is (will remain 11).
  • We set the mInterval to 15.
  • Since we are in mPhase == kBeforeRandomTime, GetLastTimerStart() will return the start of current trickle interval
  • newFireTime will point to 15 sec after the start of trickle interval.
  • When the timer fires, we are still in kBeforeRandomTime phase so we do the following:
        case kBeforeRandomTime:
            // We reached end of random `mTimeInInterval` (aka `t`)
            // within the current interval. Trickle timer invokes
            // handler if and only if the counter is less than the
            // redundancy constant.

            mPhase = kAfterRandomTime;
            TimerMilli::Start(mInterval - mTimeInInterval);
            VerifyOrExit(mCounter < mRedundancyConstant);
            break;

Which then start the timer for remaining time to end of current interval calculated as mInterval - mTimeInInterval = 15 - 11 = 4, so the overall interval becomes 15 + 4 = 19 second long which is not what we want.

I think in this case,

  • The timer is already scheduled to fire at mTimeInInterval after start (or time t) which we keep the same, so we don't need to change the timer firetime.
  • We only need to update the mInterval to aIntervalMax so that after timer fires, we apply the shorter interval.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried to capture the possible cases and list them below. Once we're aligned on the desired behaviour, I'll ensure that my code is correctly implementing it.

  1. aIntervalMax >= mInterval - doesn't matter timer type, do nothing except update mIntervalMax and let it affect the next run

    (question: what happens if aIntervalMax is selected such that the currently running timer will fire at a time less than aIntervalMax / 2 in Trickle mode. I think technically we're out of spec, but I would be tempted to just leave it to resolve after the next timer run)

  2. aIntervalMax < mInterval - plain timer mode - just reschedule to aIntervalMax

  3. aIntervalMax < mInterval - trickle mode

    1. in kBeforeRandomTime
      1. aIntervalMax < mTimeInInterval - need to set mInterval = aIntervalMax & re-schedule mTimeInInterval to fire at aIntervalMax (from start of interval)
      2. aIntervalMax >= mTimeInInterval - need to set mInterval = aIntervalMax
    2. in kAfterRandomTime
      1. aIntervalMax < mTimeInInterval - not possible as mTimeInInterval is the transition point to kAfterRandomTime
      2. aIntervalMax >= mTimeInInterval - need to set mInterval = aIntervalMax & re-schedule timer to fire at aIntervalMax (from start of interval)

Please let me know if you agree with my logic above or if I should make updates.

Copy link
Member

@abtink abtink May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Looks good. 👍

I think ii.a is possible, like this:

    |<------ mInterval = 30--------------------------->|
    |<-- mTimeInInterval=18 sec -->|       ^           |                    
    |                              |       ^           |                 
    |<-- aMaxInterval = 10 ->|     |       ^           |
    |                                      ^           |
                                           Now

But I think we need to do the same in this case as in ii.b change mInterval and re-schedule to fire aIntervalMax from last interval start (which will then fire immediately)

Copy link
Member

@abtink abtink May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may be able to combine the cases:

  • The only case that seems to be different is i.b.

  • In all other cases we can do the same set of things:

    • Change mInterval = aIntervalMax
    • Change mTimeInInterval = aIntervalMax (it only matters in i.a case, ignored in other cases and harmless to change)
    • And re-schedule timer to fire aIntervalMax from the last start interval.
    • And we keep mPhase as is.

Does this make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the diagram for ii.a, that makes it clear that it is possible. As you say, taking the same approach as ii.b should work.

I think that even in i.b we need to set mInterval = aIntervalMax (according to the logic above)

So with all of this worked through, I think the only change necessary is to update GetLastTimerStart() to GetLastIntervalStart()

- `TrickleTimer::GetLastTimerStart` and `TrickleTImer::SetIntervalMax` handle kModePlainTimer now
- in `TrickleTimer::GetLastTimerStart` the variable `aStartTime` is renamed to `startTime` as it's no longer a parameter
- documentation for the private method is removed
- `MleRouter::RecalculateAdvertiseInterval`:
  - removes a superfluous scope
  - declares all variables at the start of the function
  - uses existing function `RouterTable::GetNeighborCount` to count the number of neighbor routers
  - uses the `Min` and `Max` helper functions which are more modern than the `OT_MIN` and `OT_MAX` functions
  - uses named constants for the multiplier and lower bound
- adds constant definitions for the multiplier and lower bound

Outstanding Items:
- the `TrickleTimer::SetIntervalMax` will need to have adjustments done based on the conclusion of the discussion on the draft PR.
- depending on outcome of `TrickleTimer::SetIntervalMax`, the `TrickleTimer::GetLastTimerStart` may be renamed to `TrickleTimer::GetLastIntervalStart` and updated to always return the start of the interval vs the specific timer within the interval.
@mmb-davidsmith
Copy link
Contributor Author

Are there any resources about how to add new unit tests / integration tests. Ultimately I would like to figure out how to add some unit tests for the trickle timer changes and some simulator tests for the overall functionality.

Am I correct in my understanding that the unit tests would need to be a part of this PR, and then for the simulator tests, I would need to add the necessary functions in https://github.com/openthread/ot-ns/tree/main/pylibs/stress_tests and then reference them in a PR in this repo which updated the matrix on the workflow?

@jwhui
Copy link
Member

jwhui commented May 10, 2023

Are there any resources about how to add new unit tests / integration tests. Ultimately I would like to figure out how to add some unit tests for the trickle timer changes and some simulator tests for the overall functionality.

We don't have existing unit tests for the trickle timer. The closest we have is the timer unit tests. In short, we basically implement a mock platform and test the behavior the the specific component.

For functional tests, one option is to follow the scripts in tests/scripts/thread-cert. This would allow you to include the tests in this PR.

We generally prefer to have tests included with the PR, but I admit there are many PRs where we do not enforce this.

…sed in the pull request. The primary change is that `GetLastTimerStart` needed to be changed to `GetLastIntervalStart` to ensure all calculations were being started from the beginning of trickle interval instead of the specific phase.
@mmb-davidsmith
Copy link
Contributor Author

@jwhui - I'm just trying to write some unit tests for the trickle timer and wanted to understand this bit of code from TrickleTimer::StartNewInterval

        // Select a random point in the interval taken from the range [I/2, I).
        halfInterval = mInterval / 2;
        mTimeInInterval =
            (halfInterval < mInterval) ? Random::NonCrypto::GetUint32InRange(halfInterval, mInterval) : halfInterval;

My understanding of C math is that the only time that this would ever select halfInterval is if mInterval is 0. Given we assert that mIntervalMin > 0 in TrickleTimer::Start, and mInterval is set to a random number which is lower bounded by mIntervalMin in TrickleTimer::StartNewInterval and in TrickleTimer::HandleTimer it specifically sets the value to 1 if it is zero, I'm not sure this check would ever evaluate to false unless the TrickleTimer::StartNewInterval was called before the TrickleTimer::Start function. Given it's a private method, I'm not even sure that's possible.

Should this be simplified?

@jwhui
Copy link
Member

jwhui commented May 11, 2023

Should this be simplified?

@mmb-davidsmith , thanks for pointing this out. I reviewed the code as well and I agree with your conclusions.

I think this might have been the result of avoiding a div-by-0 warning from static analyzer on this line of code:

return (aMin + (GetUint32() % (aMax - aMin)));

But I think the OT_ASSERT immediately above should be sufficient to avoid this warning. Feel free to suggest the simplification.

@mmb-davidsmith
Copy link
Contributor Author

@jwhui / @abtink - I've made a new file for implementing my trickle timer tests. Unfortunately I'm getting issues with the pretty tool that I'm not understanding. Specifically it's saying

You must pass the clang tidy checks before submitting a pull request

/home/runner/work/openthread/openthread/tests/unit/test_trickle_timer.cpp:116:14: warning: method 'GetFiredCounter' can be made const [readability-make-member-function-const]
    uint32_t GetFiredCounter(void) { return mFiredCounter; }
             ^
                                   const
const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type );
                                                            ^~~~~~
Error: Process completed with exit code 1.

I have tried putting const both in front of and after the uint32_t type specifier and am still failing the pretty check. As noted earlier, I can't run the pretty check locally as the version of clang available to me is not the one used here.

@abtink
Copy link
Member

abtink commented May 11, 2023

I have tried putting const both in front of and after the uint32_t type specifier and am still failing the pretty check. As noted earlier, I can't run the pretty check locally as the version of clang available to me is not the one used here.

I think tool is suggesting for the method to be declared as const:

uint32_t GetFiredCounter(void) const { return mFiredCounter; }

@mmb-davidsmith
Copy link
Contributor Author

I have tried putting const both in front of and after the uint32_t type specifier and am still failing the pretty check. As noted earlier, I can't run the pretty check locally as the version of clang available to me is not the one used here.

I think tool is suggesting for the method to be declared as const:

uint32_t GetFiredCounter(void) const { return mFiredCounter; }

Thanks. C++ isn't a language I use regularly so I'm a little less familiar with some of the constructs.

@mmb-davidsmith
Copy link
Contributor Author

@jwhui Is it expected that the Unit / upload-coverage step/check is failing? Looking at the logs, it's possible there's some token that can't be accessed, but I'm not 100% sure.

@jwhui
Copy link
Member

jwhui commented May 12, 2023

@jwhui Is it expected that the Unit / upload-coverage step/check is failing? Looking at the logs, it's possible there's some token that can't be accessed, but I'm not 100% sure.

This occurs when codecov API limits are exceeded. Waiting a bit and re-running the job typically resolves the check.

@jwhui jwhui requested a review from abtink May 17, 2023 04:24
@@ -169,6 +177,8 @@ class TrickleTimer : public TimerMilli
void FireAtIfEarlier(void) {}
void GetFireTime(void) {}

TimeMilli GetLastIntervalStart(void);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declare as const?

Suggested change
TimeMilli GetLastIntervalStart(void);
TimeMilli GetLastIntervalStart(void) const;

@@ -53,6 +53,78 @@ TrickleTimer::TrickleTimer(Instance &aInstance, Handler aHandler)
{
}

TimeMilli TrickleTimer::GetLastIntervalStart(void)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TimeMilli TrickleTimer::GetLastIntervalStart(void)
TimeMilli TrickleTimer::GetLastIntervalStart(void) const

Comment on lines +94 to +95
TimeMilli newFireTime = GetLastIntervalStart();
newFireTime += aIntervalMax;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new line after variable declarations?

Suggested change
TimeMilli newFireTime = GetLastIntervalStart();
newFireTime += aIntervalMax;
TimeMilli newFireTime = GetLastIntervalStart();
newFireTime += aIntervalMax;

mTimeInInterval = aIntervalMax;
}

TimerMilli::FireAt(newFireTime);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in i.b case we should not re-schedule the timer.

Comment on lines +115 to +121
mInterval = aIntervalMax;
if (mTimeInInterval > aIntervalMax)
{
mTimeInInterval = aIntervalMax;
}

TimerMilli::FireAt(newFireTime);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is what I would suggest:

  • In all cases we do mInterval = aIntervalMax;.
  • The if() is for i.b case where we exit (and won't change the timer).
  • In all other cases, we mTimeInInterval = aIntervalMax (only matters for 1.a case but harmless to do in other cases), and re-schedule the timer.
Suggested change
mInterval = aIntervalMax;
if (mTimeInInterval > aIntervalMax)
{
mTimeInInterval = aIntervalMax;
}
TimerMilli::FireAt(newFireTime);
mInterval = aIntervalMax;
if ((mPhase == kBeforeRandomTime)) && (aIntervalMax >= mTimeInInterval))
{
ExitNow();
}
mTimeInInterval = aIntervalMax;
TimerMilli::FireAt(newFireTime);

VerifyOrExit(IsRouterOrLeader());

neighbors = Get<RouterTable>().GetNeighborCount();
advertiseIntervalMax = Min(kAdvertiseIntervalMax, (neighbors + 1) * kNeighborAdvertiseIntervalMultiplier);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use Get<RouterTable>().GetNeighborCount() directly here (and not define a local neighbors variable)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would also avoid assigning the uint8 return value into the uint32 first, which isn't needed.
Note that there was discussion on only using the Router neighbors that have Link Quality >= 2 for this count.

@@ -0,0 +1,314 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Copyright (c) 2016, The OpenThread Authors.
* Copyright (c) 2023, The OpenThread Authors.

@@ -494,6 +494,11 @@ class MleRouter : public Mle
mDiscoveryRequestCallback.Set(aCallback, aContext);
}

/**
* This method recalculates the MLE Advertisement Trickle timer interval based on SPEC-1167 algorithm.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the main branch now all the wording on "This method" and "This function" have been removed.

Also the description is incomplete, because the function also starts the Trickle timer in case it wasn't yet running.
That seems important enough to also have it stated in the function's name.
E.g. RecalculateAdvertiseIntervalAndStartAdvertising()

@@ -881,6 +881,8 @@ void RouterTable::HandleTableChanged(void)
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
Get<Utils::HistoryTracker>().RecordRouterTableChange();
#endif

Get<Mle::MleRouter>().RecalculateAdvertiseInterval();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suppose that the Adv Trickle timer was not running (for whatever reason - it seems to be possible, looking at the code) and an event comes in that the router table is changed. Is it really intended here to start the Trickle timer now? (which is a side effect of RecalculateAdvertiseInterval() )
If yes, why wasn't it started here in the original code?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took care of this in new PR -> #9307.

@abtink
Copy link
Member

abtink commented Jul 21, 2023

Submitted

@mmb-davidsmith
Copy link
Contributor Author

Closing as @abtink has submitted a PR which supersedes this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants