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

Handle expired clients in server.loadClients(). #341

Merged
merged 3 commits into from
Dec 12, 2023
Merged

Handle expired clients in server.loadClients(). #341

merged 3 commits into from
Dec 12, 2023

Conversation

werbenhu
Copy link
Member

@werbenhu werbenhu commented Dec 7, 2023

I encountered a problem similar to #339 . If the broker is forcefully shut down, and clients have the clean flag set, after restarting the broker and calling loadClients(), these expired clients will be retained indefinitely if the client is no longer connected.

It is necessary to handle expired clients in server.loadClients(). Call OnDisconnect() to trigger the hook for clearing persistent clients. Also, if a client has expired, there is no need to retain this client in server.Clients.

@coveralls
Copy link

Pull Request Test Coverage Report for Build 7128618616

  • 9 of 9 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.001%) to 98.913%

Totals Coverage Status
Change from base Build 7076132597: 0.001%
Covered Lines: 5462
Relevant Lines: 5522

💛 - Coveralls

Copy link
Collaborator

@mochi-co mochi-co left a comment

Choose a reason for hiding this comment

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

Makes sense to me, and a good solution. For me, it's approved! Thank you for finding this @werbenhu!

@x20080406
Copy link
Contributor

I think this change make the logic become too difficult. The loaded client should be invoke the Stop method only.

With this commit, there will get some issues.

expire := (cl.Properties.ProtocolVersion == 5 && cl.Properties.Props.SessionExpiryInterval == 0) || (cl.Properties.ProtocolVersion < 5 && cl.Properties.Clean)
s.hooks.OnDisconnect(cl, packets.ErrServerShuttingDown, expire)
if expire {
	cl.ClearInflights()  // inflights not recoverd
	s.UnsubscribeClient(cl)  // subscription not recoverd
        // there couldn't find clients after loadClients in the `readStore` method,
} else {
	s.Clients.Add(cl)
}

@werbenhu
Copy link
Member Author

werbenhu commented Dec 11, 2023

@x20080406 If the client has already expired, it would be reasonable to clear its ClearInflights and subscriptions. There would be no need for recovery at that point.

Now that 'cl' has been deprecated, and you have obtained all the necessary information from it, what is the significance of keeping it continued in 'Clients'?

Calling 'stop()' can also resolve the issue. However, it follows the same final processing logic, and it adds two redundant operations: adding the client to 'Clients' and then removing it.

@mochi-co mochi-co merged commit 624dde0 into mochi-mqtt:main Dec 12, 2023
3 checks passed
@mochi-co
Copy link
Collaborator

Released in v2.4.3
This is a preventative fix to solve the current issue as it's better than having bugs, however I am happy for @x20080406 and @werbenhu for you to please keep discussing the optimal solution to replace this one if necessary.

@thedevop
Copy link
Collaborator

@x20080406 @werbenhu @mochi-co

s.NewClient will start the WriteLoop in a Go routine for non-inline clients:

server/server.go

Lines 231 to 239 in 624dde0

if inline { // inline clients bypass acl and some validity checks.
cl.Net.Inline = true
// By default, we don't want to restrict developer publishes,
// but if you do, reset this after creating inline client.
cl.State.Inflight.ResetReceiveQuota(math.MaxInt32)
} else {
go cl.WriteLoop() // can only write to real clients
}

This will only stop if cl.Stop or cl.State.cancelOpen is called.

@werbenhu
Copy link
Member Author

@thedevop I found this too, and I will submit a new pull request to fix it.

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.

None yet

5 participants