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

Release co #1

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
359 changes: 19 additions & 340 deletions .github/workflows/dapr.yml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div style="text-align: center"><img src="/img/dapr_logo.svg" height="120px">
<h2>Any language, any framework, anywhere</h2>
<h2>Any language1, any framework, anywhere</h2>
</div>

[![Go Report Card](https://goreportcard.com/badge/github.com/dapr/dapr)](https://goreportcard.com/report/github.com/dapr/dapr)
Expand Down
4 changes: 2 additions & 2 deletions docker/docker.mk
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ DOCKERFILE_DIR?=./docker

DAPR_SYSTEM_IMAGE_NAME?=$(RELEASE_NAME)
DAPR_RUNTIME_IMAGE_NAME?=daprd
DAPR_PLACEMENT_IMAGE_NAME?=placement
DAPR_SENTRY_IMAGE_NAME?=sentry
DAPR_PLACEMENT_IMAGE_NAME?=dapr_placement
DAPR_SENTRY_IMAGE_NAME?=dapr_sentry

# build docker image for linux
BIN_PATH=$(OUT_DIR)/$(TARGET_OS)_$(TARGET_ARCH)
Expand Down
23 changes: 23 additions & 0 deletions docs/release_notes/v1.9.4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Dapr 1.9.4

## Fixes MQTT pubsub component failure to read messages on startup when multiple subscriptions are configured

### Problem

When using the MQTT component users who had multiple subcriptions could encounter an issue where messages would stop being processed for the component.

### Impact

This issue impacts users of the MQTT pubsub component on Dapr 1.9.0-1.9.3 that subscribe to multiple topics using the same component.

### Root cause

The issue occurs when there are two or more subscriptions, messages are being published to the first topic only, and the subscriber gets killed after publishing a few messages. If the subscriber comes back online after a few (two or more) messages have been published already, then it will only deliver the first pending message and stop.

In the situation above, Dapr could enter into a deadlock and stop processing messages from MQTT.

The issue was traced back to an error in the upstream MQTT SDK used by Dapr

### Solution

We have upgraded the MQTT SDK used by Dapr to a new version which fixes the error.
85 changes: 85 additions & 0 deletions docs/release_notes/v1.9.5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Dapr 1.9.5

- Fixes a panic in the Azure Cosmos DB state store component when performing transaction request with ETags
- Fixes component initialization failure when the built-in Kubernetes secret store is disabled
- Fixes nil dereference crash in placement membership heartbeat loop in sidecar
- Fixes MQTT message acknowledgement for retained messages

## Fixes a panic in the Azure Cosmos DB state store component when performing transaction request with ETags

### Problem

When setting any ETag in a transaction request with the Azure Cosmos DB state store, Dapr panics with a nil pointer dereference.

### Impact

This issue impacts all users of the Azure Cosmos DB state store on Dapr 1.9.0-1.9.4.

### Root cause

When setting an ETag on a transaction request in the Azure Cosmos DB state store, a bug causes Dapr to panic.

### Solution

We fixed a bug that caused Dapr to panic.


## Fixes component initialization failure when the built-in Kubernetes secret store is disabled

### Problem

When running on Kubernetes, Dapr automatically initializes a Kubernetes secret store in each sidecar. Starting with Dapr 1.8, this behavior can be [turned off](https://docs.dapr.io/reference/arguments-annotations-overview/) using the `dapr.io/disable-builtin-k8s-secret-store`.

However, with the built-in Kubernetes secret store disabled, an error prevented components from being able to retrieve secrets [stored as Kubernetes secrets](https://docs.dapr.io/operations/components/component-secrets/#referencing-a-kubernetes-secret) during initialization. This caused components to fail to initialize due to not being able to read secrets, for example connection strings or passwords.

### Impact

The issue impacts users on Dapr 1.8.0-1.9.4 who want to disable the built-in Kubernetes secret store.

### Root cause

In Dapr, components that use secrets stored as Kubernetes secrets should not need the built-in Kubernetes secret store to be loaded to work. This is because the Dapr Operator service populates the secrets from the Kubernetes secret store and passes them to the sidecar automatically.

However, during initialization of a component that references a secret stored in Kubernetes, a bug caused Dapr to return an error if the built-in Kubernetes secret store was disabled, and the value of the secret as included by the Dapr Operator was ignored.

### Solution

We have implemented a fix in the component initialization sequence. Now, components that reference secrets from the Kubernetes secret store do not need the built-in Kubernetes secret store to be enabled anymore.


## Fixes panic in actor placement membership in Dapr sidecar

### Problem

When recovering from a failure in the connection to the Dapr placement service, the Dapr sidecar could have encountered a panic in some cases.

### Impact

The issue can impact all Dapr users on Dapr 1.7.0-1.9.4 using actors.

### Root cause

We identified a race condition in the actor placement service client that could have caused the Dapr to panic after recovering from a failure.

### Solution

We updated actor placement service to address the race condition and remove the cause for the panic.


## Fixes MQTT message acknowledgement for retained messages

### Problem

Retained MQTT messages should be only processed once, however, they were not being acknowledged and thus were resent indefinitely.

### Impact

This issue impacts all users of the MQTT PubSub component on Dapr 1.9.0-1.9.4, where-in a subscriber using MQTT component receives a `retained` message.

### Root cause

MQTT retained messages were never being acknowledged and were therefore being resent indefinitely.

### Solution

We updated Dapr to acknowledge a retained message in the MQTT PubSub component.
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/PuerkitoBio/purell v1.1.1
github.com/agrea/ptr v0.0.0-20180711073057-77a518d99b7b
github.com/cenkalti/backoff/v4 v4.1.3
github.com/dapr/components-contrib v1.9.1
github.com/dapr/components-contrib v1.9.6
github.com/dapr/kit v0.0.3-0.20220930182601-272e358ba6a7
github.com/fasthttp/router v1.4.12
github.com/fsnotify/fsnotify v1.5.4
Expand Down Expand Up @@ -175,7 +175,7 @@ require (
github.com/eapache/go-resiliency v1.2.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/eclipse/paho.mqtt.golang v1.3.5 // indirect
github.com/eclipse/paho.mqtt.golang v1.4.2-0.20221018190109-a1800d8df9a4 // indirect
github.com/emicklei/go-restful v2.9.5+incompatible // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
Expand Down Expand Up @@ -388,17 +388,17 @@ require (
)

replace (
github.com/dapr/components-contrib v1.9.6 => github.com/TheLandGame/components-contrib v0.0.0-20241122170834-508d9cbfe046
github.com/toolkits/concurrent => github.com/niean/gotools v0.0.0-20151221085310-ff3f51fc5c60
gopkg.in/couchbaselabs/gocbconnstr.v1 => github.com/couchbaselabs/gocbconnstr v1.0.5
k8s.io/client => github.com/kubernetes-client/go v0.0.0-20190928040339-c757968c4c36
)

replace github.com/eclipse/paho.mqtt.golang => github.com/shivamkm07/paho.mqtt.golang v1.3.6-0.20220106130409-e28a1db639f8

// Uncomment for local development for testing with changes in the components-contrib repository.
// Don't commit with this uncommented!
//
// replace github.com/dapr/components-contrib => ../components-contrib

//
// Then, run `make modtidy` in this repository.
// This ensures that go.mod and go.sum are up-to-date.
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ github.com/Shopify/toxiproxy/v2 v2.1.6-0.20210914104332-15ea381dcdae/go.mod h1:/
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjlRbWyNqkPsJ3Fg+tQZCbgeX1VGljbQY=
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/TheLandGame/components-contrib v0.0.0-20241122170834-508d9cbfe046 h1:7ciYMota8fW0LACi28k/Fg1wGSp/B71SefmhQ3w73PI=
github.com/TheLandGame/components-contrib v0.0.0-20241122170834-508d9cbfe046/go.mod h1:U0cjxEEbZR7sNN9i1ZdWnkIOZP8iRSvoyF2gRhBaHfc=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig=
Expand Down Expand Up @@ -593,8 +595,6 @@ github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3E
github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=
github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0=
github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0=
github.com/dapr/components-contrib v1.9.1 h1:g2TpEwvnB4s5Lvf89QXzAlj3xaWGaxTZIhTY4LpIfYI=
github.com/dapr/components-contrib v1.9.1/go.mod h1:ftVthBjl0e5G61J5XKkZKEjU/TGE0gNT9fJCNAdUjU8=
github.com/dapr/kit v0.0.3-0.20220930182601-272e358ba6a7 h1:XDb+PwAOxbVNvLxkmwPgKlH5ltYlDdz/GcEDMe8RJxE=
github.com/dapr/kit v0.0.3-0.20220930182601-272e358ba6a7/go.mod h1:FR+yc0R0szlKnJooVqJvl7FhWf21wzY4/EzmyFQrESw=
github.com/dave/jennifer v1.4.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
Expand Down Expand Up @@ -681,6 +681,8 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/eclipse/paho.mqtt.golang v1.4.2-0.20221018190109-a1800d8df9a4 h1:yJj84YKRTY+zu/s9peWf0kuSq38zKT4KJUaFcJ1uRJM=
github.com/eclipse/paho.mqtt.golang v1.4.2-0.20221018190109-a1800d8df9a4/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
Expand Down Expand Up @@ -1768,8 +1770,6 @@ github.com/shirou/gopsutil v3.20.11+incompatible h1:LJr4ZQK4mPpIV5gOa4jCOKOGb4ty
github.com/shirou/gopsutil v3.20.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v3 v3.21.6 h1:vU7jrp1Ic/2sHB7w6UNs7MIkn7ebVtTb5D9j45o9VYE=
github.com/shirou/gopsutil/v3 v3.21.6/go.mod h1:JfVbDpIBLVzT8oKbvMg9P3wEIMDDpVn+LwHTKj0ST88=
github.com/shivamkm07/paho.mqtt.golang v1.3.6-0.20220106130409-e28a1db639f8 h1:BXKXQzeHuVnSrHAKjvq9ICrgPC27tJ/hXWLMQo36c5s=
github.com/shivamkm07/paho.mqtt.golang v1.3.6-0.20220106130409-e28a1db639f8/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
Expand Down
2 changes: 0 additions & 2 deletions pkg/actors/internal/placement.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,10 @@ func (p *ActorPlacement) closeStream() {

if p.clientStream != nil {
p.clientStream.CloseSend()
p.clientStream = nil
}

if p.clientConn != nil {
p.clientConn.Close()
p.clientConn = nil
}
}()

Expand Down
101 changes: 101 additions & 0 deletions pkg/actors/internal/placement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ limitations under the License.
package internal

import (
"errors"
"fmt"
"io"
"net"
Expand Down Expand Up @@ -142,6 +143,106 @@ func TestAppHealthyStatus(t *testing.T) {
cleanup()
}

type fakeStream struct {
//nolint:nosnakecase
placementv1pb.Placement_ReportDaprStatusClient
send func(host *placementv1pb.Host) error
recv func() (*placementv1pb.PlacementOrder, error)
closeSendCalled atomic.Int64
}

func (f *fakeStream) Send(host *placementv1pb.Host) error {
return f.send(host)
}

func (f *fakeStream) Recv() (*placementv1pb.PlacementOrder, error) {
return f.recv()
}

func (f *fakeStream) CloseSend() error {
f.closeSendCalled.Add(1)
return nil
}

func TestCloseOnRecv(t *testing.T) {
t.Run("should not panic", func(t *testing.T) {
address, testSrv, cleanup := newTestServer()

// set leader
testSrv.setLeader(true)

appHealth := atomic.Bool{}
appHealth.Store(true)

appHealthFunc := appHealth.Load
noopTableUpdateFunc := func() {}
testPlacement := NewActorPlacement(
[]string{address}, nil, "testAppID", "127.0.0.1:1000", []string{"actorOne", "actorTwo"},
appHealthFunc, noopTableUpdateFunc)

// act
testPlacement.Start()

assert.NotNil(t, testPlacement.clientStream)

var called int
recvGroup := sync.WaitGroup{}
recvGroup.Add(1)

closeGroup := sync.WaitGroup{}
closeGroup.Add(1)

testPlacement.clientLock.Lock()
fs := &fakeStream{
recv: func() (*placementv1pb.PlacementOrder, error) {
defer func() {
called++
}()
if called == 0 { // first call should close stream and wait
recvGroup.Done()
closeGroup.Wait()
return &placementv1pb.PlacementOrder{
Operation: unlockOperation,
}, nil
}

if called == 1 { // force reconnect
return nil, errors.New("force reconnect")
}

return &placementv1pb.PlacementOrder{
Operation: unlockOperation,
}, nil
},
send: func(host *placementv1pb.Host) error {
return nil
},
}
testPlacement.clientStream = fs
testPlacement.clientLock.Unlock()

go func() {
recvGroup.Wait()
testPlacement.closeStream()
closeGroup.Done()
}()
// should not panic
closeGroup.Wait()
testPlacement.streamConnectedCond.L.Lock()
for !testPlacement.streamConnAlive {
testPlacement.streamConnectedCond.Wait()
}
testPlacement.streamConnectedCond.L.Unlock()

assert.Equal(t, called, 2)
assert.GreaterOrEqual(t, fs.closeSendCalled.Load(), int64(2))
assert.NotEqual(t, testPlacement.clientStream, fs)
// clean up
testPlacement.Stop()
cleanup()
})
}

func TestOnPlacementOrder(t *testing.T) {
tableUpdateCount := 0
appHealthFunc := func() bool { return true }
Expand Down
11 changes: 9 additions & 2 deletions pkg/http/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ func (a *api) constructHealthzEndpoints() []Endpoint {
return []Endpoint{
{
Methods: []string{fasthttp.MethodGet},
Route: "healthz",
Route: "healthz/{appId:*}",
Version: apiVersionV1,
Handler: a.onGetHealthz,
},
Expand Down Expand Up @@ -1357,6 +1357,7 @@ func (a *api) getStateStoreName(reqCtx *fasthttp.RequestCtx) string {
}

func (a *api) onDirectMessage(reqCtx *fasthttp.RequestCtx) {
log.Infof("Received direct message: %s, startAt: %d", reqCtx.RequestURI(), time.Now().UnixMilli())
targetID := a.findTargetID(reqCtx)
if targetID == "" {
msg := NewErrorResponse("ERR_DIRECT_INVOKE", messages.ErrDirectInvokeNoAppID)
Expand Down Expand Up @@ -2020,7 +2021,13 @@ func (a *api) onGetHealthz(reqCtx *fasthttp.RequestCtx) {
respond(reqCtx, withError(fasthttp.StatusInternalServerError, msg))
log.Debug(msg)
} else {
respond(reqCtx, withEmpty())
matchAppId := reqCtx.UserValue("appId").(string)
if matchAppId != "" && matchAppId != a.id {
msg := NewErrorResponse("ERR_HEALTH_APPID_NOT_MATCH", messages.ErrHealthAppIdNotMatch)
respond(reqCtx, withError(fasthttp.StatusInternalServerError, msg))
} else {
respond(reqCtx, withEmpty())
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/messages/api_errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ const (
ErrMetadataGet = "failed deserializing metadata: %s"

// Healthz.
ErrHealthNotReady = "dapr is not ready"
ErrHealthNotReady = "dapr is not ready"
ErrHealthAppIdNotMatch = "dapr appId is not match"

// Configuration.
ErrConfigurationStoresNotConfigured = "error configuration stores not configured"
Expand Down
5 changes: 4 additions & 1 deletion pkg/messaging/direct_messaging.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,10 @@ func (d *directMessaging) Invoke(ctx context.Context, targetAppID string, req *i
}

if app.id == d.appID && app.namespace == d.namespace {
return d.invokeLocal(ctx, req)
log.Infof("invoke local app: %s.%s startAt: %d", app.id, app.namespace, time.Now().UnixMilli())
result, err := d.invokeLocal(ctx, req)
log.Infof("invoke local app: %s.%s endAt: %d", app.id, app.namespace, time.Now().UnixMilli())
return result, err
}
return d.invokeWithRetry(ctx, retry.DefaultLinearRetryCount, retry.DefaultLinearBackoffInterval, app, d.invokeRemote, req)
}
Expand Down
Loading
Loading