Skip to content

Commit 18e2cc3

Browse files
committed
kfake: support committing to non-existing groups
Used to test the prior commit
1 parent a7caf20 commit 18e2cc3

File tree

2 files changed

+79
-36
lines changed

2 files changed

+79
-36
lines changed

Diff for: pkg/kfake/08_offset_commit.go

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
package kfake
22

33
import (
4-
"github.com/twmb/franz-go/pkg/kerr"
54
"github.com/twmb/franz-go/pkg/kmsg"
65
)
76

87
func init() { regKey(8, 0, 8) }
98

109
func (c *Cluster) handleOffsetCommit(creq *clientReq) (kmsg.Response, error) {
1110
req := creq.kreq.(*kmsg.OffsetCommitRequest)
12-
resp := req.ResponseKind().(*kmsg.OffsetCommitResponse)
1311

1412
if err := checkReqVersion(req.Key(), req.Version); err != nil {
1513
return nil, err
1614
}
1715

18-
if c.groups.handleOffsetCommit(creq) {
19-
return nil, nil
20-
}
21-
22-
fillOffsetCommit(req, resp, kerr.GroupIDNotFound.Code)
23-
return resp, nil
16+
c.groups.handleOffsetCommit(creq)
17+
return nil, nil
2418
}

Diff for: pkg/kfake/groups.go

