-
Notifications
You must be signed in to change notification settings - Fork 211
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
PROTON-2748: Raw connection async close fix and tests. #402
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't compile for me - and the compiler found a definite error in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bunch of things to think about here. Probably nothing that significant, but these might make it a bit easier for me to understand and follow the code.
I wonder if the filename raw_wake_test should be raw_connection_wake_test for consistency?
@@ -304,7 +305,7 @@ void pn_raw_connection_write_close(pn_raw_connection_t *rc) { | |||
pni_raw_write_close(rc); | |||
} | |||
|
|||
static pn_event_t *pni_raw_batch_next(pn_event_batch_t *batch) { | |||
static pn_event_t *pni_epoll_raw_batch_next(pn_event_batch_t *batch, bool peek_only) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename this: pni_raw_batch_next_common() or pni_raw_batch_next_or_peek():
Ading epoll to the name doesn't communicate anything useful about the purpose of this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pni_raw_batch_has_events() was used as suggested elsewhere.
if (!e || pn_event_type(e) == PN_RAW_CONNECTION_DISCONNECTED) | ||
rc->batch_empty = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where did this logic go? It seems no longer to be anywhere. Is it no longer needed? Specifically the check against the disconnected event.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic was solely there to identify edge cases where the epoll-specific code could not be sure if the state machine was up to date. In which case a non-application call to pni_raw_batch_next() would update the state machine but a resulting event would have to be put back into the collector.
The new pni_raw_batch_has_events() updates the state machine and has no side effects to the event stream, so the check for batch_empty is no longer needed.
if (events & EPOLLIN) pni_raw_read(&rc->raw_connection, fd, rcv, set_error); | ||
if (events & EPOLLOUT) pni_raw_write(&rc->raw_connection, fd, snd, set_error); | ||
rc->batch_empty = false; | ||
if (rc->connected) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need this condition (which is why it wasn't present previously) - if you get here without returning already you must be connected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
pni_raw_async_disconnect(&rc->raw_connection); | ||
} else if (events & EPOLLHUP) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The style of this function is early return. So please change this to have a return with no 'else if' if that is possible - I don't understand enough of this logic to see if you could get EPOLLERR as well as EPOLLIN, EPOLLOUT or EPOLLRDHUP at the same time with a useful action of reading or writing, but it seems unlikely to me.
And if this change is possible it lowers the cognitive load (and indentation) of the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
static pn_event_t *pni_raw_batch_peek(pn_event_batch_t *batch) { | ||
return pni_epoll_raw_batch_next(batch, true); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure you want to introduce a peek operation? This is only ever used to find out whether there is an outstanding event so why not just introduce an operation bool pni_raw_batch_has_events()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
// If we're closed and we've sent the disconnect then close | ||
pni_raw_finalize(raw); | ||
praw_connection_cleanup(rc); | ||
// Must poll for iO. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
pn_event_t *pni_raw_event_peek(pn_raw_connection_t *conn) { | ||
return pni_get_next_raw_event(conn, true); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would refactor pni_raw_event_next differently:
- Refactor the event generating if chain into a separate function that is called by ...next() and ...peek() (or if you follow my earlier suggestion ...has_events()
- Then wrap that with pn_collector_next/peek logic.
Just in case it's not clear the do ... while (true) is a bit of a red herring and somewhat bad coding on my part in that there is never more than one effective pass through the loop. There can be 2 but that if only if there was no initial event. So it make more sense really to separate out the event generating logic.
Hope that is clear enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done with has_events().
@@ -134,9 +134,11 @@ void pni_raw_write_close(pn_raw_connection_t *conn); | |||
void pni_raw_read(pn_raw_connection_t *conn, int sock, long (*recv)(int, void*, size_t), void (*set_error)(pn_raw_connection_t *, const char *, int)); | |||
void pni_raw_write(pn_raw_connection_t *conn, int sock, long (*send)(int, const void*, size_t), void (*set_error)(pn_raw_connection_t *, const char *, int)); | |||
void pni_raw_process_shutdown(pn_raw_connection_t *conn, int sock, int (*shutdown_rd)(int), int (*shutdown_wr)(int)); | |||
void pni_raw_async_disconnect(pn_raw_connection_t *conn); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this is a new event going to the raw connection state machine maybe there should be a new test for this event in raw_connection_test.
@cliffjansen I really like how this has turned out now. Are you finished or are there more changes due to adding new tests? |
I will check in the changes so far to get some extended CI going. Todo: additional tests as suggested and rename the test. I will leave the pull and JIRA open until they are done and will incorporate additional suggestions. I propose changing raw_wake_test to raw_connection_proactor_test to reflect it tests the functionality of the proactor implementation of raw connections whereas the existing raw_connection_test tests the proactor-independent bits of the internal/external API without a running proactor. |
The new commits lgtm |
No description provided.