Skip to content

Cleanup: check activity of Http2Stream by ActivityCop#6494

Merged
masaori335 merged 1 commit intoapache:masterfrom
masaori335:activity-cop-2
Mar 13, 2020
Merged

Cleanup: check activity of Http2Stream by ActivityCop#6494
masaori335 merged 1 commit intoapache:masterfrom
masaori335:activity-cop-2

Conversation

@masaori335
Copy link
Copy Markdown
Contributor

Introduce NetTimeout and ActivityCop to cleanup Http2Stream.

For now, Http2Stream is 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.

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.

@masaori335 masaori335 added this to the 10.0.0 milestone Mar 10, 2020
@masaori335 masaori335 self-assigned this Mar 10, 2020
Copy link
Copy Markdown
Member

@maskit maskit left a comment

Choose a reason for hiding this comment

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

The interface doesn't look great to me.

Comment thread iocore/net/NetTimeout.h
}

if (t->is_inactive_timeout_expired(now)) {
t->handleEvent(VC_EVENT_INACTIVITY_TIMEOUT, e);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What information in e is needed?

Comment thread iocore/net/NetTimeout.h Outdated
active_event->cancel();
active_event = nullptr;
}
return _timeout.is_active_timeout_expired(now);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Which part in ActivityCop requires VConnection interface?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Comment thread iocore/net/NetTimeout.h
}

inline bool
NetTimeout::is_inactive_timeout_expired(ink_hrtime now)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The main motivation is hiding private members as much as possible. Maybe I did too much.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member

@maskit maskit Mar 11, 2020

Choose a reason for hiding this comment

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

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
shinrich previously approved these changes Mar 10, 2020
Copy link
Copy Markdown
Member

@shinrich shinrich left a comment

Choose a reason for hiding this comment

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

I agree that moving the interval-based activity checking to the session level from the stream level makes sense.

@masaori335
Copy link
Copy Markdown
Contributor Author

Pushed new commit. Including headers & some function of NetTimeout was tweaked a bit.

@maskit
Copy link
Copy Markdown
Member

maskit commented Mar 11, 2020

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.

Copy link
Copy Markdown
Member

@scw00 scw00 left a comment

Choose a reason for hiding this comment

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

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.

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.

5 participants