Compare commits

...

4 Commits

Author SHA1 Message Date
71e8a13c70 new kgo version
Some checks failed
sync / sync (push) Has been cancelled
coverage / build (push) Failing after 1m31s
test / test (push) Failing after 18m29s
update deps

fixup race conditions

add kfake usage

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2025-05-25 01:24:50 +03:00
b538ef82b5 [v4] hide access to internal mutex (#185)
* changed embedded mutex to private field

* update ci

* fix tests
2025-05-25 01:23:46 +03:00
44e2d5f9a4 update ci (#188) 2025-05-25 01:23:11 +03:00
vtolstov
9426208e1c Apply Code Coverage Badge 2025-05-21 08:14:38 +00:00
7 changed files with 80 additions and 39 deletions

View File

@@ -8,12 +8,11 @@ on:
- '.gitea/**' - '.gitea/**'
pull_request: pull_request:
branches: [ main, v3, v4 ] branches: [ main, v3, v4 ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs: jobs:
build: build:
if: github.server_url != 'https://github.com'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: checkout code - name: checkout code
@@ -25,7 +24,7 @@ jobs:
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
cache-dependency-path: "**/*.sum" cache-dependency-path: "**/*.sum"
go-version: 'stable' go-version: 'stable'
- name: test coverage - name: test coverage
run: | run: |
@@ -42,8 +41,8 @@ jobs:
name: autocommit name: autocommit
with: with:
commit_message: Apply Code Coverage Badge commit_message: Apply Code Coverage Badge
skip_fetch: true skip_fetch: false
skip_checkout: true skip_checkout: false
file_pattern: ./README.md file_pattern: ./README.md
- name: push - name: push
@@ -51,4 +50,4 @@ jobs:
uses: ad-m/github-push-action@master uses: ad-m/github-push-action@master
with: with:
github_token: ${{ github.token }} github_token: ${{ github.token }}
branch: ${{ github.ref }} branch: ${{ github.ref }}

View File

@@ -20,10 +20,10 @@ jobs:
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
cache-dependency-path: "**/*.sum" cache-dependency-path: "**/*.sum"
go-version: 'stable' go-version: 'stable'
- name: setup deps - name: setup deps
run: go get -v ./... run: go get -v ./...
- name: run lint - name: run lint
uses: https://github.com/golangci/golangci-lint-action@v6 uses: golangci/golangci-lint-action@v6
with: with:
version: 'latest' version: 'latest'

View File

@@ -8,7 +8,7 @@ on:
jobs: jobs:
sync: sync:
if: github.server_url == 'zhttps://github.com' if: github.server_url != 'https://github.com'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: init - name: init
@@ -18,34 +18,76 @@ jobs:
echo "machine git.unistack.org login vtolstov password ${{ secrets.TOKEN_GITEA }}" >> /root/.netrc echo "machine git.unistack.org login vtolstov password ${{ secrets.TOKEN_GITEA }}" >> /root/.netrc
echo "machine github.com login vtolstov password ${{ secrets.TOKEN_GITHUB }}" >> /root/.netrc echo "machine github.com login vtolstov password ${{ secrets.TOKEN_GITHUB }}" >> /root/.netrc
- name: check master
id: check_master
run: |
src_hash=$(git ls-remote https://github.com/${GITHUB_REPOSITORY} refs/heads/master | cut -f1)
dst_hash=$(git ls-remote ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} refs/heads/master | cut -f1)
echo "src_hash=$src_hash"
echo "dst_hash=$dst_hash"
if [ "$src_hash" != "$dst_hash" ]; then
echo "sync_needed=true" >> $GITHUB_OUTPUT
else
echo "sync_needed=false" >> $GITHUB_OUTPUT
fi
- name: sync master - name: sync master
if: steps.check_master.outputs.sync_needed == 'true'
run: | run: |
git clone --filter=blob:none --filter=tree:0 --branch master --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo git clone --filter=blob:none --filter=tree:0 --branch master --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo
cd repo cd repo
git remote add --no-tags --fetch --track master upstream https://github.com/${GITHUB_REPOSITORY} git remote add --no-tags --fetch --track master upstream https://github.com/${GITHUB_REPOSITORY}
git merge upstream/master git pull --rebase upstream master
git push upstream master --progress git push upstream master --progress
git push origin master --progress git push origin master --progress
cd ../ cd ../
rm -rf repo rm -rf repo
- name: check v3
id: check_v3
run: |
src_hash=$(git ls-remote https://github.com/${GITHUB_REPOSITORY} refs/heads/v3 | cut -f1)
dst_hash=$(git ls-remote ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} refs/heads/v3 | cut -f1)
echo "src_hash=$src_hash"
echo "dst_hash=$dst_hash"
if [ "$src_hash" != "$dst_hash" ]; then
echo "sync_needed=true" >> $GITHUB_OUTPUT
else
echo "sync_needed=false" >> $GITHUB_OUTPUT
fi
- name: sync v3 - name: sync v3
if: steps.check_v3.outputs.sync_needed == 'true'
run: | run: |
git clone --filter=blob:none --filter=tree:0 --branch v3 --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo git clone --filter=blob:none --filter=tree:0 --branch v3 --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo
cd repo cd repo
git remote add --no-tags --fetch --track v3 upstream https://github.com/${GITHUB_REPOSITORY} git remote add --no-tags --fetch --track v3 upstream https://github.com/${GITHUB_REPOSITORY}
git merge upstream/v3 git pull --rebase upstream v3
git push upstream v3 --progress git push upstream v3 --progress
git push origin v3 --progress git push origin v3 --progress
cd ../ cd ../
rm -rf repo rm -rf repo
- name: check v4
id: check_v4
run: |
src_hash=$(git ls-remote https://github.com/${GITHUB_REPOSITORY} refs/heads/v4 | cut -f1)
dst_hash=$(git ls-remote ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} refs/heads/v4 | cut -f1)
echo "src_hash=$src_hash"
echo "dst_hash=$dst_hash"
if [ "$src_hash" != "$dst_hash" ]; then
echo "sync_needed=true" >> $GITHUB_OUTPUT
else
echo "sync_needed=false" >> $GITHUB_OUTPUT
fi
- name: sync v4 - name: sync v4
if: steps.check_v4.outputs.sync_needed == 'true'
run: | run: |
git clone --filter=blob:none --filter=tree:0 --branch v4 --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo git clone --filter=blob:none --filter=tree:0 --branch v4 --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo
cd repo cd repo
git remote add --no-tags --fetch --track v4 upstream https://github.com/${GITHUB_REPOSITORY} git remote add --no-tags --fetch --track v4 upstream https://github.com/${GITHUB_REPOSITORY}
git merge upstream/v4 git pull --rebase upstream v4
git push upstream v4 --progress git push upstream v4 --progress
git push origin v4 --progress git push origin v4 --progress
cd ../ cd ../

View File

@@ -32,19 +32,19 @@ jobs:
go-version: 'stable' go-version: 'stable'
- name: setup go work - name: setup go work
env: env:
GOWORK: /workspace/${{ github.repository_owner }}/go.work GOWORK: ${{ github.workspace }}/go.work
run: | run: |
go work init go work init
go work use . go work use .
go work use micro-tests go work use micro-tests
- name: setup deps - name: setup deps
env: env:
GOWORK: /workspace/${{ github.repository_owner }}/go.work GOWORK: ${{ github.workspace }}/go.work
run: go get -v ./... run: go get -v ./...
- name: run tests - name: run tests
env: env:
INTEGRATION_TESTS: yes INTEGRATION_TESTS: yes
GOWORK: /workspace/${{ github.repository_owner }}/go.work GOWORK: ${{ github.workspace }}/go.work
run: | run: |
cd micro-tests cd micro-tests
go test -mod readonly -v ./... || true go test -mod readonly -v ./... || true

View File

@@ -1,2 +1,2 @@
# micro-broker-kgo # micro-broker-kgo
![Coverage](https://img.shields.io/badge/Coverage-65.8%25-yellow) ![Coverage](https://img.shields.io/badge/Coverage-65.1%25-yellow)

22
kgo.go
View File

@@ -74,7 +74,7 @@ type Broker struct {
opts broker.Options opts broker.Options
sync.RWMutex mu sync.RWMutex
init bool init bool
} }
@@ -141,9 +141,9 @@ func (b *Broker) newCodec(ct string) (codec.Codec, error) {
if idx := strings.IndexRune(ct, ';'); idx >= 0 { if idx := strings.IndexRune(ct, ';'); idx >= 0 {
ct = ct[:idx] ct = ct[:idx]
} }
b.RLock() b.mu.RLock()
c, ok := b.opts.Codecs[ct] c, ok := b.opts.Codecs[ct]
b.RUnlock() b.mu.RUnlock()
if ok { if ok {
return c, nil return c, nil
} }
@@ -238,10 +238,10 @@ func (k *Broker) Connect(ctx context.Context) error {
return err return err
} }
k.Lock() k.mu.Lock()
k.c = c k.c = c
k.connected.Store(1) k.connected.Store(1)
k.Unlock() k.mu.Unlock()
return nil return nil
} }
@@ -259,8 +259,8 @@ func (k *Broker) Disconnect(ctx context.Context) error {
ctx, span = k.opts.Tracer.Start(ctx, "Disconnect") ctx, span = k.opts.Tracer.Start(ctx, "Disconnect")
defer span.Finish() defer span.Finish()
k.Lock() k.mu.Lock()
defer k.Unlock() defer k.mu.Unlock()
select { select {
case <-nctx.Done(): case <-nctx.Done():
return nctx.Err() return nctx.Err()
@@ -284,8 +284,8 @@ func (k *Broker) Disconnect(ctx context.Context) error {
} }
func (k *Broker) Init(opts ...broker.Option) error { func (k *Broker) Init(opts ...broker.Option) error {
k.Lock() k.mu.Lock()
defer k.Unlock() defer k.mu.Unlock()
if len(opts) == 0 && k.init { if len(opts) == 0 && k.init {
return nil return nil
@@ -538,9 +538,9 @@ func (b *Broker) fnSubscribe(ctx context.Context, topic string, handler interfac
go sub.poll(ctx) go sub.poll(ctx)
b.Lock() b.mu.Lock()
b.subs = append(b.subs, sub) b.subs = append(b.subs, sub)
b.Unlock() b.mu.Unlock()
return sub, nil return sub, nil
} }

View File

@@ -49,8 +49,8 @@ type Subscriber struct {
kopts broker.Options kopts broker.Options
opts broker.SubscribeOptions opts broker.SubscribeOptions
connected *atomic.Uint32 connected *atomic.Uint32
sync.RWMutex mu sync.RWMutex
closed bool closed bool
fatalOnError bool fatalOnError bool
} }
@@ -118,11 +118,11 @@ func (s *Subscriber) poll(ctx context.Context) {
continue continue
} }
s.Lock() s.mu.Lock()
for p, l := range lmap { for p, l := range lmap {
s.kopts.Meter.Counter(semconv.BrokerGroupLag, "topic", s.topic, "group", s.opts.Group, "partition", strconv.Itoa(int(p))).Set(uint64(l.Lag)) s.kopts.Meter.Counter(semconv.BrokerGroupLag, "topic", s.topic, "group", s.opts.Group, "partition", strconv.Itoa(int(p))).Set(uint64(l.Lag))
} }
s.Unlock() s.mu.Unlock()
} }
} }
@@ -147,9 +147,9 @@ func (s *Subscriber) poll(ctx context.Context) {
fetches.EachPartition(func(p kgo.FetchTopicPartition) { fetches.EachPartition(func(p kgo.FetchTopicPartition) {
tps := tp{p.Topic, p.Partition} tps := tp{p.Topic, p.Partition}
s.Lock() s.mu.Lock()
c := s.consumers[tps] c := s.consumers[tps]
s.Unlock() s.mu.Unlock()
if c != nil { if c != nil {
c.recs <- p c.recs <- p
} }
@@ -166,15 +166,15 @@ func (s *Subscriber) killConsumers(ctx context.Context, lost map[string][]int32)
for topic, partitions := range lost { for topic, partitions := range lost {
for _, partition := range partitions { for _, partition := range partitions {
tps := tp{topic, partition} tps := tp{topic, partition}
s.Lock() s.mu.Lock()
pc, ok := s.consumers[tps] pc, ok := s.consumers[tps]
s.Unlock() s.mu.Unlock()
if !ok { if !ok {
continue continue
} }
s.Lock() s.mu.Lock()
delete(s.consumers, tps) delete(s.consumers, tps)
s.Unlock() s.mu.Unlock()
close(pc.quit) close(pc.quit)
if s.kopts.Logger.V(logger.DebugLevel) { if s.kopts.Logger.V(logger.DebugLevel) {
s.kopts.Logger.Debug(ctx, fmt.Sprintf("[kgo] waiting for work to finish topic %s partition %d", topic, partition)) s.kopts.Logger.Debug(ctx, fmt.Sprintf("[kgo] waiting for work to finish topic %s partition %d", topic, partition))
@@ -230,9 +230,9 @@ func (s *Subscriber) assigned(_ context.Context, c *kgo.Client, assigned map[str
opts: s.opts, opts: s.opts,
connected: s.connected, connected: s.connected,
} }
s.Lock() s.mu.Lock()
s.consumers[tp{topic, partition}] = pc s.consumers[tp{topic, partition}] = pc
s.Unlock() s.mu.Unlock()
go pc.consume() go pc.consume()
} }
} }