Cleanup: check activity of Http2Stream by ActivityCop#6494
Cleanup: check activity of Http2Stream by ActivityCop#6494masaori335 merged 1 commit intoapache:masterfrom
Conversation
bb9f4e3 to
3ac0f62
Compare
maskit
left a comment
There was a problem hiding this comment.
The interface doesn't look great to me.
| } | ||
|
|
||
| if (t->is_inactive_timeout_expired(now)) { | ||
| t->handleEvent(VC_EVENT_INACTIVITY_TIMEOUT, e); |
There was a problem hiding this comment.
What information in e is needed?
| active_event->cancel(); | ||
| active_event = nullptr; | ||
| } | ||
| return _timeout.is_active_timeout_expired(now); |
There was a problem hiding this comment.
What benefit do we get from delegating this?
If Http2Stream inherited NetTimeout, we would not need to use template and the check that requires C++20. And the interface of NetTimeout would be clearer. Currently it has functions that are indirectly called from ActivityCop and functions that are called from Http2Stream to update internal state. These two kinds of function would be separated as public functions for ActivityCop and protected functions for Http2Stream. Then ActivityCop would be able to call is_active_timeout_expired directly and we would not need this function here.
There was a problem hiding this comment.
To make ActivityCop without Template, you need a class that inherits VConnection & NetTimeout. When Http2Stream inherits that class, you'll see the diamond problem. Also, when you try to make ActivityCop based InactivityCop, your class hierarchy becomes more complicated.
You can solve the complicated class hierarchy. But using Template is easier than that.
There was a problem hiding this comment.
Which part in ActivityCop requires VConnection interface?
There was a problem hiding this comment.
If you are talking about VC_EVENTs, it's not checked on your code neither. And technically the class doesn't have to be a VConnection. Continuation satisfies the requirement for handling events.
If that part is going to be a problem, you could add on_timeout() to the interface. It's more general and you would be able to use it for any timeout.
There was a problem hiding this comment.
Yeh, it's Continuation.
Assuming you're saying NetTimeout doesn't need to inherit the Continuation by declaring int on_timeout(int event, Event *e) as a pure virtual function. It will work, but it allows derived class to implement it anyhow. Some will call Continuation::handleEvent(int, void*) correctly, but some will not.
I prefer to restrict how events are passed & handled.
There was a problem hiding this comment.
Calling handleEvent would not ensure that timeout is going to be handled correctly. You still need to implement the handler correctly. In this sense, having handleEvent is not enough, and I'd call it a halfway restriction. on_timeout() would be more robust and flexible interface because it does not depend on other mechanisms. Changes against how we handle timeout on VConnection does not affect ActivityCop's job, and like I said on the comment above, you can use AC for other timeouts.
Also, having on_timeout and having handleEvent at somewhere are not exclusive. You could implement on_timeout to (Net)VConnection if you wanted to make sure handleEvent is going to be called at least.
| } | ||
|
|
||
| inline bool | ||
| NetTimeout::is_inactive_timeout_expired(ink_hrtime now) |
There was a problem hiding this comment.
Why is this check done by NetTimeout itself?
The interaction between ActivityCop and NetTimeout looks weird.
AC: Hey, it's March 1st. Is your visa expired?
NT: Yes, it is.
AC: Your visa is expired.
NT: (I know, I told you.)
I'd do
AC: Hey, when is your visa expire date?
NT: It's March 1st.
AC: Your visa is expired.
There was a problem hiding this comment.
The main motivation is hiding private members as much as possible. Maybe I did too much.
There was a problem hiding this comment.
I revisit this but it looks like what AC needs to know is timeout is expired or not.
We see a similar code & relations for checking a connection is closed or not.
There was a problem hiding this comment.
Just asking expiration time is enough to know whether a stream is timed out. I don't see any needs to make two function calls if NetTimeout already know it's timed out. I'd move the check logic to AC and make NetTimeout to a simple data structure (with accessors).
shinrich
left a comment
There was a problem hiding this comment.
I agree that moving the interval-based activity checking to the session level from the stream level makes sense.
3ac0f62 to
6e20007
Compare
|
Pushed new commit. Including headers & some function of NetTimeout was tweaked a bit. |
|
I think it could be better, but I don't see blockers and it's better than current code. I'm not going to stop it but no +1 from me at the moment. |
scw00
left a comment
There was a problem hiding this comment.
Looks good to me. After this change , Timeout Event : H2Stream = 1 : n. I'd like to launch this change , and change it again after we fully abstract the Timer interface.
Introduce
NetTimeoutandActivityCopto cleanupHttp2Stream.For now,
Http2Streamis checking the activity and inactivity by itself. This is working but giving little pressure to the EventSystem and complexity of code.In the long term, HTTP/3 & QUIC need a similar timeout mechanism (probably,
QUICStreamVConnection). ActivityCop is made as reusable easily.trafficserver/proxy/http2/Http2Stream.cc
Line 828 in deea85a
trafficserver/proxy/http2/Http2Stream.cc
Line 839 in deea85a
Out of scope
NetTimeout/ActivityCop is very similar to NetEvent/InactiviyCop which observes the activity and inactivity of UnixNetVConnection. We can make it NetTimeout/ActivityCop base, but it needs a bunch of refactoring of the iocore layer. I leave it for now.