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

PROTON-2748: Raw connection async close fix and tests. #402

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

cliffjansen
Copy link
Contributor

No description provided.

Copy link
Member

@astitcher astitcher left a 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.

c/src/proactor/epoll_raw_connection.c Outdated Show resolved Hide resolved
Copy link
Member

@astitcher astitcher left a 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) {
Copy link
Member

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.

Copy link
Contributor Author

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.

Comment on lines -322 to -323
if (!e || pn_event_type(e) == PN_RAW_CONNECTION_DISCONNECTED)
rc->batch_empty = true;
Copy link
Member

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.

Copy link
Contributor Author

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) {
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Comment on lines 427 to 428
pni_raw_async_disconnect(&rc->raw_connection);
} else if (events & EPOLLHUP) {
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Comment on lines 330 to 332
static pn_event_t *pni_raw_batch_peek(pn_event_batch_t *batch) {
return pni_epoll_raw_batch_next(batch, true);
}
Copy link
Member

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()?

Copy link
Contributor Author

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.
Copy link
Member

Choose a reason for hiding this comment

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

typo

Copy link
Contributor Author

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);
}

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 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.

Copy link
Contributor Author

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);
Copy link
Member

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.

@astitcher
Copy link
Member

@cliffjansen I really like how this has turned out now. Are you finished or are there more changes due to adding new tests?

@cliffjansen
Copy link
Contributor Author

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.

@astitcher
Copy link
Member

The new commits lgtm

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