-
Notifications
You must be signed in to change notification settings - Fork 1.4k
BufferingTargetWrapper - Avoid Timer starvation when SlidingTimeout = true #3412
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
BufferingTargetWrapper - Avoid Timer starvation when SlidingTimeout = true #3412
Conversation
ea623a6 to
90521f3
Compare
Codecov Report
@@ Coverage Diff @@
## release/4.6.4 #3412 +/- ##
==============================================
+ Coverage 80% 80% +<1%
==============================================
Files 358 358
Lines 28373 28384 +11
Branches 3785 3789 +4
==============================================
+ Hits 22750 22770 +20
+ Misses 4537 4523 -14
- Partials 1086 1091 +5 |
|
Thanks! |
|
It's not just "when SlidingTimeout=true" - this happens a lot when the target is slow (say, temporarily overwhelmed by writes), and If I understand things correctly, things are like this - let's say that FlushTimeout is 1000ms, and it takes 5000ms to actually write a buffer; also we have a 1001-items buffer, and we write one log event per ms. What happens both before & after this PR is:
|
|
Think buffer-full-situtation is not handled by timer. But is handled by the calling thread. The timer is "only" scheduled when having inserted the first item with SlidingTimout=false
|
|
@virgilp If possible then please tell how this PR will fail to solve the problem with hanging timers.
|
|
What I was trying to say is that I don't think this solves in any meaningful way the problem of "slow target" (or intermittently-slow target). So, before this PR, with I guess what I'm saying is that I don't think this PR changes/ improves anything. As long as there's a single |
|
@virgilp Nice of you to explain the issue before this PR.
More interested in input about what is wrong with this PR? And why?
We are trying to prevent timer threads getting stuck for a long time. Because they keep firing but each of them get stuck.
Any issues with SlidingTimeout always postponing on dripping activity is a known behavior. Not gonna be fixed. And is unrelated to this issue.
|
|
What I'm saying is that I don't think they keep firing - do they? Can you reproduce it? I don't understand what's the scenario where more than two timer threads get stuck. (I apparently suck at explaining things - in retrospect I shouldn't have buried this in the last paragraph) |
You have these two statements:
I can only agree on the obvious that a blocking operation will block the calling timer. Regarding your second statement, then you can run the following code: System.Threading.Timer timer = new System.Threading.Timer((s) => System.Threading.Thread.Sleep(2000));
for (int i = 0; i < 1000; ++i)
{
timer.Change(5, System.Threading.Timeout.Infinite);
System.Threading.Thread.Sleep(10);
}You will see that you suddenly have more than 2 timer-thread being stuck in the Thread.Sleep-operation. Imagine the following example with SlidingTimeout = true and a LogEvent is written every second with a FlushTimeout of 500ms: Now with this PR the following will happen: So I guess the 500 msec lock-timeout is too long. Instead it should be 100 ms (or half the FlushTimeout depending which is less): |
90521f3 to
071b128
Compare
Is this sarcasm? |
I guess so. Trying to understand the input for this PR, but it is a shotgun of information. I like input to be concise (and maybe even proven) without needing to dig for the needle. |
I prefer a "be nice" policy ;) (and feel free to let me know when I violate that policy) |
|
@virgilp Do you think this PR is an improvement? Do you have any suggestions what we have to change? The latter is also a bit unclear to me. Thanks! |
|
@snakefoot ok, but this assumes flush timeout < frequency of logging (i.e. I write an event every second, but flush the buffer every half second). I was assuming that "flush timeout" < "logging frequency" is such an unrealistic case that it basically never happens (I'm pretty sure that's not what happened in #3410 - there's a constant stream of logevents in that system). @304NotModified I think it's not a significant improvement/ i.e. doesn't improve things in real-life situations; in particular, I was looking to see if this PR fixes the issue we encountered, and I don't think it does. I was not criticizing the PR as much as trying to validate my understanding that this will not fix the referenced issue. For the suggestions... I do have some, but it's not a small change, and it's best explained by opening a PR when I have time to do it :). |
|
Still very confusing. Your two previous statements said there is no issue to be fixed because there will only be 2 timer threads blocked no matter what.
Now you are saying that you are also experiencing some kind of issue with blocking timer threads.
It would make things a lot easier if you shared:
- how you configured your buffering Wrappers
- how your logging pattern (frequency and amount and flush-latency)
- some kind of description of the problem state you see (thread listing, callstacks, etc)
Please create a new issue with all of this. Instead of piggy backing on this PR
|
|
Ok. |
|
@snakefoot should we merge this PR or abandoned it? |
|
@304NotModified I think it should be merged. It implements what @rusanu requested in the initial issue. And solves the issue with timer-threads building up in different situations. But maybe not the situation @virgilp is seeing. |
|
@virgilp NLog 4.6.4 has been released: https://www.nuget.org/packages/NLog/4.6.4 Please try testing the new version. If you still have issue with timer-threads building up, then please create a new issue. |
See also #3410