Compare commits

...

5 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
d6e73a3419 minimize checks on publish
Some checks failed
coverage / build (push) Successful in 4m51s
sync / sync (push) Has been skipped
test / test (push) Failing after 15m31s
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2025-05-21 09:54:16 +03:00
8 changed files with 81 additions and 51 deletions

View File

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

View File

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

View File

@@ -8,7 +8,7 @@ on:
jobs:
sync:
if: github.server_url == 'zhttps://github.com'
if: github.server_url != 'https://github.com'
runs-on: ubuntu-latest
steps:
- name: init
@@ -18,34 +18,76 @@ jobs:
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
- 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
if: steps.check_master.outputs.sync_needed == 'true'
run: |
git clone --filter=blob:none --filter=tree:0 --branch master --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo
cd repo
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 origin master --progress
cd ../
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
if: steps.check_v3.outputs.sync_needed == 'true'
run: |
git clone --filter=blob:none --filter=tree:0 --branch v3 --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo
cd repo
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 origin v3 --progress
cd ../
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
if: steps.check_v4.outputs.sync_needed == 'true'
run: |
git clone --filter=blob:none --filter=tree:0 --branch v4 --single-branch ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} repo
cd repo
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 origin v4 --progress
cd ../

View File

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

View File

@@ -1,2 +1,2 @@
# 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)

33
kgo.go
View File

@@ -74,7 +74,7 @@ type Broker struct {
opts broker.Options
sync.RWMutex
mu sync.RWMutex
init bool
}
@@ -141,9 +141,9 @@ func (b *Broker) newCodec(ct string) (codec.Codec, error) {
if idx := strings.IndexRune(ct, ';'); idx >= 0 {
ct = ct[:idx]
}
b.RLock()
b.mu.RLock()
c, ok := b.opts.Codecs[ct]
b.RUnlock()
b.mu.RUnlock()
if ok {
return c, nil
}
@@ -238,10 +238,10 @@ func (k *Broker) Connect(ctx context.Context) error {
return err
}
k.Lock()
k.mu.Lock()
k.c = c
k.connected.Store(1)
k.Unlock()
k.mu.Unlock()
return nil
}
@@ -259,8 +259,8 @@ func (k *Broker) Disconnect(ctx context.Context) error {
ctx, span = k.opts.Tracer.Start(ctx, "Disconnect")
defer span.Finish()
k.Lock()
defer k.Unlock()
k.mu.Lock()
defer k.mu.Unlock()
select {
case <-nctx.Done():
return nctx.Err()
@@ -284,8 +284,8 @@ func (k *Broker) Disconnect(ctx context.Context) error {
}
func (k *Broker) Init(opts ...broker.Option) error {
k.Lock()
defer k.Unlock()
k.mu.Lock()
defer k.mu.Unlock()
if len(opts) == 0 && k.init {
return nil
@@ -344,23 +344,12 @@ func (b *Broker) fnPublish(ctx context.Context, topic string, messages ...broker
}
func (b *Broker) publish(ctx context.Context, topic string, messages ...broker.Message) error {
if b.connected.Load() == 0 {
c, _, err := b.connect(ctx, b.kopts...)
if err != nil {
return err
}
b.Lock()
b.c = c
b.Unlock()
}
records := make([]*kgo.Record, 0, len(messages))
var errs []string
var key []byte
var promise func(*kgo.Record, error)
for _, msg := range messages {
if mctx := msg.Context(); mctx != nil {
if k, ok := mctx.Value(publishKey{}).([]byte); ok && k != nil {
key = k
@@ -549,9 +538,9 @@ func (b *Broker) fnSubscribe(ctx context.Context, topic string, handler interfac
go sub.poll(ctx)
b.Lock()
b.mu.Lock()
b.subs = append(b.subs, sub)
b.Unlock()
b.mu.Unlock()
return sub, nil
}

View File

@@ -222,7 +222,7 @@ func TestPubSub(t *testing.T) {
if prc := atomic.LoadInt64(&idx); prc == msgcnt {
close(done)
} else {
t.Logf("processed %v\n", prc)
t.Logf("processed %v of %v\n", prc, msgcnt)
}
case <-ticker.C:
close(done)

View File

@@ -49,8 +49,8 @@ type Subscriber struct {
kopts broker.Options
opts broker.SubscribeOptions
connected *atomic.Uint32
sync.RWMutex
connected *atomic.Uint32
mu sync.RWMutex
closed bool
fatalOnError bool
}
@@ -118,11 +118,11 @@ func (s *Subscriber) poll(ctx context.Context) {
continue
}
s.Lock()
s.mu.Lock()
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.Unlock()
s.mu.Unlock()
}
}
@@ -147,9 +147,9 @@ func (s *Subscriber) poll(ctx context.Context) {
fetches.EachPartition(func(p kgo.FetchTopicPartition) {
tps := tp{p.Topic, p.Partition}
s.Lock()
s.mu.Lock()
c := s.consumers[tps]
s.Unlock()
s.mu.Unlock()
if c != nil {
c.recs <- p
}
@@ -166,15 +166,15 @@ func (s *Subscriber) killConsumers(ctx context.Context, lost map[string][]int32)
for topic, partitions := range lost {
for _, partition := range partitions {
tps := tp{topic, partition}
s.Lock()
s.mu.Lock()
pc, ok := s.consumers[tps]
s.Unlock()
s.mu.Unlock()
if !ok {
continue
}
s.Lock()
s.mu.Lock()
delete(s.consumers, tps)
s.Unlock()
s.mu.Unlock()
close(pc.quit)
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))
@@ -230,9 +230,9 @@ func (s *Subscriber) assigned(_ context.Context, c *kgo.Client, assigned map[str
opts: s.opts,
connected: s.connected,
}
s.Lock()
s.mu.Lock()
s.consumers[tp{topic, partition}] = pc
s.Unlock()
s.mu.Unlock()
go pc.consume()
}
}