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

Disable scheduleSend when onMessage callback is running #144

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

Conversation

nemoshlag
Copy link
Member

@nemoshlag nemoshlag commented Nov 7, 2022

Resolves #88

@nemoshlag nemoshlag requested a review from a team November 7, 2022 15:30
@codecov
Copy link

codecov bot commented Nov 7, 2022

Codecov Report

Patch coverage: 93.18% and project coverage change: +0.90 🎉

Comparison is base (efddaa2) 76.11% compared to head (ad3a057) 77.02%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #144      +/-   ##
==========================================
+ Coverage   76.11%   77.02%   +0.90%     
==========================================
  Files          24       24              
  Lines        1834     1893      +59     
==========================================
+ Hits         1396     1458      +62     
+ Misses        326      324       -2     
+ Partials      112      111       -1     
Impacted Files Coverage Δ
client/types/callbacks.go 66.66% <ø> (ø)
server/httpconnection.go 33.33% <0.00%> (ø)
client/internal/mockserver.go 82.35% <85.71%> (+0.31%) ⬆️
server/serverimpl.go 58.92% <94.73%> (+0.37%) ⬆️
client/httpclient.go 95.00% <100.00%> (+0.26%) ⬆️
client/internal/clientcommon.go 79.80% <100.00%> (ø)
client/internal/httpsender.go 72.22% <100.00%> (+1.25%) ⬆️
client/internal/receivedprocessor.go 85.03% <100.00%> (+0.74%) ⬆️
client/internal/sender.go 93.33% <100.00%> (+5.33%) ⬆️
server/callbacks.go 68.18% <100.00%> (-4.55%) ⬇️
... and 1 more

... and 1 file with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@nemoshlag nemoshlag changed the title fix(ScheduleSend): disable scheduleSend when onMessage callback is ha… WIP fix(ScheduleSend): disable scheduleSend when onMessage callback is ha… Nov 8, 2022
@nemoshlag nemoshlag changed the title WIP fix(ScheduleSend): disable scheduleSend when onMessage callback is ha… Disable scheduleSend when onMessage callback is running Nov 8, 2022
client/internal/receivedprocessor.go Outdated Show resolved Hide resolved
func (r *receivedProcessor) onMessage(ctx context.Context, msgData *types.MessageData) {
r.senderCommon.DisableScheduleSend()
r.callbacks.OnMessage(ctx, msgData)
r.senderCommon.EnableScheduleSend()
Copy link
Member

Choose a reason for hiding this comment

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

Nit: move this up and use defer so that if the code becomes more complicated in the future there is no chance that EnableScheduleSend() is not executed on some of the return paths.

client/internal/receivedprocessor.go Outdated Show resolved Hide resolved
client/internal/receivedprocessor.go Outdated Show resolved Hide resolved
client/internal/receivedprocessor.go Show resolved Hide resolved
client/internal/sender.go Outdated Show resolved Hide resolved
client/internal/sender.go Outdated Show resolved Hide resolved
Copy link
Member

@tigrannajaryan tigrannajaryan left a comment

Choose a reason for hiding this comment

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

Code LGTM, I just left a few comments about improving the comments (pun not intended).

r.callbacks.OnMessage(ctx, msgData)

r.sender.EnableScheduleSend()
Copy link
Member

Choose a reason for hiding this comment

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

Can we add a comment to EnableScheduleSend definition that calling EnableScheduleSend when it is already enabled is allowed? (since we do it twice here).

@@ -31,6 +38,12 @@ type SenderCommon struct {
// Indicates that there is a pending message to send.
hasPendingMessage chan struct{}

// Indicates onMessage callback is running
Copy link
Member

Choose a reason for hiding this comment

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

Nit: the comment doesn't match what the field name implies. It would be best to reword it to something like "Set to non-zero to indicate that the message sending is disabled"

}
}

// ScheduleSend signals to HTTPSender that the message in NextMessage struct
// is now ready to be sent. If there is no pending message (e.g. the NextMessage was
// already sent and "pending" flag is reset) then no message will be sent.
func (h *SenderCommon) ScheduleSend() {
if h.IsSendingDisabled() {
// onMessage callback is running, ScheduleSend() will rerun after it is done
Copy link
Member

Choose a reason for hiding this comment

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

Same here, comment doesn't match what the code and func names imply.

atomic.StoreInt32(&h.isSendingDisabled, 1)
}

// EnableScheduleSend re-enables ScheduleSend and checks if it was called during onMessage callback
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I would refrain from mentioning onMessage here. It is not a concern of SenderCommon.

@tigrannajaryan
Copy link
Member

tigrannajaryan commented Nov 24, 2022

Technically the change in this PR can be the cause of the test failure:

go test -race ./...
--- FAIL: TestUpdatePackages (5.10s)
    --- FAIL: TestUpdatePackages/error_on_callback (5.03s)
        --- FAIL: TestUpdatePackages/error_on_callback/ws (5.01s)
            mockserver.go:250: Time out expecting a message from the client: compressed PackageStatuses

This happened because the server did not receive a message client was supposed to send. I haven't seen this error before and it is not reproducible on the latest main.

I can't see the problem by reading the code but maybe there is some race that I am not seeing that causes a ScheduleSend to missfire?

Can you try go test -run TestUpdatePackages/error_on_callback/ws -race -count 1000 on this change and see if it is possible to reproduce?

select {
case <-h.registerScheduleSend:
h.ScheduleSend()
case <-time.Tick(100 * time.Millisecond):
Copy link
Member

Choose a reason for hiding this comment

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

Unclear why this is necessary.

Copy link
Member Author

Choose a reason for hiding this comment

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

This fixed my sync issue. Several tests failed when testing with -race -count 1000 flags. Honestly, I don't fully understand why but it seems that the default case was selected over reading from the registerScheduleSend channel even when it (should have) held an unread message.

Copy link
Member

Choose a reason for hiding this comment

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

Failing tests may be indicating a real problem. The current code (before this PR) does not fail the tests.

The addition of the second case that waits a time without explaining why it fixes the problem is not an acceptable code change. We need precise explanation what the problem is and why this is the correct fix for it.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've removed this bypass and tests are looking stable at the moment with the updated branch. Still, I don't have a smoking gun regarding the sync issue, but it could have been resolved due to recent commits. Would appreciate your opinion on whether or not this should stay blocked or more changes are needed

Copy link
Member

@tigrannajaryan tigrannajaryan left a comment

Choose a reason for hiding this comment

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

Blocking until we have clarity around failing tests.

@nemoshlag nemoshlag changed the title Disable scheduleSend when onMessage callback is running [WIP] Disable scheduleSend when onMessage callback is running Dec 13, 2022
@nemoshlag nemoshlag marked this pull request as draft December 13, 2022 09:33
@nemoshlag nemoshlag changed the title [WIP] Disable scheduleSend when onMessage callback is running Disable scheduleSend when onMessage callback is running Dec 14, 2022
@nemoshlag nemoshlag marked this pull request as ready for review December 14, 2022 14:04
@srikanthccv
Copy link
Member

@nemoshlag, any chance you can rebase and resolve the conflicts?

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

Successfully merging this pull request may close these issues.

Delay ScheduleSend if OnMessage is in progress
3 participants