+77-28
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,20 @@ func generateMemberID(clientID string, instanceID *string) string {
132132
// GROUPS //
133133
////////////
134134

135+
func (gs *groups) newGroup(name string) *group {
136+
return &group{
137+
c: gs.c,
138+
gs: gs,
139+
name: name,
140+
members: make(map[string]*groupMember),
141+
pending: make(map[string]*groupMember),
142+
protocols: make(map[string]int),
143+
reqCh: make(chan *clientReq),
144+
controlCh: make(chan func()),
145+
quitCh: make(chan struct{}),
146+
}
147+
}
148+
135149
// handleJoin completely hijacks the incoming request.
136150
func (gs *groups) handleJoin(creq *clientReq) {
137151
if gs.gs == nil {
@@ -141,17 +155,7 @@ func (gs *groups) handleJoin(creq *clientReq) {
141155
start:
142156
g := gs.gs[req.Group]
143157
if g == nil {
144-
g = &group{
145-
c: gs.c,
146-
gs: gs,
147-
name: req.Group,
148-
members: make(map[string]*groupMember),
149-
pending: make(map[string]*groupMember),
150-
protocols: make(map[string]int),
151-
reqCh: make(chan *clientReq),
152-
controlCh: make(chan func()),
153-
quitCh: make(chan struct{}),
154-
}
158+
g = gs.newGroup(req.Group)
155159
waitJoin := make(chan struct{})
156160
gs.gs[req.Group] = g
157161
go g.manage(func() { close(waitJoin) })
@@ -194,8 +198,25 @@ func (gs *groups) handleLeave(creq *clientReq) bool {
194198
return gs.handleHijack(creq.kreq.(*kmsg.LeaveGroupRequest).Group, creq)
195199
}
196200

197-
func (gs *groups) handleOffsetCommit(creq *clientReq) bool {
198-
return gs.handleHijack(creq.kreq.(*kmsg.OffsetCommitRequest).Group, creq)
201+
func (gs *groups) handleOffsetCommit(creq *clientReq) {
202+
if gs.gs == nil {
203+
gs.gs = make(map[string]*group)
204+
}
205+
req := creq.kreq.(*kmsg.OffsetCommitRequest)
206+
start:
207+
g := gs.gs[req.Group]
208+
if g == nil {
209+
g = gs.newGroup(req.Group)
210+
waitCommit := make(chan struct{})
211+
gs.gs[req.Group] = g
212+
go g.manage(func() { close(waitCommit) })
213+
defer func() { <-waitCommit }()
214+
}
215+
select {
216+
case g.reqCh <- creq:
217+
case <-g.quitCh:
218+
goto start
219+
}
199220
}
200221

201222
func (gs *groups) handleOffsetDelete(creq *clientReq) bool {
@@ -551,7 +572,9 @@ func (g *group) manage(detachNew func()) {
551572
case *kmsg.LeaveGroupRequest:
552573
kresp = g.handleLeave(creq)
553574
case *kmsg.OffsetCommitRequest:
554-
kresp = g.handleOffsetCommit(creq)
575+
var ok bool
576+
kresp, ok = g.handleOffsetCommit(creq)
577+
firstJoin(ok)
555578
case *kmsg.OffsetDeleteRequest:
556579
kresp = g.handleOffsetDelete(creq)
557580
}
@@ -807,34 +830,60 @@ func fillOffsetCommit(req *kmsg.OffsetCommitRequest, resp *kmsg.OffsetCommitResp
807830
}
808831

809832
// Handles a commit.
810-
func (g *group) handleOffsetCommit(creq *clientReq) *kmsg.OffsetCommitResponse {
833+
func (g *group) handleOffsetCommit(creq *clientReq) (*kmsg.OffsetCommitResponse, bool) {
811834
req := creq.kreq.(*kmsg.OffsetCommitRequest)
812835
resp := req.ResponseKind().(*kmsg.OffsetCommitResponse)
813836

814837
if kerr := g.c.validateGroup(creq, req.Group); kerr != nil {
815838
fillOffsetCommit(req, resp, kerr.Code)
816-
return resp
839+
return resp, false
817840
}
818841
if req.InstanceID != nil {
819842
fillOffsetCommit(req, resp, kerr.InvalidGroupID.Code)
820-
return resp
821-
}
822-
m, ok := g.members[req.MemberID]
823-
if !ok {
824-
fillOffsetCommit(req, resp, kerr.UnknownMemberID.Code)
825-
return resp
843+
return resp, false
826844
}
827-
if req.Generation != g.generation {
828-
fillOffsetCommit(req, resp, kerr.IllegalGeneration.Code)
829-
return resp
845+
846+
var m *groupMember
847+
if len(g.members) > 0 {
848+
var ok bool
849+
m, ok = g.members[req.MemberID]
850+
if !ok {
851+
fillOffsetCommit(req, resp, kerr.UnknownMemberID.Code)
852+
return resp, false
853+
}
854+
if req.Generation != g.generation {
855+
fillOffsetCommit(req, resp, kerr.IllegalGeneration.Code)
856+
return resp, false
857+
}
858+
} else {
859+
if req.MemberID != "" {
860+
fillOffsetCommit(req, resp, kerr.UnknownMemberID.Code)
861+
return resp, false
862+
}
863+
if req.Generation != -1 {
864+
fillOffsetCommit(req, resp, kerr.IllegalGeneration.Code)
865+
return resp, false
866+
}
867+
if g.state != groupEmpty {
868+
panic("invalid state: no members, but group not empty")
869+
}
830870
}
831871

832872
switch g.state {
833873
default:
834874
fillOffsetCommit(req, resp, kerr.GroupIDNotFound.Code)
835-
return resp
875+
return resp, true
836876
case groupEmpty:
837-
// for when we support empty group commits
877+
for _, t := range req.Topics {
878+
for _, p := range t.Partitions {
879+
g.commits.set(t.Topic, p.Partition, offsetCommit{
880+
offset: p.Offset,
881+
leaderEpoch: p.LeaderEpoch,
882+
metadata: p.Metadata,
883+
})
884+
}
885+
}
886+
fillOffsetCommit(req, resp, 0)
838887
case groupPreparingRebalance, groupStable:
839888
for _, t := range req.Topics {
840889
for _, p := range t.Partitions {
@@ -851,7 +900,7 @@ func (g *group) handleOffsetCommit(creq *clientReq) *kmsg.OffsetCommitResponse {
851900
fillOffsetCommit(req, resp, kerr.RebalanceInProgress.Code)
852901
g.updateHeartbeat(m)
853902
}
854-
return resp
903+
return resp, true
855904
}
856905

857906
// Transitions the group to the preparing rebalance state. We first need to

0 commit comments

Comments
 (0)