From f0d51d410c49432cb9708f3d576744fee5c6aaaf Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Wed, 10 Jun 2026 23:07:53 +0200 Subject: [PATCH 01/11] feature: migrate to v6 module, api-go/v6, pool/v2 and goridge/v4 --- aggregatedpool/activity.go | 8 ++++---- aggregatedpool/handler.go | 6 +++--- aggregatedpool/interceptor.go | 2 +- aggregatedpool/local_activity.go | 8 ++++---- aggregatedpool/workers.go | 4 ++-- aggregatedpool/workers_test.go | 2 +- aggregatedpool/workflow.go | 12 ++++++------ api/interfaces.go | 12 ++++++------ config.go | 2 +- go.mod | 13 +++++++++---- go.sum | 16 ++++++++++------ go.work.sum | 2 ++ info.go | 8 ++++---- internal.go | 12 ++++++------ internal/codec/proto/proto.go | 6 +++--- metrics.go | 4 ++-- status.go | 4 ++-- 17 files changed, 66 insertions(+), 55 deletions(-) diff --git a/aggregatedpool/activity.go b/aggregatedpool/activity.go index 11c3102f..2451ebdc 100644 --- a/aggregatedpool/activity.go +++ b/aggregatedpool/activity.go @@ -7,10 +7,10 @@ import ( "unsafe" "github.com/roadrunner-server/errors" - "github.com/roadrunner-server/goridge/v3/pkg/frame" - "github.com/roadrunner-server/pool/payload" - "github.com/temporalio/roadrunner-temporal/v5/api" - "github.com/temporalio/roadrunner-temporal/v5/internal" + "github.com/roadrunner-server/goridge/v4/pkg/frame" + "github.com/roadrunner-server/pool/v2/payload" + "github.com/temporalio/roadrunner-temporal/v6/api" + "github.com/temporalio/roadrunner-temporal/v6/internal" commonpb "go.temporal.io/api/common/v1" tActivity "go.temporal.io/sdk/activity" "go.temporal.io/sdk/temporal" diff --git a/aggregatedpool/handler.go b/aggregatedpool/handler.go index 3afce609..e373c325 100644 --- a/aggregatedpool/handler.go +++ b/aggregatedpool/handler.go @@ -8,9 +8,9 @@ import ( "time" "github.com/roadrunner-server/errors" - "github.com/roadrunner-server/goridge/v3/pkg/frame" - "github.com/roadrunner-server/pool/payload" - "github.com/temporalio/roadrunner-temporal/v5/internal" + "github.com/roadrunner-server/goridge/v4/pkg/frame" + "github.com/roadrunner-server/pool/v2/payload" + "github.com/temporalio/roadrunner-temporal/v6/internal" commonpb "go.temporal.io/api/common/v1" bindings "go.temporal.io/sdk/internalbindings" "go.temporal.io/sdk/temporal" diff --git a/aggregatedpool/interceptor.go b/aggregatedpool/interceptor.go index 4da55d3c..59e3e355 100644 --- a/aggregatedpool/interceptor.go +++ b/aggregatedpool/interceptor.go @@ -3,7 +3,7 @@ package aggregatedpool import ( "context" - "github.com/temporalio/roadrunner-temporal/v5/api" + "github.com/temporalio/roadrunner-temporal/v6/api" "go.temporal.io/sdk/interceptor" ) diff --git a/aggregatedpool/local_activity.go b/aggregatedpool/local_activity.go index ebd3fe1c..46627f42 100644 --- a/aggregatedpool/local_activity.go +++ b/aggregatedpool/local_activity.go @@ -7,10 +7,10 @@ import ( "github.com/google/uuid" "github.com/roadrunner-server/errors" - "github.com/roadrunner-server/goridge/v3/pkg/frame" - "github.com/roadrunner-server/pool/payload" - "github.com/temporalio/roadrunner-temporal/v5/api" - "github.com/temporalio/roadrunner-temporal/v5/internal" + "github.com/roadrunner-server/goridge/v4/pkg/frame" + "github.com/roadrunner-server/pool/v2/payload" + "github.com/temporalio/roadrunner-temporal/v6/api" + "github.com/temporalio/roadrunner-temporal/v6/internal" commonpb "go.temporal.io/api/common/v1" tActivity "go.temporal.io/sdk/activity" "go.temporal.io/sdk/temporal" diff --git a/aggregatedpool/workers.go b/aggregatedpool/workers.go index fcbc9c45..c4d41f33 100644 --- a/aggregatedpool/workers.go +++ b/aggregatedpool/workers.go @@ -6,8 +6,8 @@ import ( "github.com/google/uuid" "github.com/roadrunner-server/errors" - "github.com/temporalio/roadrunner-temporal/v5/api" - "github.com/temporalio/roadrunner-temporal/v5/internal" + "github.com/temporalio/roadrunner-temporal/v6/api" + "github.com/temporalio/roadrunner-temporal/v6/internal" tActivity "go.temporal.io/sdk/activity" temporalClient "go.temporal.io/sdk/client" "go.temporal.io/sdk/converter" diff --git a/aggregatedpool/workers_test.go b/aggregatedpool/workers_test.go index a98c3e0d..be378ba3 100644 --- a/aggregatedpool/workers_test.go +++ b/aggregatedpool/workers_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/temporalio/roadrunner-temporal/v5/api" + "github.com/temporalio/roadrunner-temporal/v6/api" commonpb "go.temporal.io/api/common/v1" "go.temporal.io/sdk/converter" sdkinterceptor "go.temporal.io/sdk/interceptor" diff --git a/aggregatedpool/workflow.go b/aggregatedpool/workflow.go index 3d43d8bd..93f0ecc3 100644 --- a/aggregatedpool/workflow.go +++ b/aggregatedpool/workflow.go @@ -9,12 +9,12 @@ import ( "time" "github.com/google/uuid" - "github.com/roadrunner-server/pool/payload" - "github.com/temporalio/roadrunner-temporal/v5/api" - "github.com/temporalio/roadrunner-temporal/v5/canceller" - "github.com/temporalio/roadrunner-temporal/v5/internal" - "github.com/temporalio/roadrunner-temporal/v5/queue" - "github.com/temporalio/roadrunner-temporal/v5/registry" + "github.com/roadrunner-server/pool/v2/payload" + "github.com/temporalio/roadrunner-temporal/v6/api" + "github.com/temporalio/roadrunner-temporal/v6/canceller" + "github.com/temporalio/roadrunner-temporal/v6/internal" + "github.com/temporalio/roadrunner-temporal/v6/queue" + "github.com/temporalio/roadrunner-temporal/v6/registry" commonpb "go.temporal.io/api/common/v1" enumspb "go.temporal.io/api/enums/v1" temporalClient "go.temporal.io/sdk/client" diff --git a/api/interfaces.go b/api/interfaces.go index 7abb0e19..c6dc3190 100644 --- a/api/interfaces.go +++ b/api/interfaces.go @@ -4,15 +4,15 @@ import ( "context" "time" - "github.com/roadrunner-server/pool/payload" - "github.com/roadrunner-server/pool/pool" - "github.com/roadrunner-server/pool/state/process" - "github.com/roadrunner-server/pool/worker" - "github.com/temporalio/roadrunner-temporal/v5/internal" + "github.com/roadrunner-server/pool/v2/payload" + "github.com/roadrunner-server/pool/v2/pool" + "github.com/roadrunner-server/pool/v2/state/process" + "github.com/roadrunner-server/pool/v2/worker" + "github.com/temporalio/roadrunner-temporal/v6/internal" "go.temporal.io/sdk/interceptor" "go.uber.org/zap" - staticPool "github.com/roadrunner-server/pool/pool/static_pool" + staticPool "github.com/roadrunner-server/pool/v2/pool/static_pool" ) type Interceptor interface { diff --git a/config.go b/config.go index 9ac789e4..6eda6301 100644 --- a/config.go +++ b/config.go @@ -6,7 +6,7 @@ import ( "time" "github.com/roadrunner-server/errors" - "github.com/roadrunner-server/pool/pool" + "github.com/roadrunner-server/pool/v2/pool" ) // Config of the temporal client and dependent services. diff --git a/go.mod b/go.mod index bdf5a930..734ebd00 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/temporalio/roadrunner-temporal/v5 +module github.com/temporalio/roadrunner-temporal/v6 go 1.26.3 @@ -6,11 +6,9 @@ require ( github.com/goccy/go-json v0.10.6 github.com/google/uuid v1.6.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 // indirect - github.com/roadrunner-server/api/v4 v4.24.0 github.com/roadrunner-server/endure/v2 v2.6.2 github.com/roadrunner-server/errors v1.5.0 github.com/roadrunner-server/events v1.0.1 - github.com/roadrunner-server/pool v1.1.3 github.com/stretchr/testify v1.11.1 github.com/uber-go/tally/v4 v4.1.17 go.temporal.io/api v1.62.13 @@ -39,7 +37,6 @@ require ( github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.68.1 // indirect github.com/prometheus/procfs v0.20.1 // indirect - github.com/roadrunner-server/goridge/v3 v3.8.3 github.com/robfig/cron v1.2.0 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect @@ -61,6 +58,14 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect ) +require ( + connectrpc.com/connect v1.20.0 + github.com/roadrunner-server/api-go/v6 v6.0.0-beta.12.0.20260610203904-09df89976edc + github.com/roadrunner-server/api-plugins/v6 v6.0.0-beta.2 + github.com/roadrunner-server/goridge/v4 v4.0.0-beta.2 + github.com/roadrunner-server/pool/v2 v2.0.0-beta.1 +) + require ( github.com/nexus-rpc/nexus-proto-annotations v0.1.0 // indirect go.opentelemetry.io/otel v1.44.0 // indirect diff --git a/go.sum b/go.sum index 25ecf3ee..f48e981b 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +connectrpc.com/connect v1.20.0 h1:6TNDAB+WeNd2uolWNlYczB5E0KNNaVMNUEx8JEUsPmQ= +connectrpc.com/connect v1.20.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -173,18 +175,20 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= -github.com/roadrunner-server/api/v4 v4.24.0 h1:99lN8nu7aD76d1fru4+MZkf9m8+YJ22Jy+qVoDwn4OY= -github.com/roadrunner-server/api/v4 v4.24.0/go.mod h1:O0LputszJr6NXMw0SKyWaiS/C9K6JVh9HV2BHKXeosA= +github.com/roadrunner-server/api-go/v6 v6.0.0-beta.12.0.20260610203904-09df89976edc h1:tJhOZ31bN0HVO4JTgkcjHK1MLu8Waee+rFnbx5AjXyQ= +github.com/roadrunner-server/api-go/v6 v6.0.0-beta.12.0.20260610203904-09df89976edc/go.mod h1:prGWJ2GoF5YD5PIG7Tb6VKulU3bWoFwr9DCwgxheb80= +github.com/roadrunner-server/api-plugins/v6 v6.0.0-beta.2 h1:GqsZzWQ5jMXRF1O/b8IqFz9PLpS7Ui0K4OyACLql2MI= +github.com/roadrunner-server/api-plugins/v6 v6.0.0-beta.2/go.mod h1:2v4yUK5Kvbvq8C3IkDoBkuamq9h+7i/JLjyf7k1j5JM= github.com/roadrunner-server/endure/v2 v2.6.2 h1:sIB4kTyE7gtT3fDhuYWUYn6Vt/dcPtiA6FoNS1eS+84= github.com/roadrunner-server/endure/v2 v2.6.2/go.mod h1:t/2+xpNYgGBwhzn83y2MDhvhZ19UVq1REcvqn7j7RB8= github.com/roadrunner-server/errors v1.5.0 h1:unG7LKIZrSzkCCF3YLRLA5VyqE0KKomofXVJUXJe00g= github.com/roadrunner-server/errors v1.5.0/go.mod h1:g9fo/T2C13cWRDR9PW1r0ZAOSQfNhWAZawyfkGiaHuI= github.com/roadrunner-server/events v1.0.1 h1:waCkKhxhzdK3VcI1xG22l+h+0J+Nfdpxjhyy01Un+kI= github.com/roadrunner-server/events v1.0.1/go.mod h1:WZRqoEVaFm209t52EuoT7ISUtvX6BrCi6bI/7pjkVC0= -github.com/roadrunner-server/goridge/v3 v3.8.3 h1:XmjrOFnI6ZbQTPaP39DEk8KwLUNTgjluK3pcZaW6ixQ= -github.com/roadrunner-server/goridge/v3 v3.8.3/go.mod h1:4TZU8zgkKIZCsH51qwGMpvyXCT59u/8z6q8sCe4ZGAQ= -github.com/roadrunner-server/pool v1.1.3 h1:KMsiL6yuYBWGk73bdO0akwP+fJ63bxDF972JukCGsxI= -github.com/roadrunner-server/pool v1.1.3/go.mod h1:8ceC7NvZKJRciv+KJmcyk5CeDugoel6GD+crm5kBFW0= +github.com/roadrunner-server/goridge/v4 v4.0.0-beta.2 h1:MgH6oiSgcl+vphsQ6JpyedkXQ/DPf8zVpn0z7rdBp10= +github.com/roadrunner-server/goridge/v4 v4.0.0-beta.2/go.mod h1:Wv9CBO9VIU92e5iZIuehLHKakXgMkOzxoT4/oHDjIUA= +github.com/roadrunner-server/pool/v2 v2.0.0-beta.1 h1:jpYXFtdD6QGAdAGPgMxrNi3j1CegCRpb2y+A+3GnXFA= +github.com/roadrunner-server/pool/v2 v2.0.0-beta.1/go.mod h1:Bo1wT7RtL3eyQHXBUohNhtj/yAmRt6Rq8smuBg5pWkY= github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= diff --git a/go.work.sum b/go.work.sum index 9d485283..24084c55 100644 --- a/go.work.sum +++ b/go.work.sum @@ -595,6 +595,8 @@ codeberg.org/go-latex/latex v0.1.0 h1:hoGO86rIbWVyjtlDLzCqZPjNykpWQ9YuTZqAzPcfL3 codeberg.org/go-latex/latex v0.1.0/go.mod h1:LA0q/AyWIYrqVd+A9Upkgsb+IqPcmSTKc9Dny04MHMw= codeberg.org/go-pdf/fpdf v0.10.0 h1:u+w669foDDx5Ds43mpiiayp40Ov6sZalgcPMDBcZRd4= codeberg.org/go-pdf/fpdf v0.10.0/go.mod h1:Y0DGRAdZ0OmnZPvjbMp/1bYxmIPxm0ws4tfoPOc4LjU= +connectrpc.com/connect v1.19.2 h1:McQ83FGdzL+t60peksi0gXC7MQ/iLKgLduAnThbM0mo= +connectrpc.com/connect v1.19.2/go.mod h1:tN20fjdGlewnSFeZxLKb0xwIZ6ozc3OQs2hTXy4du9w= contrib.go.opencensus.io/exporter/stackdriver v0.13.15-0.20230702191903-2de6d2748484 h1:xRc46S76eyn4ZF3jWX8I+aUSKVLw5EQ1aDvHwfV5W1o= contrib.go.opencensus.io/exporter/stackdriver v0.13.15-0.20230702191903-2de6d2748484/go.mod h1:uxw+4/0SiKbbVSD/F2tk5pJTdVcfIBBcsQ8gwcu4X+E= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= diff --git a/info.go b/info.go index e4d5592c..5623cb4e 100644 --- a/info.go +++ b/info.go @@ -5,10 +5,10 @@ import ( "time" "github.com/roadrunner-server/errors" - "github.com/roadrunner-server/goridge/v3/pkg/frame" - "github.com/roadrunner-server/pool/payload" - "github.com/temporalio/roadrunner-temporal/v5/api" - "github.com/temporalio/roadrunner-temporal/v5/internal" + "github.com/roadrunner-server/goridge/v4/pkg/frame" + "github.com/roadrunner-server/pool/v2/payload" + "github.com/temporalio/roadrunner-temporal/v6/api" + "github.com/temporalio/roadrunner-temporal/v6/internal" ) func WorkerInfo(c api.Codec, p api.Pool, rrVersion string, wwPID int) ([]*internal.WorkerInfo, error) { diff --git a/internal.go b/internal.go index 16584226..3982613f 100644 --- a/internal.go +++ b/internal.go @@ -7,11 +7,11 @@ import ( "time" "github.com/roadrunner-server/errors" - "github.com/roadrunner-server/pool/pool" - "github.com/temporalio/roadrunner-temporal/v5/aggregatedpool" - "github.com/temporalio/roadrunner-temporal/v5/dataconverter" - "github.com/temporalio/roadrunner-temporal/v5/internal/codec/proto" - "github.com/temporalio/roadrunner-temporal/v5/internal/logger" + "github.com/roadrunner-server/pool/v2/pool" + "github.com/temporalio/roadrunner-temporal/v6/aggregatedpool" + "github.com/temporalio/roadrunner-temporal/v6/dataconverter" + "github.com/temporalio/roadrunner-temporal/v6/internal/codec/proto" + "github.com/temporalio/roadrunner-temporal/v6/internal/logger" tclient "go.temporal.io/sdk/client" "go.temporal.io/sdk/converter" "go.temporal.io/sdk/worker" @@ -19,7 +19,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/metadata" - staticPool "github.com/roadrunner-server/pool/pool/static_pool" + staticPool "github.com/roadrunner-server/pool/v2/pool/static_pool" ) const ( diff --git a/internal/codec/proto/proto.go b/internal/codec/proto/proto.go index d3e4a7e9..8cf15a8e 100644 --- a/internal/codec/proto/proto.go +++ b/internal/codec/proto/proto.go @@ -4,10 +4,10 @@ import ( "sync" "github.com/goccy/go-json" - protocolV1 "github.com/roadrunner-server/api/v4/build/temporal/v1" + protocolV1 "github.com/roadrunner-server/api-go/v6/temporal/v1" "github.com/roadrunner-server/errors" - "github.com/roadrunner-server/pool/payload" - "github.com/temporalio/roadrunner-temporal/v5/internal" + "github.com/roadrunner-server/pool/v2/payload" + "github.com/temporalio/roadrunner-temporal/v6/internal" "go.temporal.io/sdk/converter" "go.uber.org/zap" "google.golang.org/protobuf/proto" diff --git a/metrics.go b/metrics.go index c54c9347..33e7e186 100644 --- a/metrics.go +++ b/metrics.go @@ -8,8 +8,8 @@ import ( "github.com/cactus/go-statsd-client/v5/statsd" prom "github.com/prometheus/client_golang/prometheus" "github.com/roadrunner-server/errors" - "github.com/roadrunner-server/pool/fsm" - "github.com/roadrunner-server/pool/state/process" + "github.com/roadrunner-server/pool/v2/fsm" + "github.com/roadrunner-server/pool/v2/state/process" "github.com/uber-go/tally/v4" "github.com/uber-go/tally/v4/prometheus" tclient "go.temporal.io/sdk/client" diff --git a/status.go b/status.go index 3b647eba..a87e8da0 100644 --- a/status.go +++ b/status.go @@ -3,9 +3,9 @@ package rrtemporal import ( "net/http" - "github.com/roadrunner-server/pool/fsm" + "github.com/roadrunner-server/pool/v2/fsm" - "github.com/roadrunner-server/api/v4/plugins/v1/status" + "github.com/roadrunner-server/api-plugins/v6/status" ) // Status return status of the particular plugin From 713dd69f21f1182eeede75ae4347592bf50d45e1 Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Wed, 10 Jun 2026 23:08:06 +0200 Subject: [PATCH 02/11] feature: migrate the control rpc to connect --- plugin.go | 21 ++++--- rpc.go | 181 ++++++++++++++++++++++++------------------------------ 2 files changed, 93 insertions(+), 109 deletions(-) diff --git a/plugin.go b/plugin.go index 340b4061..303282b4 100644 --- a/plugin.go +++ b/plugin.go @@ -11,20 +11,23 @@ import ( "sync/atomic" "time" + "net/http" + + "github.com/roadrunner-server/api-go/v6/temporal/v1/temporalV1connect" "github.com/roadrunner-server/endure/v2/dep" "github.com/roadrunner-server/errors" "github.com/roadrunner-server/events" - "github.com/roadrunner-server/pool/state/process" - "github.com/temporalio/roadrunner-temporal/v5/aggregatedpool" - "github.com/temporalio/roadrunner-temporal/v5/api" - "github.com/temporalio/roadrunner-temporal/v5/internal" - "github.com/temporalio/roadrunner-temporal/v5/internal/codec/proto" + "github.com/roadrunner-server/pool/v2/state/process" + "github.com/temporalio/roadrunner-temporal/v6/aggregatedpool" + "github.com/temporalio/roadrunner-temporal/v6/api" + "github.com/temporalio/roadrunner-temporal/v6/internal" + "github.com/temporalio/roadrunner-temporal/v6/internal/codec/proto" tclient "go.temporal.io/sdk/client" "go.temporal.io/sdk/converter" "go.temporal.io/sdk/worker" "go.uber.org/zap" - "github.com/roadrunner-server/pool/pool/static_pool" + "github.com/roadrunner-server/pool/v2/pool/static_pool" ) const ( @@ -417,8 +420,10 @@ func (p *Plugin) Name() string { return pluginName } -func (p *Plugin) RPC() any { - return &rpc{plugin: p, client: p.temporal.client} +// RPC returns the TemporalService connect handler mounted on the rpc plugin's +// server. +func (p *Plugin) RPC() (string, http.Handler) { + return temporalV1connect.NewTemporalServiceHandler(&rpc{plugin: p}) } func ptr[T any](v T) *T { diff --git a/rpc.go b/rpc.go index abaf8fc0..0e7935f8 100644 --- a/rpc.go +++ b/rpc.go @@ -6,15 +6,16 @@ import ( "os" "time" - commonV1 "github.com/roadrunner-server/api/v4/build/common/v1" - protoApi "github.com/roadrunner-server/api/v4/build/temporal/v1" + "connectrpc.com/connect" + commonV1 "github.com/roadrunner-server/api-go/v6/common/v1" + protoApi "github.com/roadrunner-server/api-go/v6/temporal/v1" + "github.com/roadrunner-server/api-go/v6/temporal/v1/temporalV1connect" "github.com/roadrunner-server/errors" - "github.com/temporalio/roadrunner-temporal/v5/internal/logger" + "github.com/temporalio/roadrunner-temporal/v6/internal/logger" commonpb "go.temporal.io/api/common/v1" "go.temporal.io/api/enums/v1" "go.temporal.io/api/history/v1" "go.temporal.io/sdk/activity" - "go.temporal.io/sdk/client" "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" "go.uber.org/zap" @@ -23,56 +24,37 @@ import ( "google.golang.org/protobuf/proto" ) -/* -- the method's type is exported. -- the method is exported. -- the method has two arguments, both exported (or builtin) types. -- the method's second argument is a pointer. -- the method has return type error. -*/ +// rpc exposes the temporal plugin control API (temporal.v1.TemporalService) +// on the RoadRunner Connect-RPC plane. type rpc struct { plugin *Plugin - client client.Client } -// RecordHeartbeatRequest sent by activity to record current state. -type RecordHeartbeatRequest struct { - TaskToken []byte `json:"taskToken"` - Details []byte `json:"details"` -} - -// RecordHeartbeatResponse sent back to the worker to indicate that activity was canceled. -type RecordHeartbeatResponse struct { - Canceled bool `json:"canceled"` - Paused bool `json:"paused"` -} +// Compile-time check that rpc implements the generated handler interface. +var _ temporalV1connect.TemporalServiceHandler = (*rpc)(nil) -// RecordActivityHeartbeat records heartbeat for an activity. -// taskToken - is the value of the binary "TaskToken" field of the "ActivityInfo" struct retrieved inside the activity. -// details - is the progress you want to record along with heart beat for this activity. -// The errors it can return: -// - EntityNotExistsError -// - InternalServiceError -// - CanceledError -func (r *rpc) RecordActivityHeartbeat(in RecordHeartbeatRequest, out *RecordHeartbeatResponse) error { +// RecordActivityHeartbeat records a heartbeat for an activity. +// task_token - is the value of the binary "TaskToken" field of the "ActivityInfo" struct retrieved inside the activity. +// details - is the progress you want to record along with the heartbeat for this activity. +func (r *rpc) RecordActivityHeartbeat(_ context.Context, req *connect.Request[protoApi.RecordHeartbeatRequest]) (*connect.Response[protoApi.RecordHeartbeatResponse], error) { details := &commonpb.Payloads{} - if len(in.Details) != 0 { - if err := proto.Unmarshal(in.Details, details); err != nil { - return err + if len(req.Msg.GetDetails()) != 0 { + if err := proto.Unmarshal(req.Msg.GetDetails(), details); err != nil { + return nil, connect.NewError(connect.CodeInvalidArgument, err) } } if r.plugin.getActDef() == nil { - return errors.Str("no activity definition registered") + return nil, connect.NewError(connect.CodeFailedPrecondition, errors.Str("no activity definition registered")) } // find running activity r.plugin.mu.RLock() - ctx, err := r.plugin.temporal.rrActivityDef.GetActivityContext(in.TaskToken) + ctx, err := r.plugin.temporal.rrActivityDef.GetActivityContext(req.Msg.GetTaskToken()) if err != nil { r.plugin.mu.RUnlock() - return err + return nil, err } r.plugin.mu.RUnlock() @@ -81,65 +63,63 @@ func (r *rpc) RecordActivityHeartbeat(in RecordHeartbeatRequest, out *RecordHear err = context.Cause(ctx) if err != nil { if stderr.Is(err, activity.ErrActivityPaused) { - *out = RecordHeartbeatResponse{Paused: true} - return nil + return connect.NewResponse(&protoApi.RecordHeartbeatResponse{Paused: true}), nil } } + out := &protoApi.RecordHeartbeatResponse{} select { case <-ctx.Done(): - *out = RecordHeartbeatResponse{Canceled: true} + out.Canceled = true default: - *out = RecordHeartbeatResponse{Canceled: false} + out.Canceled = false } - return nil + return connect.NewResponse(out), nil } -func (r *rpc) GetActivityNames(_ bool, out *[]string) error { +func (r *rpc) GetActivityNames(_ context.Context, _ *connect.Request[protoApi.GetNamesRequest]) (*connect.Response[protoApi.NamesList], error) { r.plugin.mu.RLock() defer r.plugin.mu.RUnlock() + + out := &protoApi.NamesList{} for k := range r.plugin.temporal.activities { - *out = append(*out, k) + out.Names = append(out.Names, k) } - return nil + + return connect.NewResponse(out), nil } -func (r *rpc) GetWorkflowNames(_ bool, out *[]string) error { +func (r *rpc) GetWorkflowNames(_ context.Context, _ *connect.Request[protoApi.GetNamesRequest]) (*connect.Response[protoApi.NamesList], error) { r.plugin.mu.RLock() defer r.plugin.mu.RUnlock() + out := &protoApi.NamesList{} for k := range r.plugin.temporal.workflows { - *out = append(*out, k) + out.Names = append(out.Names, k) } - return nil + return connect.NewResponse(out), nil } -func (r *rpc) ReplayWorkflow(in *protoApi.ReplayRequest, out *protoApi.ReplayResponse) error { +func (r *rpc) ReplayWorkflow(_ context.Context, req *connect.Request[protoApi.ReplayRequest]) (*connect.Response[protoApi.ReplayResponse], error) { + in := req.Msg + out := &protoApi.ReplayResponse{} + r.plugin.log.Debug("replay workflow request", zap.String("run_id", in.GetWorkflowExecution().GetRunId()), zap.String("workflow_id", in.GetWorkflowExecution().GetWorkflowId()), zap.String("workflow_name", in.GetWorkflowType().GetName())) - if in.GetWorkflowExecution() == nil || in.GetWorkflowType() == nil { - out.Status = &commonV1.Status{ - Code: int32(codes.InvalidArgument), - Message: "run_id, workflow_id or workflow_name should not be empty", - } - - r.plugin.log.Error("replay workflow request", zap.String("error", "run_id, workflow_id or workflow_name should not be empty")) - return nil - } - - if in.GetWorkflowExecution().GetRunId() == "" || in.GetWorkflowExecution().GetWorkflowId() == "" || in.GetWorkflowType().GetName() == "" { + if in.GetWorkflowExecution() == nil || in.GetWorkflowType() == nil || + in.GetWorkflowExecution().GetRunId() == "" || in.GetWorkflowExecution().GetWorkflowId() == "" || in.GetWorkflowType().GetName() == "" { out.Status = &commonV1.Status{ Code: int32(codes.InvalidArgument), Message: "run_id, workflow_id or workflow_name should not be empty", } r.plugin.log.Error("replay workflow request", zap.String("error", "run_id, workflow_id or workflow_name should not be empty")) - return nil + return connect.NewResponse(out), nil } ctx, cancel := context.WithTimeout(context.Background(), time.Minute) @@ -156,7 +136,7 @@ func (r *rpc) ReplayWorkflow(in *protoApi.ReplayRequest, out *protoApi.ReplayRes } r.plugin.log.Error("history iteration error", zap.Error(err)) - return nil + return connect.NewResponse(out), nil } hist.Events = append(hist.Events, event) } @@ -167,7 +147,7 @@ func (r *rpc) ReplayWorkflow(in *protoApi.ReplayRequest, out *protoApi.ReplayRes Message: "workflow definition is not initialized, retry in a second", } - return nil + return connect.NewResponse(out), nil } replayer := worker.NewWorkflowReplayer() @@ -184,7 +164,7 @@ func (r *rpc) ReplayWorkflow(in *protoApi.ReplayRequest, out *protoApi.ReplayRes } r.plugin.log.Error("replay error", zap.Error(err)) - return nil + return connect.NewResponse(out), nil } out.Status = &commonV1.Status{ @@ -193,32 +173,27 @@ func (r *rpc) ReplayWorkflow(in *protoApi.ReplayRequest, out *protoApi.ReplayRes r.plugin.log.Debug("replay workflow request finished successfully") - return nil + return connect.NewResponse(out), nil } -func (r *rpc) DownloadWorkflowHistory(in *protoApi.ReplayRequest, out *protoApi.ReplayResponse) error { +func (r *rpc) DownloadWorkflowHistory(_ context.Context, req *connect.Request[protoApi.ReplayRequest]) (*connect.Response[protoApi.ReplayResponse], error) { + in := req.Msg + out := &protoApi.ReplayResponse{} + r.plugin.log.Debug("replay workflow request", zap.String("run_id", in.GetWorkflowExecution().GetRunId()), zap.String("workflow_id", in.GetWorkflowExecution().GetWorkflowId()), zap.String("save_path", in.GetSavePath())) - if in.GetWorkflowExecution() == nil || in.GetWorkflowType() == nil || in.GetSavePath() == "" { - out.Status = &commonV1.Status{ - Code: int32(codes.InvalidArgument), - Message: "run_id, workflow_id or save_path should not be empty", - } - - return nil - } - - if in.GetWorkflowExecution().GetRunId() == "" || in.GetWorkflowExecution().GetWorkflowId() == "" || in.GetWorkflowType().GetName() == "" { + if in.GetWorkflowExecution() == nil || in.GetWorkflowType() == nil || in.GetSavePath() == "" || + in.GetWorkflowExecution().GetRunId() == "" || in.GetWorkflowExecution().GetWorkflowId() == "" || in.GetWorkflowType().GetName() == "" { out.Status = &commonV1.Status{ Code: int32(codes.InvalidArgument), Message: "run_id, workflow_id or save_path should not be empty", } r.plugin.log.Error("replay workflow request", zap.String("error", "run_id, workflow_id or save_path should not be empty")) - return nil + return connect.NewResponse(out), nil } file, err := os.Create(in.GetSavePath()) @@ -229,7 +204,7 @@ func (r *rpc) DownloadWorkflowHistory(in *protoApi.ReplayRequest, out *protoApi. } r.plugin.log.Error("failed to create the file", zap.Error(err)) - return nil + return connect.NewResponse(out), nil } defer func() { @@ -254,7 +229,7 @@ func (r *rpc) DownloadWorkflowHistory(in *protoApi.ReplayRequest, out *protoApi. } r.plugin.log.Error("history iteration error", zap.Error(errn)) - return nil + return connect.NewResponse(out), nil } hist.Events = append(hist.Events, event) @@ -268,7 +243,7 @@ func (r *rpc) DownloadWorkflowHistory(in *protoApi.ReplayRequest, out *protoApi. } r.plugin.log.Error("history marshal error", zap.Error(err)) - return nil + return connect.NewResponse(out), nil } _, err = file.Write(data) @@ -279,7 +254,7 @@ func (r *rpc) DownloadWorkflowHistory(in *protoApi.ReplayRequest, out *protoApi. } r.plugin.log.Error("history marshal error", zap.Error(err)) - return nil + return connect.NewResponse(out), nil } out.Status = &commonV1.Status{ @@ -288,10 +263,13 @@ func (r *rpc) DownloadWorkflowHistory(in *protoApi.ReplayRequest, out *protoApi. r.plugin.log.Debug("history saved", zap.String("location", in.GetSavePath())) - return nil + return connect.NewResponse(out), nil } -func (r *rpc) ReplayFromJSON(in *protoApi.ReplayRequest, out *protoApi.ReplayResponse) error { +func (r *rpc) ReplayFromJSON(_ context.Context, req *connect.Request[protoApi.ReplayRequest]) (*connect.Response[protoApi.ReplayResponse], error) { + in := req.Msg + out := &protoApi.ReplayResponse{} + r.plugin.log.Debug("replay from JSON request", zap.String("workflow_name", in.GetWorkflowType().GetName()), zap.String("save_path", in.GetSavePath()), @@ -305,7 +283,7 @@ func (r *rpc) ReplayFromJSON(in *protoApi.ReplayRequest, out *protoApi.ReplayRes } r.plugin.log.Error("replay from JSON request", zap.String("error", "workflow_name and save_path should not be empty")) - return nil + return connect.NewResponse(out), nil } if in.GetWorkflowType().GetName() == "" { @@ -315,7 +293,7 @@ func (r *rpc) ReplayFromJSON(in *protoApi.ReplayRequest, out *protoApi.ReplayRes } r.plugin.log.Error("replay from JSON request", zap.String("error", "workflow_name should not be empty")) - return nil + return connect.NewResponse(out), nil } if r.plugin.getWfDef() == nil { @@ -324,7 +302,7 @@ func (r *rpc) ReplayFromJSON(in *protoApi.ReplayRequest, out *protoApi.ReplayRes Message: "workflow definition is not initialized, retry in a second", } - return nil + return connect.NewResponse(out), nil } replayer := worker.NewWorkflowReplayer() @@ -344,7 +322,7 @@ func (r *rpc) ReplayFromJSON(in *protoApi.ReplayRequest, out *protoApi.ReplayRes } r.plugin.log.Error("replay from JSON request", zap.Error(err)) - return nil + return connect.NewResponse(out), nil } default: // we have last event ID @@ -356,7 +334,7 @@ func (r *rpc) ReplayFromJSON(in *protoApi.ReplayRequest, out *protoApi.ReplayRes } r.plugin.log.Error("replay from JSON request (partial workflow history)", zap.Int64("id", in.GetLastEventId()), zap.Error(err)) - return nil + return connect.NewResponse(out), nil } } @@ -366,10 +344,13 @@ func (r *rpc) ReplayFromJSON(in *protoApi.ReplayRequest, out *protoApi.ReplayRes r.plugin.log.Debug("replay from JSON request finished successfully") - return nil + return connect.NewResponse(out), nil } -func (r *rpc) ReplayWorkflowHistory(in *protoApi.History, out *protoApi.ReplayResponse) error { +func (r *rpc) ReplayWorkflowHistory(_ context.Context, req *connect.Request[protoApi.History]) (*connect.Response[protoApi.ReplayResponse], error) { + in := req.Msg + out := &protoApi.ReplayResponse{} + r.plugin.log.Debug("replay from workflow history request", zap.String("workflow_name", in.GetWorkflowType().GetName()), ) @@ -381,7 +362,7 @@ func (r *rpc) ReplayWorkflowHistory(in *protoApi.History, out *protoApi.ReplayRe } r.plugin.log.Error("workflow_name and/or history should not be empty") - return nil + return connect.NewResponse(out), nil } if r.plugin.getWfDef() == nil { @@ -390,7 +371,7 @@ func (r *rpc) ReplayWorkflowHistory(in *protoApi.History, out *protoApi.ReplayRe Message: "workflow definition is not initialized, retry in a second", } - return nil + return connect.NewResponse(out), nil } replayer := worker.NewWorkflowReplayer() @@ -407,7 +388,7 @@ func (r *rpc) ReplayWorkflowHistory(in *protoApi.History, out *protoApi.ReplayRe } r.plugin.log.Error("replay workflow history", zap.Error(err)) - return nil + return connect.NewResponse(out), nil } out.Status = &commonV1.Status{ @@ -416,16 +397,14 @@ func (r *rpc) ReplayWorkflowHistory(in *protoApi.History, out *protoApi.ReplayRe r.plugin.log.Debug("replay workflow request finished successfully") - return nil + return connect.NewResponse(out), nil } -func (r *rpc) UpdateAPIKey(in *string, out *bool) error { - if in != nil && *in != "" { - r.plugin.apiKey.Store(in) - *out = true - return nil +func (r *rpc) UpdateAPIKey(_ context.Context, req *connect.Request[protoApi.UpdateAPIKeyRequest]) (*connect.Response[protoApi.UpdateAPIKeyResponse], error) { + if key := req.Msg.GetApiKey(); key != "" { + r.plugin.apiKey.Store(&key) + return connect.NewResponse(&protoApi.UpdateAPIKeyResponse{Ok: true}), nil } - *out = false - return nil + return connect.NewResponse(&protoApi.UpdateAPIKeyResponse{Ok: false}), nil } From cb40a956ee5cd5c5a5286292bf3efe42e36e36c1 Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Wed, 10 Jun 2026 23:08:06 +0200 Subject: [PATCH 03/11] chore: port integration tests to the connect clients --- tests/general/disaster_test.go | 58 ++++++---------------------- tests/general/general_test.go | 18 +-------- tests/general/hp_test.go | 26 ++++--------- tests/general/plugin_status_test.go | 2 +- tests/general/rpc_test.go | 37 ++++++------------ tests/go.mod | 15 ++++--- tests/go.sum | 10 +++++ tests/helpers/helpers.go | 4 +- tests/helpers/rpc.go | 42 ++++++++++++++++++++ tests/tls/disaster_tls_test.go | 58 ++++++---------------------- tests/tls/hp_tls_test.go | 26 ++++--------- tests/updates/updates_replay_test.go | 35 +++++------------ 12 files changed, 125 insertions(+), 206 deletions(-) create mode 100644 tests/helpers/rpc.go diff --git a/tests/general/disaster_test.go b/tests/general/disaster_test.go index 05f46d8c..c857ae5c 100644 --- a/tests/general/disaster_test.go +++ b/tests/general/disaster_test.go @@ -2,8 +2,6 @@ package tests import ( "context" - "net" - "net/rpc" "os" "sync" "syscall" @@ -12,8 +10,8 @@ import ( "tests/helpers" - goridgeRpc "github.com/roadrunner-server/goridge/v3/pkg/rpc" - "github.com/roadrunner-server/pool/state/process" + informerV1 "github.com/roadrunner-server/api-go/v6/informer/v1" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.temporal.io/sdk/client" @@ -238,19 +236,10 @@ func Test_WorkerError_DisasterRecovery_Heavy(t *testing.T) { // Makes worker pool unable to recover for some time require.NoError(t, os.Rename("../php_test_files/worker.php", "../php_test_files/worker.bak")) - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - err = c.Call("informer.Workers", "temporal", &list) + list, err := helpers.Workers(t.Context()) require.NoError(t, err) - p, err := os.FindProcess(int(list.Workers[0].Pid)) + p, err := os.FindProcess(int(list[0].GetPid())) assert.NoError(t, err) // must fully recover with new worker @@ -341,19 +330,10 @@ func Test_WorkerError_DisasterRecovery_HeavyLA(t *testing.T) { // Makes worker pool unable to recover for some time require.NoError(t, os.Rename("../php_test_files/worker-la.php", "../php_test_files/worker-la.bak")) - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - err = c.Call("informer.Workers", "temporal", &list) + list, err := helpers.Workers(t.Context()) require.NoError(t, err) - p, err := os.FindProcess(int(list.Workers[0].Pid)) + p, err := os.FindProcess(int(list[0].GetPid())) assert.NoError(t, err) // must fully recover with new worker @@ -585,30 +565,14 @@ func Test_ActivityErrorLA_DisasterRecoveryProto(t *testing.T) { wg.Wait() } -func getWorkers(t *testing.T) []process.State { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - err = c.Call("informer.Workers", "temporal", &list) +func getWorkers(t *testing.T) []*informerV1.ProcessState { + list, err := helpers.Workers(t.Context()) assert.NoError(t, err) - assert.Len(t, list.Workers, 5) + assert.Len(t, list, 5) - return list.Workers + return list } func reset(t *testing.T) { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - var ret bool - err = c.Call("resetter.Reset", "temporal", &ret) - assert.NoError(t, err) - require.True(t, ret) + require.NoError(t, helpers.Reset(t.Context())) } diff --git a/tests/general/general_test.go b/tests/general/general_test.go index 133807a0..d6e79db1 100644 --- a/tests/general/general_test.go +++ b/tests/general/general_test.go @@ -3,18 +3,13 @@ package tests import ( "context" "io" - "net" "net/http" - "net/rpc" "sync" "testing" "time" "github.com/stretchr/testify/require" - goridgeRpc "github.com/roadrunner-server/goridge/v3/pkg/rpc" - "github.com/roadrunner-server/pool/state/process" - "tests/helpers" "github.com/stretchr/testify/assert" @@ -125,16 +120,7 @@ func Test_DisabledActivityWorkers(t *testing.T) { } func assertWorkers(t *testing.T, workers int) { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - err = c.Call("informer.Workers", "temporal", &list) + list, err := helpers.Workers(t.Context()) assert.NoError(t, err) - assert.Len(t, list.Workers, workers) + assert.Len(t, list, workers) } diff --git a/tests/general/hp_test.go b/tests/general/hp_test.go index a7b1edca..0903e223 100644 --- a/tests/general/hp_test.go +++ b/tests/general/hp_test.go @@ -5,15 +5,15 @@ import ( "crypto/rand" "crypto/sha512" "fmt" - "net" - "net/rpc" "strconv" "sync" "testing" "tests/helpers" "time" - goridgeRpc "github.com/roadrunner-server/goridge/v3/pkg/rpc" + protoApi "github.com/roadrunner-server/api-go/v6/temporal/v1" + + "connectrpc.com/connect" "github.com/stretchr/testify/require" "go.temporal.io/api/common/v1" @@ -869,27 +869,15 @@ func Test_SagaWorkflowLAProto(t *testing.T) { } func getActivities(t *testing.T) []string { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - res := make([]string, 0, 10) - - err = c.Call("temporal.GetActivityNames", true, &res) + resp, err := helpers.TemporalClient().GetActivityNames(t.Context(), connect.NewRequest(&protoApi.GetNamesRequest{})) assert.NoError(t, err) - return res + return resp.Msg.GetNames() } func getWorkflows(t *testing.T) []string { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - res := make([]string, 0, 10) - - err = c.Call("temporal.GetWorkflowNames", true, &res) + resp, err := helpers.TemporalClient().GetWorkflowNames(t.Context(), connect.NewRequest(&protoApi.GetNamesRequest{})) assert.NoError(t, err) - return res + return resp.Msg.GetNames() } diff --git a/tests/general/plugin_status_test.go b/tests/general/plugin_status_test.go index b0a1173a..cbeeaf26 100644 --- a/tests/general/plugin_status_test.go +++ b/tests/general/plugin_status_test.go @@ -18,7 +18,7 @@ import ( "github.com/roadrunner-server/server/v5" "github.com/roadrunner-server/status/v5" "github.com/stretchr/testify/require" - rrtemporal "github.com/temporalio/roadrunner-temporal/v5" + rrtemporal "github.com/temporalio/roadrunner-temporal/v6" "github.com/stretchr/testify/assert" ) diff --git a/tests/general/rpc_test.go b/tests/general/rpc_test.go index 74c6af13..0fb66a97 100644 --- a/tests/general/rpc_test.go +++ b/tests/general/rpc_test.go @@ -2,27 +2,20 @@ package tests import ( "context" - "net" - "net/rpc" "path" "sync" "testing" "tests/helpers" "time" - protoApi "github.com/roadrunner-server/api/v4/build/temporal/v1" - goridgeRpc "github.com/roadrunner-server/goridge/v3/pkg/rpc" + "connectrpc.com/connect" + protoApi "github.com/roadrunner-server/api-go/v6/temporal/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.temporal.io/api/common/v1" "go.temporal.io/sdk/client" ) -const ( - download string = "temporal.DownloadWorkflowHistory" - replay string = "temporal.ReplayFromJSON" -) - func Test_RPC_Methods(t *testing.T) { stopCh := make(chan struct{}, 1) wg := &sync.WaitGroup{} @@ -60,20 +53,16 @@ func Test_RPC_Methods(t *testing.T) { time.Sleep(time.Second) tmp := path.Join(t.TempDir(), "replay.json") - t.Run("downloadWFHistory", downloadWFHistory("127.0.0.1:6001", w.GetID(), w.GetRunID(), "HistoryLengthWorkflow", tmp)) - t.Run("replayFromJSON", replayFromJSON("127.0.0.1:6001", tmp, "HistoryLengthWorkflow")) + t.Run("downloadWFHistory", downloadWFHistory(w.GetID(), w.GetRunID(), "HistoryLengthWorkflow", tmp)) + t.Run("replayFromJSON", replayFromJSON(tmp, "HistoryLengthWorkflow")) stopCh <- struct{}{} wg.Wait() time.Sleep(time.Second) } -func downloadWFHistory(address, wid, rid, wname, path string) func(t *testing.T) { +func downloadWFHistory(wid, rid, wname, path string) func(t *testing.T) { return func(t *testing.T) { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", address) - require.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - req := &protoApi.ReplayRequest{ SavePath: path, WorkflowType: &common.WorkflowType{ @@ -84,26 +73,24 @@ func downloadWFHistory(address, wid, rid, wname, path string) func(t *testing.T) RunId: rid, }, } - resp := &protoApi.ReplayResponse{} - err = client.Call(download, req, resp) + + resp, err := helpers.TemporalClient().DownloadWorkflowHistory(t.Context(), connect.NewRequest(req)) require.NoError(t, err) + require.Zero(t, resp.Msg.GetStatus().GetCode()) } } -func replayFromJSON(address, path, wname string) func(t *testing.T) { +func replayFromJSON(path, wname string) func(t *testing.T) { return func(t *testing.T) { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", address) - require.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - req := &protoApi.ReplayRequest{ SavePath: path, WorkflowType: &common.WorkflowType{ Name: wname, }, } - resp := &protoApi.ReplayResponse{} - err = client.Call(replay, req, resp) + + resp, err := helpers.TemporalClient().ReplayFromJSON(t.Context(), connect.NewRequest(req)) require.NoError(t, err) + require.Zero(t, resp.Msg.GetStatus().GetCode()) } } diff --git a/tests/go.mod b/tests/go.mod index 17d9fe7e..db61504c 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -3,21 +3,20 @@ module tests go 1.26.3 require ( + connectrpc.com/connect v1.20.0 github.com/fatih/color v1.19.0 github.com/pborman/uuid v1.2.1 - github.com/roadrunner-server/api/v4 v4.24.0 + github.com/roadrunner-server/api-go/v6 v6.0.0-beta.12.0.20260610203904-09df89976edc github.com/roadrunner-server/config/v5 v5.1.9 github.com/roadrunner-server/endure/v2 v2.6.2 - github.com/roadrunner-server/goridge/v3 v3.8.3 github.com/roadrunner-server/informer/v5 v5.1.9 github.com/roadrunner-server/logger/v5 v5.1.9 - github.com/roadrunner-server/pool v1.1.3 github.com/roadrunner-server/resetter/v5 v5.1.9 github.com/roadrunner-server/rpc/v5 v5.1.9 github.com/roadrunner-server/server/v5 v5.2.10 github.com/roadrunner-server/status/v5 v5.1.9 github.com/stretchr/testify v1.11.1 - github.com/temporalio/roadrunner-temporal/v5 v5.11.0 + github.com/temporalio/roadrunner-temporal/v6 v6.0.0-00010101000000-000000000000 go.opentelemetry.io/otel/sdk v1.44.0 go.temporal.io/api v1.62.13 go.temporal.io/sdk v1.44.1 @@ -27,7 +26,7 @@ require ( replace github.com/uber-go/tally/v4 => github.com/uber-go/tally/v4 v4.1.10 -replace github.com/temporalio/roadrunner-temporal/v5 => ../ +replace github.com/temporalio/roadrunner-temporal/v6 => ../ require ( github.com/beorn7/perks v1.0.1 // indirect @@ -59,8 +58,14 @@ require ( github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.68.1 // indirect github.com/prometheus/procfs v0.20.1 // indirect + github.com/roadrunner-server/api-plugins/v6 v6.0.0-beta.2 // indirect + github.com/roadrunner-server/api/v4 v4.24.0 // indirect github.com/roadrunner-server/errors v1.5.0 // indirect github.com/roadrunner-server/events v1.0.1 // indirect + github.com/roadrunner-server/goridge/v3 v3.8.3 // indirect + github.com/roadrunner-server/goridge/v4 v4.0.0-beta.2 // indirect + github.com/roadrunner-server/pool v1.1.3 // indirect + github.com/roadrunner-server/pool/v2 v2.0.0-beta.1 // indirect github.com/roadrunner-server/tcplisten v1.5.2 // indirect github.com/robfig/cron v1.2.0 // indirect github.com/sagikazarmark/locafero v0.12.0 // indirect diff --git a/tests/go.sum b/tests/go.sum index b8d698c1..f4f5448f 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -1,5 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +connectrpc.com/connect v1.20.0 h1:6TNDAB+WeNd2uolWNlYczB5E0KNNaVMNUEx8JEUsPmQ= +connectrpc.com/connect v1.20.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -191,6 +193,10 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= +github.com/roadrunner-server/api-go/v6 v6.0.0-beta.12.0.20260610203904-09df89976edc h1:tJhOZ31bN0HVO4JTgkcjHK1MLu8Waee+rFnbx5AjXyQ= +github.com/roadrunner-server/api-go/v6 v6.0.0-beta.12.0.20260610203904-09df89976edc/go.mod h1:prGWJ2GoF5YD5PIG7Tb6VKulU3bWoFwr9DCwgxheb80= +github.com/roadrunner-server/api-plugins/v6 v6.0.0-beta.2 h1:GqsZzWQ5jMXRF1O/b8IqFz9PLpS7Ui0K4OyACLql2MI= +github.com/roadrunner-server/api-plugins/v6 v6.0.0-beta.2/go.mod h1:2v4yUK5Kvbvq8C3IkDoBkuamq9h+7i/JLjyf7k1j5JM= github.com/roadrunner-server/api/v4 v4.24.0 h1:99lN8nu7aD76d1fru4+MZkf9m8+YJ22Jy+qVoDwn4OY= github.com/roadrunner-server/api/v4 v4.24.0/go.mod h1:O0LputszJr6NXMw0SKyWaiS/C9K6JVh9HV2BHKXeosA= github.com/roadrunner-server/config/v5 v5.1.9 h1:ReWwts/prEvuC4yVJ0BRDmY5sxw/1c+hGTSdJ71hIQU= @@ -203,12 +209,16 @@ github.com/roadrunner-server/events v1.0.1 h1:waCkKhxhzdK3VcI1xG22l+h+0J+Nfdpxjh github.com/roadrunner-server/events v1.0.1/go.mod h1:WZRqoEVaFm209t52EuoT7ISUtvX6BrCi6bI/7pjkVC0= github.com/roadrunner-server/goridge/v3 v3.8.3 h1:XmjrOFnI6ZbQTPaP39DEk8KwLUNTgjluK3pcZaW6ixQ= github.com/roadrunner-server/goridge/v3 v3.8.3/go.mod h1:4TZU8zgkKIZCsH51qwGMpvyXCT59u/8z6q8sCe4ZGAQ= +github.com/roadrunner-server/goridge/v4 v4.0.0-beta.2 h1:MgH6oiSgcl+vphsQ6JpyedkXQ/DPf8zVpn0z7rdBp10= +github.com/roadrunner-server/goridge/v4 v4.0.0-beta.2/go.mod h1:Wv9CBO9VIU92e5iZIuehLHKakXgMkOzxoT4/oHDjIUA= github.com/roadrunner-server/informer/v5 v5.1.9 h1:yl334LMqUoWXfeP4299HgY9G7mq6kX6FVCSwT+cYdfQ= github.com/roadrunner-server/informer/v5 v5.1.9/go.mod h1:JPzSsDjLHExdQ9SbT9e8H/oB7pajgCScL/G70saQzSA= github.com/roadrunner-server/logger/v5 v5.1.9 h1:3Kn+NYXF7Ww5LvkwMZwkv1q99t5qusIPBsreRJL08JI= github.com/roadrunner-server/logger/v5 v5.1.9/go.mod h1:hwct/TWTmxYsVzowLx4g9HkY5z2/gpYOC+UN8btsrAA= github.com/roadrunner-server/pool v1.1.3 h1:KMsiL6yuYBWGk73bdO0akwP+fJ63bxDF972JukCGsxI= github.com/roadrunner-server/pool v1.1.3/go.mod h1:8ceC7NvZKJRciv+KJmcyk5CeDugoel6GD+crm5kBFW0= +github.com/roadrunner-server/pool/v2 v2.0.0-beta.1 h1:jpYXFtdD6QGAdAGPgMxrNi3j1CegCRpb2y+A+3GnXFA= +github.com/roadrunner-server/pool/v2 v2.0.0-beta.1/go.mod h1:Bo1wT7RtL3eyQHXBUohNhtj/yAmRt6Rq8smuBg5pWkY= github.com/roadrunner-server/resetter/v5 v5.1.9 h1:rH1nxkgvItbMEp1/JFZqcijOkkav4zo0E4wcVXBcXa8= github.com/roadrunner-server/resetter/v5 v5.1.9/go.mod h1:P5TfzCGQMNsUDPTrjOU7XFLdRz+DtFH/FmRla+lUF94= github.com/roadrunner-server/rpc/v5 v5.1.9 h1:AbRd2xEkWY8N3J4GUhoDeL+pnfwzKHazV4k40jZ+YDk= diff --git a/tests/helpers/helpers.go b/tests/helpers/helpers.go index 2707bfad..8cb89a0e 100644 --- a/tests/helpers/helpers.go +++ b/tests/helpers/helpers.go @@ -22,8 +22,8 @@ import ( "github.com/roadrunner-server/server/v5" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - roadrunnerTemporal "github.com/temporalio/roadrunner-temporal/v5" - "github.com/temporalio/roadrunner-temporal/v5/dataconverter" + roadrunnerTemporal "github.com/temporalio/roadrunner-temporal/v6" + "github.com/temporalio/roadrunner-temporal/v6/dataconverter" "go.temporal.io/api/enums/v1" "go.temporal.io/api/history/v1" temporalClient "go.temporal.io/sdk/client" diff --git a/tests/helpers/rpc.go b/tests/helpers/rpc.go new file mode 100644 index 00000000..5181146f --- /dev/null +++ b/tests/helpers/rpc.go @@ -0,0 +1,42 @@ +package helpers + +import ( + "context" + "net/http" + + "connectrpc.com/connect" + informerV1 "github.com/roadrunner-server/api-go/v6/informer/v1" + "github.com/roadrunner-server/api-go/v6/informer/v1/informerV1connect" + resetterV1 "github.com/roadrunner-server/api-go/v6/resetter/v1" + "github.com/roadrunner-server/api-go/v6/resetter/v1/resetterV1connect" + "github.com/roadrunner-server/api-go/v6/temporal/v1/temporalV1connect" +) + +// RPCAddr is the base URL of the RoadRunner Connect-RPC plane started by the +// test configs (rpc plugin listening on 127.0.0.1:6001). +const RPCAddr = "http://127.0.0.1:6001" + +// TemporalClient returns a TemporalService client bound to the test rpc plane. +func TemporalClient() temporalV1connect.TemporalServiceClient { + return temporalV1connect.NewTemporalServiceClient(http.DefaultClient, RPCAddr) +} + +// Workers returns the temporal plugin's worker list via the informer service. +func Workers(ctx context.Context) ([]*informerV1.ProcessState, error) { + c := informerV1connect.NewInformerServiceClient(http.DefaultClient, RPCAddr) + + resp, err := c.GetWorkers(ctx, connect.NewRequest(&informerV1.GetWorkersRequest{Plugin: "temporal"})) + if err != nil { + return nil, err + } + + return resp.Msg.GetWorkers(), nil +} + +// Reset resets the temporal plugin's worker pools via the resetter service. +func Reset(ctx context.Context) error { + c := resetterV1connect.NewResetterServiceClient(http.DefaultClient, RPCAddr) + + _, err := c.Reset(ctx, connect.NewRequest(&resetterV1.ResetRequest{Plugin: "temporal"})) + return err +} diff --git a/tests/tls/disaster_tls_test.go b/tests/tls/disaster_tls_test.go index 857a7458..f0ddc6be 100644 --- a/tests/tls/disaster_tls_test.go +++ b/tests/tls/disaster_tls_test.go @@ -2,8 +2,6 @@ package tls import ( "context" - "net" - "net/rpc" "os" "sync" "syscall" @@ -12,8 +10,8 @@ import ( "tests/helpers" - goridgeRpc "github.com/roadrunner-server/goridge/v3/pkg/rpc" - "github.com/roadrunner-server/pool/state/process" + informerV1 "github.com/roadrunner-server/api-go/v6/informer/v1" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.temporal.io/sdk/client" @@ -238,19 +236,10 @@ func Test_WorkerError_DisasterRecovery_Heavy(t *testing.T) { // Makes worker pool unable to recover for some time require.NoError(t, os.Rename("../php_test_files/worker.php", "../php_test_files/worker.bak")) - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - err = c.Call("informer.Workers", "temporal", &list) + list, err := helpers.Workers(t.Context()) require.NoError(t, err) - p, err := os.FindProcess(int(list.Workers[0].Pid)) + p, err := os.FindProcess(int(list[0].GetPid())) assert.NoError(t, err) // must fully recover with new worker @@ -292,19 +281,10 @@ func Test_WorkerError_DisasterRecovery_HeavyLA(t *testing.T) { // Makes worker pool unable to recover for some time require.NoError(t, os.Rename("../php_test_files/worker-la.php", "../php_test_files/worker-la.bak")) - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - err = c.Call("informer.Workers", "temporal", &list) + list, err := helpers.Workers(t.Context()) require.NoError(t, err) - p, err := os.FindProcess(int(list.Workers[0].Pid)) + p, err := os.FindProcess(int(list[0].GetPid())) assert.NoError(t, err) // must fully recover with new worker @@ -585,30 +565,14 @@ func Test_ActivityErrorLA_DisasterRecoveryProto(t *testing.T) { wg.Wait() } -func getWorkers(t *testing.T) []process.State { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - // WorkerList contains list of workers. - list := struct { - // Workers is list of workers. - Workers []process.State `json:"workers"` - }{} - - err = c.Call("informer.Workers", "temporal", &list) +func getWorkers(t *testing.T) []*informerV1.ProcessState { + list, err := helpers.Workers(t.Context()) assert.NoError(t, err) - assert.Len(t, list.Workers, 5) + assert.Len(t, list, 5) - return list.Workers + return list } func reset(t *testing.T) { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - var ret bool - err = c.Call("resetter.Reset", "temporal", &ret) - assert.NoError(t, err) - require.True(t, ret) + require.NoError(t, helpers.Reset(t.Context())) } diff --git a/tests/tls/hp_tls_test.go b/tests/tls/hp_tls_test.go index 6cd83492..7d590637 100644 --- a/tests/tls/hp_tls_test.go +++ b/tests/tls/hp_tls_test.go @@ -5,16 +5,16 @@ import ( "crypto/rand" "crypto/sha512" "fmt" - "net" - "net/rpc" "sync" "testing" "time" "tests/helpers" + protoApi "github.com/roadrunner-server/api-go/v6/temporal/v1" + + "connectrpc.com/connect" "github.com/fatih/color" - goridgeRpc "github.com/roadrunner-server/goridge/v3/pkg/rpc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.temporal.io/api/common/v1" @@ -821,27 +821,15 @@ func Test_SagaWorkflowLAProto(t *testing.T) { } func getActivities(t *testing.T) []string { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - res := make([]string, 0, 10) - - err = c.Call("temporal.GetActivityNames", true, &res) + resp, err := helpers.TemporalClient().GetActivityNames(t.Context(), connect.NewRequest(&protoApi.GetNamesRequest{})) assert.NoError(t, err) - return res + return resp.Msg.GetNames() } func getWorkflows(t *testing.T) []string { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", "127.0.0.1:6001") - assert.NoError(t, err) - c := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - - res := make([]string, 0, 10) - - err = c.Call("temporal.GetWorkflowNames", true, &res) + resp, err := helpers.TemporalClient().GetWorkflowNames(t.Context(), connect.NewRequest(&protoApi.GetNamesRequest{})) assert.NoError(t, err) - return res + return resp.Msg.GetNames() } diff --git a/tests/updates/updates_replay_test.go b/tests/updates/updates_replay_test.go index 39c6f561..765ef966 100644 --- a/tests/updates/updates_replay_test.go +++ b/tests/updates/updates_replay_test.go @@ -2,16 +2,14 @@ package updates import ( "context" - "net" - "net/rpc" "path" "sync" "testing" "tests/helpers" "time" - protoApi "github.com/roadrunner-server/api/v4/build/temporal/v1" - goridgeRpc "github.com/roadrunner-server/goridge/v3/pkg/rpc" + "connectrpc.com/connect" + protoApi "github.com/roadrunner-server/api-go/v6/temporal/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.temporal.io/api/common/v1" @@ -20,11 +18,6 @@ import ( "go.temporal.io/sdk/client" ) -const ( - download string = "temporal.DownloadWorkflowHistory" - replay string = "temporal.ReplayFromJSON" -) - func TestUpdatesReplay(t *testing.T) { stopCh := make(chan struct{}, 1) wg := &sync.WaitGroup{} @@ -75,20 +68,16 @@ func TestUpdatesReplay(t *testing.T) { time.Sleep(time.Second) tmp := path.Join(t.TempDir(), "replay.json") - t.Run("downloadWFHistory", downloadWFHistory("127.0.0.1:6001", w.GetID(), w.GetRunID(), updateGreetWF, tmp)) - t.Run("replayFromJSON", replayFromJSON("127.0.0.1:6001", tmp, updateGreetWF)) + t.Run("downloadWFHistory", downloadWFHistory(w.GetID(), w.GetRunID(), updateGreetWF, tmp)) + t.Run("replayFromJSON", replayFromJSON(tmp, updateGreetWF)) stopCh <- struct{}{} wg.Wait() time.Sleep(time.Second) } -func downloadWFHistory(address, wid, rid, wname, path string) func(t *testing.T) { +func downloadWFHistory(wid, rid, wname, path string) func(t *testing.T) { return func(t *testing.T) { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", address) - require.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - req := &protoApi.ReplayRequest{ SavePath: path, WorkflowType: &common.WorkflowType{ @@ -99,26 +88,22 @@ func downloadWFHistory(address, wid, rid, wname, path string) func(t *testing.T) RunId: rid, }, } - resp := &protoApi.ReplayResponse{} - err = client.Call(download, req, resp) + resp, err := helpers.TemporalClient().DownloadWorkflowHistory(t.Context(), connect.NewRequest(req)) require.NoError(t, err) + require.Zero(t, resp.Msg.GetStatus().GetCode()) } } -func replayFromJSON(address, path, wname string) func(t *testing.T) { +func replayFromJSON(path, wname string) func(t *testing.T) { return func(t *testing.T) { - conn, err := (&net.Dialer{}).DialContext(t.Context(), "tcp", address) - require.NoError(t, err) - client := rpc.NewClientWithCodec(goridgeRpc.NewClientCodec(conn)) - req := &protoApi.ReplayRequest{ SavePath: path, WorkflowType: &common.WorkflowType{ Name: wname, }, } - resp := &protoApi.ReplayResponse{} - err = client.Call(replay, req, resp) + resp, err := helpers.TemporalClient().ReplayFromJSON(t.Context(), connect.NewRequest(req)) require.NoError(t, err) + require.Zero(t, resp.Msg.GetStatus().GetCode()) } } From 127dc343c040f760883cd1678004269235b2fb93 Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Wed, 10 Jun 2026 23:08:23 +0200 Subject: [PATCH 04/11] chore: migrate queue package imports to v6 --- queue/queue.go | 2 +- queue/queue_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/queue/queue.go b/queue/queue.go index 2cee3810..6596718f 100644 --- a/queue/queue.go +++ b/queue/queue.go @@ -3,7 +3,7 @@ package queue import ( "sync" - "github.com/temporalio/roadrunner-temporal/v5/internal" + "github.com/temporalio/roadrunner-temporal/v6/internal" "go.temporal.io/api/common/v1" "go.temporal.io/api/failure/v1" ) diff --git a/queue/queue_test.go b/queue/queue_test.go index 6ac14494..ee2b8a97 100644 --- a/queue/queue_test.go +++ b/queue/queue_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/temporalio/roadrunner-temporal/v5/internal" + "github.com/temporalio/roadrunner-temporal/v6/internal" "go.temporal.io/api/common/v1" "go.temporal.io/api/failure/v1" ) From 054711671b929f8b58da862449d1fc5e573bb4fa Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Wed, 10 Jun 2026 23:11:47 +0200 Subject: [PATCH 05/11] chore: extract soft-status helper, preallocate name lists --- rpc.go | 112 ++++++++++++++++----------------------------------------- 1 file changed, 30 insertions(+), 82 deletions(-) diff --git a/rpc.go b/rpc.go index 0e7935f8..a8f9ffe3 100644 --- a/rpc.go +++ b/rpc.go @@ -33,6 +33,13 @@ type rpc struct { // Compile-time check that rpc implements the generated handler interface. var _ temporalV1connect.TemporalServiceHandler = (*rpc)(nil) +// newStatus builds the soft-error status carried inside replay responses +// (kept in the response body for parity with the v5 RPC behavior). +func newStatus(code codes.Code, msg string) *commonV1.Status { + // gRPC status codes are tiny (0..16), the conversion cannot overflow + return &commonV1.Status{Code: int32(code), Message: msg} //nolint:gosec +} + // RecordActivityHeartbeat records a heartbeat for an activity. // task_token - is the value of the binary "TaskToken" field of the "ActivityInfo" struct retrieved inside the activity. // details - is the progress you want to record along with the heartbeat for this activity. @@ -82,7 +89,7 @@ func (r *rpc) GetActivityNames(_ context.Context, _ *connect.Request[protoApi.Ge r.plugin.mu.RLock() defer r.plugin.mu.RUnlock() - out := &protoApi.NamesList{} + out := &protoApi.NamesList{Names: make([]string, 0, len(r.plugin.temporal.activities))} for k := range r.plugin.temporal.activities { out.Names = append(out.Names, k) } @@ -94,7 +101,7 @@ func (r *rpc) GetWorkflowNames(_ context.Context, _ *connect.Request[protoApi.Ge r.plugin.mu.RLock() defer r.plugin.mu.RUnlock() - out := &protoApi.NamesList{} + out := &protoApi.NamesList{Names: make([]string, 0, len(r.plugin.temporal.workflows))} for k := range r.plugin.temporal.workflows { out.Names = append(out.Names, k) } @@ -113,10 +120,7 @@ func (r *rpc) ReplayWorkflow(_ context.Context, req *connect.Request[protoApi.Re if in.GetWorkflowExecution() == nil || in.GetWorkflowType() == nil || in.GetWorkflowExecution().GetRunId() == "" || in.GetWorkflowExecution().GetWorkflowId() == "" || in.GetWorkflowType().GetName() == "" { - out.Status = &commonV1.Status{ - Code: int32(codes.InvalidArgument), - Message: "run_id, workflow_id or workflow_name should not be empty", - } + out.Status = newStatus(codes.InvalidArgument, "run_id, workflow_id or workflow_name should not be empty") r.plugin.log.Error("replay workflow request", zap.String("error", "run_id, workflow_id or workflow_name should not be empty")) return connect.NewResponse(out), nil @@ -130,10 +134,7 @@ func (r *rpc) ReplayWorkflow(_ context.Context, req *connect.Request[protoApi.Re for iter.HasNext() { event, err := iter.Next() if err != nil { - out.Status = &commonV1.Status{ - Code: int32(codes.Internal), - Message: err.Error(), - } + out.Status = newStatus(codes.Internal, err.Error()) r.plugin.log.Error("history iteration error", zap.Error(err)) return connect.NewResponse(out), nil @@ -142,10 +143,7 @@ func (r *rpc) ReplayWorkflow(_ context.Context, req *connect.Request[protoApi.Re } if r.plugin.getWfDef() == nil { - out.Status = &commonV1.Status{ - Code: int32(codes.FailedPrecondition), - Message: "workflow definition is not initialized, retry in a second", - } + out.Status = newStatus(codes.FailedPrecondition, "workflow definition is not initialized, retry in a second") return connect.NewResponse(out), nil } @@ -158,18 +156,13 @@ func (r *rpc) ReplayWorkflow(_ context.Context, req *connect.Request[protoApi.Re err := replayer.ReplayWorkflowHistory(logger.NewZapAdapter(r.plugin.log), &hist) if err != nil { - out.Status = &commonV1.Status{ - Code: int32(codes.FailedPrecondition), - Message: err.Error(), - } + out.Status = newStatus(codes.FailedPrecondition, err.Error()) r.plugin.log.Error("replay error", zap.Error(err)) return connect.NewResponse(out), nil } - out.Status = &commonV1.Status{ - Code: int32(codes.OK), - } + out.Status = newStatus(codes.OK, "") r.plugin.log.Debug("replay workflow request finished successfully") @@ -187,10 +180,7 @@ func (r *rpc) DownloadWorkflowHistory(_ context.Context, req *connect.Request[pr if in.GetWorkflowExecution() == nil || in.GetWorkflowType() == nil || in.GetSavePath() == "" || in.GetWorkflowExecution().GetRunId() == "" || in.GetWorkflowExecution().GetWorkflowId() == "" || in.GetWorkflowType().GetName() == "" { - out.Status = &commonV1.Status{ - Code: int32(codes.InvalidArgument), - Message: "run_id, workflow_id or save_path should not be empty", - } + out.Status = newStatus(codes.InvalidArgument, "run_id, workflow_id or save_path should not be empty") r.plugin.log.Error("replay workflow request", zap.String("error", "run_id, workflow_id or save_path should not be empty")) return connect.NewResponse(out), nil @@ -198,10 +188,7 @@ func (r *rpc) DownloadWorkflowHistory(_ context.Context, req *connect.Request[pr file, err := os.Create(in.GetSavePath()) if err != nil { - out.Status = &commonV1.Status{ - Code: int32(codes.Internal), - Message: err.Error(), - } + out.Status = newStatus(codes.Internal, err.Error()) r.plugin.log.Error("failed to create the file", zap.Error(err)) return connect.NewResponse(out), nil @@ -223,10 +210,7 @@ func (r *rpc) DownloadWorkflowHistory(_ context.Context, req *connect.Request[pr for iter.HasNext() { event, errn := iter.Next() if errn != nil { - out.Status = &commonV1.Status{ - Code: int32(codes.Internal), - Message: errn.Error(), - } + out.Status = newStatus(codes.Internal, errn.Error()) r.plugin.log.Error("history iteration error", zap.Error(errn)) return connect.NewResponse(out), nil @@ -237,10 +221,7 @@ func (r *rpc) DownloadWorkflowHistory(_ context.Context, req *connect.Request[pr data, err := protojson.Marshal(&hist) if err != nil { - out.Status = &commonV1.Status{ - Code: int32(codes.Internal), - Message: err.Error(), - } + out.Status = newStatus(codes.Internal, err.Error()) r.plugin.log.Error("history marshal error", zap.Error(err)) return connect.NewResponse(out), nil @@ -248,18 +229,13 @@ func (r *rpc) DownloadWorkflowHistory(_ context.Context, req *connect.Request[pr _, err = file.Write(data) if err != nil { - out.Status = &commonV1.Status{ - Code: int32(codes.Internal), - Message: err.Error(), - } + out.Status = newStatus(codes.Internal, err.Error()) r.plugin.log.Error("history marshal error", zap.Error(err)) return connect.NewResponse(out), nil } - out.Status = &commonV1.Status{ - Code: int32(codes.OK), - } + out.Status = newStatus(codes.OK, "") r.plugin.log.Debug("history saved", zap.String("location", in.GetSavePath())) @@ -277,30 +253,21 @@ func (r *rpc) ReplayFromJSON(_ context.Context, req *connect.Request[protoApi.Re ) if in.GetWorkflowType() == nil || in.GetSavePath() == "" { - out.Status = &commonV1.Status{ - Code: int32(codes.InvalidArgument), - Message: "workflow_name and save_path should not be empty", - } + out.Status = newStatus(codes.InvalidArgument, "workflow_name and save_path should not be empty") r.plugin.log.Error("replay from JSON request", zap.String("error", "workflow_name and save_path should not be empty")) return connect.NewResponse(out), nil } if in.GetWorkflowType().GetName() == "" { - out.Status = &commonV1.Status{ - Code: int32(codes.InvalidArgument), - Message: "workflow_name should not be empty", - } + out.Status = newStatus(codes.InvalidArgument, "workflow_name should not be empty") r.plugin.log.Error("replay from JSON request", zap.String("error", "workflow_name should not be empty")) return connect.NewResponse(out), nil } if r.plugin.getWfDef() == nil { - out.Status = &commonV1.Status{ - Code: int32(codes.FailedPrecondition), - Message: "workflow definition is not initialized, retry in a second", - } + out.Status = newStatus(codes.FailedPrecondition, "workflow definition is not initialized, retry in a second") return connect.NewResponse(out), nil } @@ -316,10 +283,7 @@ func (r *rpc) ReplayFromJSON(_ context.Context, req *connect.Request[protoApi.Re case 0: err := replayer.ReplayWorkflowHistoryFromJSONFile(logger.NewZapAdapter(r.plugin.log), in.GetSavePath()) if err != nil { - out.Status = &commonV1.Status{ - Code: int32(codes.FailedPrecondition), - Message: err.Error(), - } + out.Status = newStatus(codes.FailedPrecondition, err.Error()) r.plugin.log.Error("replay from JSON request", zap.Error(err)) return connect.NewResponse(out), nil @@ -328,19 +292,14 @@ func (r *rpc) ReplayFromJSON(_ context.Context, req *connect.Request[protoApi.Re // we have last event ID err := replayer.ReplayPartialWorkflowHistoryFromJSONFile(logger.NewZapAdapter(r.plugin.log), in.GetSavePath(), in.GetLastEventId()) if err != nil { - out.Status = &commonV1.Status{ - Code: int32(codes.FailedPrecondition), - Message: err.Error(), - } + out.Status = newStatus(codes.FailedPrecondition, err.Error()) r.plugin.log.Error("replay from JSON request (partial workflow history)", zap.Int64("id", in.GetLastEventId()), zap.Error(err)) return connect.NewResponse(out), nil } } - out.Status = &commonV1.Status{ - Code: int32(codes.OK), - } + out.Status = newStatus(codes.OK, "") r.plugin.log.Debug("replay from JSON request finished successfully") @@ -356,20 +315,14 @@ func (r *rpc) ReplayWorkflowHistory(_ context.Context, req *connect.Request[prot ) if in.GetHistory() == nil || in.GetWorkflowType().GetName() == "" { - out.Status = &commonV1.Status{ - Code: int32(codes.FailedPrecondition), - Message: "workflow_name and/or history should not be empty", - } + out.Status = newStatus(codes.FailedPrecondition, "workflow_name and/or history should not be empty") r.plugin.log.Error("workflow_name and/or history should not be empty") return connect.NewResponse(out), nil } if r.plugin.getWfDef() == nil { - out.Status = &commonV1.Status{ - Code: int32(codes.FailedPrecondition), - Message: "workflow definition is not initialized, retry in a second", - } + out.Status = newStatus(codes.FailedPrecondition, "workflow definition is not initialized, retry in a second") return connect.NewResponse(out), nil } @@ -382,18 +335,13 @@ func (r *rpc) ReplayWorkflowHistory(_ context.Context, req *connect.Request[prot err := replayer.ReplayWorkflowHistory(logger.NewZapAdapter(r.plugin.log), in.GetHistory()) if err != nil { - out.Status = &commonV1.Status{ - Code: int32(codes.FailedPrecondition), - Message: err.Error(), - } + out.Status = newStatus(codes.FailedPrecondition, err.Error()) r.plugin.log.Error("replay workflow history", zap.Error(err)) return connect.NewResponse(out), nil } - out.Status = &commonV1.Status{ - Code: int32(codes.OK), - } + out.Status = newStatus(codes.OK, "") r.plugin.log.Debug("replay workflow request finished successfully") From c9f766c3dfea255abca27f07631c30ea61a85636 Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Fri, 12 Jun 2026 13:40:40 +0200 Subject: [PATCH 06/11] chore: bump deps --- go.mod | 18 +++++++++--------- go.sum | 32 ++++++++++++++++---------------- go.work | 2 +- tests/go.mod | 18 +++++++++--------- tests/go.sum | 32 ++++++++++++++++---------------- 5 files changed, 51 insertions(+), 51 deletions(-) diff --git a/go.mod b/go.mod index 734ebd00..244bff3d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/temporalio/roadrunner-temporal/v6 -go 1.26.3 +go 1.26.4 require ( github.com/goccy/go-json v0.10.6 @@ -11,10 +11,10 @@ require ( github.com/roadrunner-server/events v1.0.1 github.com/stretchr/testify v1.11.1 github.com/uber-go/tally/v4 v4.1.17 - go.temporal.io/api v1.62.13 + go.temporal.io/api v1.62.14 go.temporal.io/sdk v1.44.1 go.temporal.io/sdk/contrib/tally v0.2.0 - go.temporal.io/server v1.31.0 + go.temporal.io/server v1.31.1 go.uber.org/zap v1.28.0 google.golang.org/protobuf v1.36.11 ) @@ -47,13 +47,13 @@ require ( github.com/yusufpapurcu/wmi v1.2.4 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.37.0 // indirect + golang.org/x/net v0.56.0 // indirect + golang.org/x/sync v0.21.0 // indirect + golang.org/x/sys v0.46.0 // indirect + golang.org/x/text v0.38.0 // indirect golang.org/x/time v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260610212136-7ab31c22f7ad // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad // indirect google.golang.org/grpc v1.81.1 gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index f48e981b..994a85b3 100644 --- a/go.sum +++ b/go.sum @@ -245,15 +245,15 @@ go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/ go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.temporal.io/api v1.5.0/go.mod h1:BqKxEJJYdxb5dqf0ODfzfMxh8UEQ5L3zKS51FiIYYkA= -go.temporal.io/api v1.62.13 h1:xMa8Nt5oAMX+LvlCJA44wjTCc1H09i2rG9poB1/xvH4= -go.temporal.io/api v1.62.13/go.mod h1:0k75tRljEuELWGeXjEZZO7zYqBln4+1FrG6+IMOMy7Q= +go.temporal.io/api v1.62.14 h1:Tree3eqoKRt5Vv+nvYHMPp/ROiGmSOTtFUD9d0w8yJE= +go.temporal.io/api v1.62.14/go.mod h1:0k75tRljEuELWGeXjEZZO7zYqBln4+1FrG6+IMOMy7Q= go.temporal.io/sdk v1.12.0/go.mod h1:lSp3lH1lI0TyOsus0arnO3FYvjVXBZGi/G7DjnAnm6o= go.temporal.io/sdk v1.44.1 h1:Mt2OZLZpqkzDIdg9YyQzO0Rb/HqCDnnqHlIAGAJ5gqM= go.temporal.io/sdk v1.44.1/go.mod h1:vkApR12F9/Y8OR+hkxe7WyXQFuCX6clhzqnAk6rzDAM= go.temporal.io/sdk/contrib/tally v0.2.0 h1:XnTJIQcjOv+WuCJ1u8Ve2nq+s2H4i/fys34MnWDRrOo= go.temporal.io/sdk/contrib/tally v0.2.0/go.mod h1:1kpSuCms/tHeJQDPuuKkaBsMqfHnIIRnCtUYlPNXxuE= -go.temporal.io/server v1.31.0 h1:FKLodreaMXUxYc3zr6xxwxtpGz1WH/t7O0IWxV1d1x0= -go.temporal.io/server v1.31.0/go.mod h1:MTQAw8uMU3ooSHyg/62JsNu/j8lK34SfKMTXkexYcw8= +go.temporal.io/server v1.31.1 h1:3rxA0Ls21hLOseKsyzm7e+IrVLuaDsuri0DGX+chIqU= +go.temporal.io/server v1.31.1/go.mod h1:kOOpZs6WMcLuVmlu0uH+dVD2Ul1d4hGjmGpHjxfz2EI= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -301,8 +301,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -315,8 +315,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= +golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -338,8 +338,8 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -347,8 +347,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= -golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= +golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE= +golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= @@ -379,10 +379,10 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/api v0.0.0-20260610212136-7ab31c22f7ad h1:3iLyITS/sySRwbUKoC7ogfj2Yr1Cjs0pfaRKj5U5HEw= +google.golang.org/genproto/googleapis/api v0.0.0-20260610212136-7ab31c22f7ad/go.mod h1:KdNqO+rCIWgFumrNBSEDlDNrkrQnpkax7Tv1WxNY8V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad h1:45WmJvIV6C2+O/jjLkPUH+F3aOj/1miDoU2DD0+NWbg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= diff --git a/go.work b/go.work index a819d87f..3ca56c09 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.26.3 +go 1.26.4 use ( . diff --git a/tests/go.mod b/tests/go.mod index db61504c..fc514ca3 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -1,6 +1,6 @@ module tests -go 1.26.3 +go 1.26.4 require ( connectrpc.com/connect v1.20.0 @@ -18,7 +18,7 @@ require ( github.com/stretchr/testify v1.11.1 github.com/temporalio/roadrunner-temporal/v6 v6.0.0-00010101000000-000000000000 go.opentelemetry.io/otel/sdk v1.44.0 - go.temporal.io/api v1.62.13 + go.temporal.io/api v1.62.14 go.temporal.io/sdk v1.44.1 go.temporal.io/sdk/contrib/opentelemetry v0.7.0 go.uber.org/zap v1.28.0 @@ -88,17 +88,17 @@ require ( go.opentelemetry.io/otel/metric v1.44.0 // indirect go.opentelemetry.io/otel/trace v1.44.0 // indirect go.temporal.io/sdk/contrib/tally v0.2.0 // indirect - go.temporal.io/server v1.31.0 // indirect + go.temporal.io/server v1.31.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.37.0 // indirect + golang.org/x/net v0.56.0 // indirect + golang.org/x/sync v0.21.0 // indirect + golang.org/x/sys v0.46.0 // indirect + golang.org/x/text v0.38.0 // indirect golang.org/x/time v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260610212136-7ab31c22f7ad // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad // indirect google.golang.org/grpc v1.81.1 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/tests/go.sum b/tests/go.sum index f4f5448f..fc510768 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -300,8 +300,8 @@ go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/ go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.temporal.io/api v1.5.0/go.mod h1:BqKxEJJYdxb5dqf0ODfzfMxh8UEQ5L3zKS51FiIYYkA= -go.temporal.io/api v1.62.13 h1:xMa8Nt5oAMX+LvlCJA44wjTCc1H09i2rG9poB1/xvH4= -go.temporal.io/api v1.62.13/go.mod h1:0k75tRljEuELWGeXjEZZO7zYqBln4+1FrG6+IMOMy7Q= +go.temporal.io/api v1.62.14 h1:Tree3eqoKRt5Vv+nvYHMPp/ROiGmSOTtFUD9d0w8yJE= +go.temporal.io/api v1.62.14/go.mod h1:0k75tRljEuELWGeXjEZZO7zYqBln4+1FrG6+IMOMy7Q= go.temporal.io/sdk v1.12.0/go.mod h1:lSp3lH1lI0TyOsus0arnO3FYvjVXBZGi/G7DjnAnm6o= go.temporal.io/sdk v1.44.1 h1:Mt2OZLZpqkzDIdg9YyQzO0Rb/HqCDnnqHlIAGAJ5gqM= go.temporal.io/sdk v1.44.1/go.mod h1:vkApR12F9/Y8OR+hkxe7WyXQFuCX6clhzqnAk6rzDAM= @@ -309,8 +309,8 @@ go.temporal.io/sdk/contrib/opentelemetry v0.7.0 h1:GSna1HP+1ibNXZ9xlVdQU2zFVqdt5 go.temporal.io/sdk/contrib/opentelemetry v0.7.0/go.mod h1:oQJC6UIl3FbSYh4f2MlUAIYSE6FPw02X1Tw8/bOvfxg= go.temporal.io/sdk/contrib/tally v0.2.0 h1:XnTJIQcjOv+WuCJ1u8Ve2nq+s2H4i/fys34MnWDRrOo= go.temporal.io/sdk/contrib/tally v0.2.0/go.mod h1:1kpSuCms/tHeJQDPuuKkaBsMqfHnIIRnCtUYlPNXxuE= -go.temporal.io/server v1.31.0 h1:FKLodreaMXUxYc3zr6xxwxtpGz1WH/t7O0IWxV1d1x0= -go.temporal.io/server v1.31.0/go.mod h1:MTQAw8uMU3ooSHyg/62JsNu/j8lK34SfKMTXkexYcw8= +go.temporal.io/server v1.31.1 h1:3rxA0Ls21hLOseKsyzm7e+IrVLuaDsuri0DGX+chIqU= +go.temporal.io/server v1.31.1/go.mod h1:kOOpZs6WMcLuVmlu0uH+dVD2Ul1d4hGjmGpHjxfz2EI= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -359,8 +359,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -373,8 +373,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= +golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -396,8 +396,8 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -405,8 +405,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= -golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= +golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE= +golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= @@ -437,10 +437,10 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/api v0.0.0-20260610212136-7ab31c22f7ad h1:3iLyITS/sySRwbUKoC7ogfj2Yr1Cjs0pfaRKj5U5HEw= +google.golang.org/genproto/googleapis/api v0.0.0-20260610212136-7ab31c22f7ad/go.mod h1:KdNqO+rCIWgFumrNBSEDlDNrkrQnpkax7Tv1WxNY8V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad h1:45WmJvIV6C2+O/jjLkPUH+F3aOj/1miDoU2DD0+NWbg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= From c24288a772ffb0fa178546556ef75bb34fffad0d Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Fri, 12 Jun 2026 14:09:17 +0200 Subject: [PATCH 07/11] fix: migrate logging to slog so the plugin wires with the v6 plugin set --- internal/logger/doc.go | 3 - internal/logger/wrapper.go | 55 ---------- tests/mock/doc.go | 3 - tests/mock/logger.go | 64 ------------ tests/mock/observer.go | 199 ------------------------------------- 5 files changed, 324 deletions(-) delete mode 100644 internal/logger/doc.go delete mode 100644 internal/logger/wrapper.go delete mode 100644 tests/mock/doc.go delete mode 100644 tests/mock/logger.go delete mode 100644 tests/mock/observer.go diff --git a/internal/logger/doc.go b/internal/logger/doc.go deleted file mode 100644 index a3a2d015..00000000 --- a/internal/logger/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package logger provides an adapter that bridges zap.Logger with the -// go.temporal.io/sdk/log.Logger interface used by the Temporal SDK client. -package logger diff --git a/internal/logger/wrapper.go b/internal/logger/wrapper.go deleted file mode 100644 index 8e2ada47..00000000 --- a/internal/logger/wrapper.go +++ /dev/null @@ -1,55 +0,0 @@ -package logger - -import ( - "fmt" - - "go.uber.org/zap" -) - -type ZapAdapter struct { - zl *zap.Logger -} - -// NewZapAdapter ... which uses general log interface -func NewZapAdapter(zapLogger *zap.Logger) *ZapAdapter { - return &ZapAdapter{ - zl: zapLogger.WithOptions(zap.AddCallerSkip(1)), - } -} - -func (log *ZapAdapter) Debug(msg string, keyvals ...any) { - log.zl.Debug(msg, log.fields(keyvals)...) -} - -func (log *ZapAdapter) Info(msg string, keyvals ...any) { - log.zl.Info(msg, log.fields(keyvals)...) -} - -func (log *ZapAdapter) Warn(msg string, keyvals ...any) { - log.zl.Warn(msg, log.fields(keyvals)...) -} - -func (log *ZapAdapter) Error(msg string, keyvals ...any) { - log.zl.Error(msg, log.fields(keyvals)...) -} - -func (log *ZapAdapter) fields(keyvals []any) []zap.Field { - // we should have even number of keys and values - if len(keyvals)%2 != 0 { - return []zap.Field{zap.Error(fmt.Errorf("odd number of keyvals pairs: %v", keyvals))} - } - - zf := make([]zap.Field, len(keyvals)/2) - j := 0 - for i := 0; i < len(keyvals); i += 2 { - key, ok := keyvals[i].(string) - if !ok { - key = fmt.Sprintf("%v", keyvals[i]) - } - - zf[j] = zap.Any(key, keyvals[i+1]) - j++ - } - - return zf -} diff --git a/tests/mock/doc.go b/tests/mock/doc.go deleted file mode 100644 index a9c49222..00000000 --- a/tests/mock/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package mocklogger provides test logging infrastructure including an in-memory -// zapcore.Core observer and a zap.Logger implementation compatible with the Endure container lifecycle. -package mocklogger diff --git a/tests/mock/logger.go b/tests/mock/logger.go deleted file mode 100644 index 9bc251fe..00000000 --- a/tests/mock/logger.go +++ /dev/null @@ -1,64 +0,0 @@ -package mocklogger - -import ( - "github.com/roadrunner-server/endure/v2/dep" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -type ZapLoggerMock struct { - l *zap.Logger -} - -type Logger interface { - NamedLogger(string) *zap.Logger -} - -func ZapTestLogger(enab zapcore.LevelEnabler) (*ZapLoggerMock, *ObservedLogs) { - core, logs := New(enab) - obsLog := zap.New(core, zap.Development()) - - return &ZapLoggerMock{ - l: obsLog, - }, logs -} - -func (z *ZapLoggerMock) Init() error { - return nil -} - -func (z *ZapLoggerMock) Serve() chan error { - return make(chan error, 1) -} - -func (z *ZapLoggerMock) Stop() error { - return z.l.Sync() -} - -func (z *ZapLoggerMock) Provides() []*dep.Out { - return []*dep.Out{ - dep.Bind((*Logger)(nil), z.ProvideLogger), - } -} - -func (z *ZapLoggerMock) Weight() uint { - return 100 -} - -func (z *ZapLoggerMock) ProvideLogger() *Log { - return NewLogger(z.l) -} - -type Log struct { - base *zap.Logger -} - -func NewLogger(log *zap.Logger) *Log { - return &Log{ - base: log, - } -} - -func (l *Log) NamedLogger(string) *zap.Logger { - return l.base -} diff --git a/tests/mock/observer.go b/tests/mock/observer.go deleted file mode 100644 index 061cec7e..00000000 --- a/tests/mock/observer.go +++ /dev/null @@ -1,199 +0,0 @@ -package mocklogger - -// Copyright (c) 2017 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -import ( - "strings" - "sync" - "time" - - "go.uber.org/zap/zapcore" -) - -// An LoggedEntry is an encoding-agnostic representation of a log message. -// Field availability is context dependant. -type LoggedEntry struct { - zapcore.Entry - Context []zapcore.Field -} - -// ContextMap returns a map for all fields in Context. -func (e LoggedEntry) ContextMap() map[string]any { - encoder := zapcore.NewMapObjectEncoder() - for _, f := range e.Context { - f.AddTo(encoder) - } - return encoder.Fields -} - -// ObservedLogs is a concurrency-safe, ordered collection of observed logs. -type ObservedLogs struct { - mu sync.RWMutex - logs []LoggedEntry -} - -// Len returns the number of items in the collection. -func (o *ObservedLogs) Len() int { - o.mu.RLock() - n := len(o.logs) - o.mu.RUnlock() - return n -} - -// All returns a copy of all the observed logs. -func (o *ObservedLogs) All() []LoggedEntry { - o.mu.RLock() - ret := make([]LoggedEntry, len(o.logs)) - copy(ret, o.logs) - o.mu.RUnlock() - return ret -} - -// TakeAll returns a copy of all the observed logs, and truncates the observed -// slice. -func (o *ObservedLogs) TakeAll() []LoggedEntry { - o.mu.Lock() - ret := o.logs - o.logs = nil - o.mu.Unlock() - return ret -} - -// AllUntimed returns a copy of all the observed logs, but overwrites the -// observed timestamps with time.Time's zero value. This is useful when making -// assertions in tests. -func (o *ObservedLogs) AllUntimed() []LoggedEntry { - ret := o.All() - for i := range ret { - ret[i].Time = time.Time{} - } - return ret -} - -// FilterLevelExact filters entries to those logged at exactly the given level. -func (o *ObservedLogs) FilterLevelExact(level zapcore.Level) *ObservedLogs { - return o.Filter(func(e LoggedEntry) bool { - return e.Level == level - }) -} - -// FilterMessage filters entries to those that have the specified message. -func (o *ObservedLogs) FilterMessage(msg string) *ObservedLogs { - return o.Filter(func(e LoggedEntry) bool { - return e.Message == msg - }) -} - -// FilterMessageSnippet filters entries to those that have a message containing the specified snippet. -func (o *ObservedLogs) FilterMessageSnippet(snippet string) *ObservedLogs { - return o.Filter(func(e LoggedEntry) bool { - return strings.Contains(e.Message, snippet) - }) -} - -// FilterField filters entries to those that have the specified field. -func (o *ObservedLogs) FilterField(field zapcore.Field) *ObservedLogs { - return o.Filter(func(e LoggedEntry) bool { - for _, ctxField := range e.Context { - if ctxField.Equals(field) { - return true - } - } - return false - }) -} - -// FilterFieldKey filters entries to those that have the specified key. -func (o *ObservedLogs) FilterFieldKey(key string) *ObservedLogs { - return o.Filter(func(e LoggedEntry) bool { - for _, ctxField := range e.Context { - if ctxField.Key == key { - return true - } - } - return false - }) -} - -// Filter returns a copy of this ObservedLogs containing only those entries -// for which the provided function returns true. -func (o *ObservedLogs) Filter(keep func(LoggedEntry) bool) *ObservedLogs { - o.mu.RLock() - defer o.mu.RUnlock() - - var filtered []LoggedEntry - for _, entry := range o.logs { - if keep(entry) { - filtered = append(filtered, entry) - } - } - return &ObservedLogs{logs: filtered} -} - -func (o *ObservedLogs) add(log LoggedEntry) { - o.mu.Lock() - o.logs = append(o.logs, log) - o.mu.Unlock() -} - -// New creates a new Core that buffers logs in memory (without any encoding). -// It's particularly useful in tests. -func New(enab zapcore.LevelEnabler) (zapcore.Core, *ObservedLogs) { - ol := &ObservedLogs{} - return &contextObserver{ - LevelEnabler: enab, - logs: ol, - }, ol -} - -type contextObserver struct { - zapcore.LevelEnabler - logs *ObservedLogs - context []zapcore.Field -} - -func (co *contextObserver) Check(ent zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry { - if co.Enabled(ent.Level) { - return ce.AddCore(ent, co) - } - return ce -} - -func (co *contextObserver) With(fields []zapcore.Field) zapcore.Core { - return &contextObserver{ - LevelEnabler: co.LevelEnabler, - logs: co.logs, - context: append(co.context[:len(co.context):len(co.context)], fields...), - } -} - -func (co *contextObserver) Write(ent zapcore.Entry, fields []zapcore.Field) error { - all := make([]zapcore.Field, 0, len(fields)+len(co.context)) - all = append(all, co.context...) - all = append(all, fields...) - co.logs.add(LoggedEntry{ent, all}) - - return nil -} - -func (co *contextObserver) Sync() error { - return nil -} From f2db57743d050cb47ab53e26fc46c3b83debc6d5 Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Fri, 12 Jun 2026 14:09:19 +0200 Subject: [PATCH 08/11] fix: run the integration suite against the v6 plugins instead of v5 --- tests/general/plugin_status_test.go | 8 +-- tests/go.mod | 23 +++--- tests/go.sum | 42 +++++------ tests/helpers/helpers.go | 105 +++++----------------------- 4 files changed, 47 insertions(+), 131 deletions(-) diff --git a/tests/general/plugin_status_test.go b/tests/general/plugin_status_test.go index cbeeaf26..c6427f5e 100644 --- a/tests/general/plugin_status_test.go +++ b/tests/general/plugin_status_test.go @@ -12,11 +12,11 @@ import ( "testing" "time" - "github.com/roadrunner-server/config/v5" + "github.com/roadrunner-server/config/v6" "github.com/roadrunner-server/endure/v2" - "github.com/roadrunner-server/logger/v5" - "github.com/roadrunner-server/server/v5" - "github.com/roadrunner-server/status/v5" + "github.com/roadrunner-server/logger/v6" + "github.com/roadrunner-server/server/v6" + "github.com/roadrunner-server/status/v6" "github.com/stretchr/testify/require" rrtemporal "github.com/temporalio/roadrunner-temporal/v6" diff --git a/tests/go.mod b/tests/go.mod index fc514ca3..d4304e5e 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -7,21 +7,20 @@ require ( github.com/fatih/color v1.19.0 github.com/pborman/uuid v1.2.1 github.com/roadrunner-server/api-go/v6 v6.0.0-beta.12.0.20260610203904-09df89976edc - github.com/roadrunner-server/config/v5 v5.1.9 + github.com/roadrunner-server/config/v6 v6.0.0-beta.3 github.com/roadrunner-server/endure/v2 v2.6.2 - github.com/roadrunner-server/informer/v5 v5.1.9 - github.com/roadrunner-server/logger/v5 v5.1.9 - github.com/roadrunner-server/resetter/v5 v5.1.9 - github.com/roadrunner-server/rpc/v5 v5.1.9 - github.com/roadrunner-server/server/v5 v5.2.10 - github.com/roadrunner-server/status/v5 v5.1.9 + github.com/roadrunner-server/informer/v6 v6.0.0-beta.2 + github.com/roadrunner-server/logger/v6 v6.0.0-beta.3 + github.com/roadrunner-server/resetter/v6 v6.0.0-beta.3 + github.com/roadrunner-server/rpc/v6 v6.0.0-beta.4 + github.com/roadrunner-server/server/v6 v6.0.0-beta.6 + github.com/roadrunner-server/status/v6 v6.0.0-beta.5 github.com/stretchr/testify v1.11.1 github.com/temporalio/roadrunner-temporal/v6 v6.0.0-00010101000000-000000000000 go.opentelemetry.io/otel/sdk v1.44.0 go.temporal.io/api v1.62.14 go.temporal.io/sdk v1.44.1 go.temporal.io/sdk/contrib/opentelemetry v0.7.0 - go.uber.org/zap v1.28.0 ) replace github.com/uber-go/tally/v4 => github.com/uber-go/tally/v4 v4.1.10 @@ -29,6 +28,7 @@ replace github.com/uber-go/tally/v4 => github.com/uber-go/tally/v4 v4.1.10 replace github.com/temporalio/roadrunner-temporal/v6 => ../ require ( + connectrpc.com/grpcreflect v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cactus/go-statsd-client/v5 v5.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -59,12 +59,9 @@ require ( github.com/prometheus/common v0.68.1 // indirect github.com/prometheus/procfs v0.20.1 // indirect github.com/roadrunner-server/api-plugins/v6 v6.0.0-beta.2 // indirect - github.com/roadrunner-server/api/v4 v4.24.0 // indirect github.com/roadrunner-server/errors v1.5.0 // indirect github.com/roadrunner-server/events v1.0.1 // indirect - github.com/roadrunner-server/goridge/v3 v3.8.3 // indirect github.com/roadrunner-server/goridge/v4 v4.0.0-beta.2 // indirect - github.com/roadrunner-server/pool v1.1.3 // indirect github.com/roadrunner-server/pool/v2 v2.0.0-beta.1 // indirect github.com/roadrunner-server/tcplisten v1.5.2 // indirect github.com/robfig/cron v1.2.0 // indirect @@ -80,8 +77,6 @@ require ( github.com/tklauser/numcpus v0.12.0 // indirect github.com/twmb/murmur3 v1.1.8 // indirect github.com/uber-go/tally/v4 v4.1.17 // indirect - github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect - github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel v1.44.0 // indirect @@ -91,6 +86,7 @@ require ( go.temporal.io/server v1.31.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.28.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/net v0.56.0 // indirect golang.org/x/sync v0.21.0 // indirect @@ -101,6 +97,5 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20260610212136-7ab31c22f7ad // indirect google.golang.org/grpc v1.81.1 // indirect google.golang.org/protobuf v1.36.11 // indirect - gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/tests/go.sum b/tests/go.sum index fc510768..fde21f1a 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= connectrpc.com/connect v1.20.0 h1:6TNDAB+WeNd2uolWNlYczB5E0KNNaVMNUEx8JEUsPmQ= connectrpc.com/connect v1.20.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4= +connectrpc.com/grpcreflect v1.3.0 h1:Y4V+ACf8/vOb1XOc251Qun7jMB75gCUNw6llvB9csXc= +connectrpc.com/grpcreflect v1.3.0/go.mod h1:nfloOtCS8VUQOQ1+GTdFzVg2CJo4ZGaat8JIovCtDYs= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -197,36 +199,30 @@ github.com/roadrunner-server/api-go/v6 v6.0.0-beta.12.0.20260610203904-09df89976 github.com/roadrunner-server/api-go/v6 v6.0.0-beta.12.0.20260610203904-09df89976edc/go.mod h1:prGWJ2GoF5YD5PIG7Tb6VKulU3bWoFwr9DCwgxheb80= github.com/roadrunner-server/api-plugins/v6 v6.0.0-beta.2 h1:GqsZzWQ5jMXRF1O/b8IqFz9PLpS7Ui0K4OyACLql2MI= github.com/roadrunner-server/api-plugins/v6 v6.0.0-beta.2/go.mod h1:2v4yUK5Kvbvq8C3IkDoBkuamq9h+7i/JLjyf7k1j5JM= -github.com/roadrunner-server/api/v4 v4.24.0 h1:99lN8nu7aD76d1fru4+MZkf9m8+YJ22Jy+qVoDwn4OY= -github.com/roadrunner-server/api/v4 v4.24.0/go.mod h1:O0LputszJr6NXMw0SKyWaiS/C9K6JVh9HV2BHKXeosA= -github.com/roadrunner-server/config/v5 v5.1.9 h1:ReWwts/prEvuC4yVJ0BRDmY5sxw/1c+hGTSdJ71hIQU= -github.com/roadrunner-server/config/v5 v5.1.9/go.mod h1:R6YyTWahW61tWHOI2BfdkQU/0Zc/2d6/JbJ/KEvq8F8= +github.com/roadrunner-server/config/v6 v6.0.0-beta.3 h1:G0EUzJ6Yw4UnleM6BhnOBbYPXKDHRmCJiGhC3nXDBwI= +github.com/roadrunner-server/config/v6 v6.0.0-beta.3/go.mod h1:eIB+c29njpcKokXrxe483FbQOBSTNGvU3hhC6W/qYSU= github.com/roadrunner-server/endure/v2 v2.6.2 h1:sIB4kTyE7gtT3fDhuYWUYn6Vt/dcPtiA6FoNS1eS+84= github.com/roadrunner-server/endure/v2 v2.6.2/go.mod h1:t/2+xpNYgGBwhzn83y2MDhvhZ19UVq1REcvqn7j7RB8= github.com/roadrunner-server/errors v1.5.0 h1:unG7LKIZrSzkCCF3YLRLA5VyqE0KKomofXVJUXJe00g= github.com/roadrunner-server/errors v1.5.0/go.mod h1:g9fo/T2C13cWRDR9PW1r0ZAOSQfNhWAZawyfkGiaHuI= github.com/roadrunner-server/events v1.0.1 h1:waCkKhxhzdK3VcI1xG22l+h+0J+Nfdpxjhyy01Un+kI= github.com/roadrunner-server/events v1.0.1/go.mod h1:WZRqoEVaFm209t52EuoT7ISUtvX6BrCi6bI/7pjkVC0= -github.com/roadrunner-server/goridge/v3 v3.8.3 h1:XmjrOFnI6ZbQTPaP39DEk8KwLUNTgjluK3pcZaW6ixQ= -github.com/roadrunner-server/goridge/v3 v3.8.3/go.mod h1:4TZU8zgkKIZCsH51qwGMpvyXCT59u/8z6q8sCe4ZGAQ= github.com/roadrunner-server/goridge/v4 v4.0.0-beta.2 h1:MgH6oiSgcl+vphsQ6JpyedkXQ/DPf8zVpn0z7rdBp10= github.com/roadrunner-server/goridge/v4 v4.0.0-beta.2/go.mod h1:Wv9CBO9VIU92e5iZIuehLHKakXgMkOzxoT4/oHDjIUA= -github.com/roadrunner-server/informer/v5 v5.1.9 h1:yl334LMqUoWXfeP4299HgY9G7mq6kX6FVCSwT+cYdfQ= -github.com/roadrunner-server/informer/v5 v5.1.9/go.mod h1:JPzSsDjLHExdQ9SbT9e8H/oB7pajgCScL/G70saQzSA= -github.com/roadrunner-server/logger/v5 v5.1.9 h1:3Kn+NYXF7Ww5LvkwMZwkv1q99t5qusIPBsreRJL08JI= -github.com/roadrunner-server/logger/v5 v5.1.9/go.mod h1:hwct/TWTmxYsVzowLx4g9HkY5z2/gpYOC+UN8btsrAA= -github.com/roadrunner-server/pool v1.1.3 h1:KMsiL6yuYBWGk73bdO0akwP+fJ63bxDF972JukCGsxI= -github.com/roadrunner-server/pool v1.1.3/go.mod h1:8ceC7NvZKJRciv+KJmcyk5CeDugoel6GD+crm5kBFW0= +github.com/roadrunner-server/informer/v6 v6.0.0-beta.2 h1:tJsNgbQ28mK5CdQCpU+BY6ScWP884nhpGYfwJalZOlU= +github.com/roadrunner-server/informer/v6 v6.0.0-beta.2/go.mod h1:nDn5jjR1ZI1Xhz01j32bSs4PHv78IE96rcqdFr/ZvgU= +github.com/roadrunner-server/logger/v6 v6.0.0-beta.3 h1:eoJKXAUSyykDfVX6eTUhmAn6Y8pS/LyI5fDP4H+G5rQ= +github.com/roadrunner-server/logger/v6 v6.0.0-beta.3/go.mod h1:MwHb3AbltHYtu7nRpml5NeYu7O+W8rCpDBeNTTEoE1M= github.com/roadrunner-server/pool/v2 v2.0.0-beta.1 h1:jpYXFtdD6QGAdAGPgMxrNi3j1CegCRpb2y+A+3GnXFA= github.com/roadrunner-server/pool/v2 v2.0.0-beta.1/go.mod h1:Bo1wT7RtL3eyQHXBUohNhtj/yAmRt6Rq8smuBg5pWkY= -github.com/roadrunner-server/resetter/v5 v5.1.9 h1:rH1nxkgvItbMEp1/JFZqcijOkkav4zo0E4wcVXBcXa8= -github.com/roadrunner-server/resetter/v5 v5.1.9/go.mod h1:P5TfzCGQMNsUDPTrjOU7XFLdRz+DtFH/FmRla+lUF94= -github.com/roadrunner-server/rpc/v5 v5.1.9 h1:AbRd2xEkWY8N3J4GUhoDeL+pnfwzKHazV4k40jZ+YDk= -github.com/roadrunner-server/rpc/v5 v5.1.9/go.mod h1:TtbPY1cPvL46Mk9Dh4qwx33WO4R3m1lZkgL2q2MfHtA= -github.com/roadrunner-server/server/v5 v5.2.10 h1:IshR3mlXJ/fh+zY17tN3Q7GgaanMzA7H9wwEz4PxCSA= -github.com/roadrunner-server/server/v5 v5.2.10/go.mod h1:oxXhRo2EDykCk8ujhdjyJCb2rPpoTt8AVy46RHRfeeo= -github.com/roadrunner-server/status/v5 v5.1.9 h1:TxDCj88Y7Bzcwbv8zwvNV1dE25n2x7IYw5M+kqadZWk= -github.com/roadrunner-server/status/v5 v5.1.9/go.mod h1:9v53l4V680aIPinjTFHr8ZKEGwvFPEeHTFCaJkWjejA= +github.com/roadrunner-server/resetter/v6 v6.0.0-beta.3 h1:+hkbf/kXpvFjx4LfkuH8dvR07rBwrStmcqJaffsfL0g= +github.com/roadrunner-server/resetter/v6 v6.0.0-beta.3/go.mod h1:zV+MfVo6jtvrop+04HNcr4z3b/22qyKXukK29kzagYc= +github.com/roadrunner-server/rpc/v6 v6.0.0-beta.4 h1:Qj2nrHIWOHE9Tys+FBG2IdoPtzgIUh6juQ5wXLGGDMw= +github.com/roadrunner-server/rpc/v6 v6.0.0-beta.4/go.mod h1:k5KT3fpnJVd27m0HbGGBiTPXlWI6eJdd6C+ohp5IE0U= +github.com/roadrunner-server/server/v6 v6.0.0-beta.6 h1:CPtH4eIYkeRKi5cPXxb0+J+LI824cqhIGXAfcH+nkjA= +github.com/roadrunner-server/server/v6 v6.0.0-beta.6/go.mod h1:SbODuCzC2gcbFhAmJDWvjf34pPrUWP5NxxVsTRQDuZ4= +github.com/roadrunner-server/status/v6 v6.0.0-beta.5 h1:H4pmqetEElH0gTHwAsm6LwL9GD8y2mWL+RK+XCYq8+Q= +github.com/roadrunner-server/status/v6 v6.0.0-beta.5/go.mod h1:ccwdIXIWrBJFx2qJsdrpcXxR917vm3GSBUruaghcPOY= github.com/roadrunner-server/tcplisten v1.5.2 h1:nn8yXYrhRDkfQ9AAu4V075uT4fZRmOnpxkawgE+bWPA= github.com/roadrunner-server/tcplisten v1.5.2/go.mod h1:DufGBz7Dlx2KrNe/4RukEvGMTqZKB0Uve1GztwcyyR8= github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= @@ -276,10 +272,6 @@ github.com/twmb/murmur3 v1.1.8 h1:8Yt9taO/WN3l08xErzjeschgZU2QSrwm1kclYq+0aRg= github.com/twmb/murmur3 v1.1.8/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/uber-go/tally/v4 v4.1.10 h1:2GSX7Tmq26wjAvOtQEc5EvRROIkX2OX4vpROt6mlRLM= github.com/uber-go/tally/v4 v4.1.10/go.mod h1:pPR56rjthjtLB8xQlEx2I1VwAwRGCh/i4xMUcmG+6z4= -github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= -github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= -github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -473,8 +465,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= -gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/validator.v2 v2.0.0-20200605151824-2b28d334fa05/go.mod h1:o4V0GXN9/CAmCsvJ0oXYZvrZOe7syiDZSN1GWGZTGzc= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/tests/helpers/helpers.go b/tests/helpers/helpers.go index 8cb89a0e..f74f888b 100644 --- a/tests/helpers/helpers.go +++ b/tests/helpers/helpers.go @@ -11,15 +11,15 @@ import ( "testing" "time" - "github.com/roadrunner-server/status/v5" + "github.com/roadrunner-server/status/v6" - configImpl "github.com/roadrunner-server/config/v5" + configImpl "github.com/roadrunner-server/config/v6" "github.com/roadrunner-server/endure/v2" - "github.com/roadrunner-server/informer/v5" - "github.com/roadrunner-server/logger/v5" - "github.com/roadrunner-server/resetter/v5" - "github.com/roadrunner-server/rpc/v5" - "github.com/roadrunner-server/server/v5" + "github.com/roadrunner-server/informer/v6" + "github.com/roadrunner-server/logger/v6" + "github.com/roadrunner-server/resetter/v6" + "github.com/roadrunner-server/rpc/v6" + "github.com/roadrunner-server/server/v6" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" roadrunnerTemporal "github.com/temporalio/roadrunner-temporal/v6" @@ -28,8 +28,7 @@ import ( "go.temporal.io/api/history/v1" temporalClient "go.temporal.io/sdk/client" "go.temporal.io/sdk/converter" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" + tlog "go.temporal.io/sdk/log" ) const ( @@ -47,54 +46,6 @@ type TestServer struct { Client temporalClient.Client } -type log struct { - zl *zap.Logger -} - -// NewZapAdapter ... which uses general log interface -func newZapAdapter(zapLogger *zap.Logger) *log { - return &log{ - zl: zapLogger.WithOptions(zap.AddCallerSkip(1)), - } -} - -func (l *log) Debug(msg string, keyvals ...any) { - l.zl.Debug(msg, l.fields(keyvals)...) -} - -func (l *log) Info(msg string, keyvals ...any) { - l.zl.Info(msg, l.fields(keyvals)...) -} - -func (l *log) Warn(msg string, keyvals ...any) { - l.zl.Warn(msg, l.fields(keyvals)...) -} - -func (l *log) Error(msg string, keyvals ...any) { - l.zl.Error(msg, l.fields(keyvals)...) -} - -func (l *log) fields(keyvals []any) []zap.Field { - // we should have an even number of keys and values - if len(keyvals)%2 != 0 { - return []zap.Field{zap.Error(fmt.Errorf("odd number of keyvals pairs: %v", keyvals))} - } - - zf := make([]zap.Field, len(keyvals)/2) - j := 0 - for i := 0; i < len(keyvals); i += 2 { - key, ok := keyvals[i].(string) - if !ok { - key = fmt.Sprintf("%v", keyvals[i]) - } - - zf[j] = zap.Any(key, keyvals[i+1]) - j++ - } - - return zf -} - func NewTestServer(t *testing.T, stopCh chan struct{}, wg *sync.WaitGroup, configPath string) *TestServer { container := endure.New(slog.LevelDebug, endure.GracefulShutdownTimeout(time.Minute)) @@ -141,7 +92,7 @@ func NewTestServer(t *testing.T, stopCh chan struct{}, wg *sync.WaitGroup, confi HostPort: "127.0.0.1:7233", Namespace: "default", DataConverter: dc, - Logger: newZapAdapter(initLogger()), + Logger: tlog.NewStructuredLogger(initLogger()), }) if err != nil { t.Fatal(err) @@ -215,7 +166,7 @@ func NewTestServerTLS(t *testing.T, stopCh chan struct{}, wg *sync.WaitGroup, co HostPort: "127.0.0.1:7233", Namespace: "default", DataConverter: dc, - Logger: newZapAdapter(initLogger()), + Logger: tlog.NewStructuredLogger(initLogger()), ConnectionOptions: temporalClient.ConnectionOptions{ TLS: &tls.Config{ MinVersion: tls.VersionTLS12, @@ -285,7 +236,7 @@ func NewTestServerWithInterceptor(t *testing.T, stopCh chan struct{}, wg *sync.W HostPort: "127.0.0.1:7233", Namespace: "default", DataConverter: dc, - Logger: newZapAdapter(initLogger()), + Logger: tlog.NewStructuredLogger(initLogger()), }) require.NoError(t, err) @@ -345,7 +296,7 @@ func NewTestServerWithDataConverter(t *testing.T, stopCh chan struct{}, wg *sync HostPort: "127.0.0.1:7233", Namespace: "default", DataConverter: dc, - Logger: newZapAdapter(initLogger()), + Logger: tlog.NewStructuredLogger(initLogger()), }) require.NoError(t, err) @@ -402,7 +353,7 @@ func NewTestServerWithOtelInterceptor(t *testing.T, stopCh chan struct{}, wg *sy HostPort: "127.0.0.1:7233", Namespace: "default", DataConverter: dc, - Logger: newZapAdapter(initLogger()), + Logger: tlog.NewStructuredLogger(initLogger()), }) require.NoError(t, err) @@ -461,29 +412,9 @@ func (s *TestServer) AssertNotContainsEvent(client temporalClient.Client, t *tes } } -func initLogger() *zap.Logger { - cfg := zap.Config{ - Level: zap.NewAtomicLevelAt(zap.ErrorLevel), - Encoding: "console", - EncoderConfig: zapcore.EncoderConfig{ - MessageKey: "message", - LevelKey: "level", - TimeKey: "time", - CallerKey: "caller", - NameKey: "name", - StacktraceKey: "stack", - EncodeLevel: zapcore.CapitalLevelEncoder, - EncodeTime: zapcore.ISO8601TimeEncoder, - EncodeCaller: zapcore.ShortCallerEncoder, - }, - OutputPaths: []string{"stderr"}, - ErrorOutputPaths: []string{"stderr"}, - } - - l, err := cfg.Build(zap.AddCaller()) - if err != nil { - panic(err) - } - - return l +func initLogger() *slog.Logger { + return slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ + Level: slog.LevelError, + AddSource: true, + })) } From d75182f6795d349db50799ae3170fc704c5cefa5 Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Fri, 12 Jun 2026 14:09:20 +0200 Subject: [PATCH 09/11] ci: point coverage collection at the v6 module path --- .github/workflows/linux.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index b4731052..8e1cbe9a 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -146,7 +146,7 @@ jobs: cd tests docker compose -f env/docker-compose-temporal-updates.yaml up -d --remove-orphans - go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v5/... -coverprofile=./coverage-ci/rrt_upd.out -covermode=atomic ./updates + go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v6/... -coverprofile=./coverage-ci/rrt_upd.out -covermode=atomic ./updates docker compose -f env/docker-compose-temporal-updates.yaml up -d --remove-orphans @@ -224,22 +224,22 @@ jobs: - name: Run Temporal canceller module tests run: | - go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v5/... -coverprofile=./tests/coverage-ci/rrt_c.out -covermode=atomic ./canceller/... + go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v6/... -coverprofile=./tests/coverage-ci/rrt_c.out -covermode=atomic ./canceller/... - name: Run Temporal dataconverter module tests run: | - go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v5/... -coverprofile=./tests/coverage-ci/rrt_dc.out -covermode=atomic ./dataconverter/... + go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v6/... -coverprofile=./tests/coverage-ci/rrt_dc.out -covermode=atomic ./dataconverter/... - name: Run Temporal queue module tests run: | - go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v5/... -coverprofile=./tests/coverage-ci/rrt_q.out -covermode=atomic ./queue/... + go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v6/... -coverprofile=./tests/coverage-ci/rrt_q.out -covermode=atomic ./queue/... - name: Run Temporal tests with coverage run: | cd tests docker compose -f env/docker-compose-temporal.yaml up -d --remove-orphans - go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v5/... -coverprofile=./coverage-ci/rrt.out -covermode=atomic ./general + go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v6/... -coverprofile=./coverage-ci/rrt.out -covermode=atomic ./general docker compose -f env/docker-compose-temporal.yaml up -d --remove-orphans @@ -313,7 +313,7 @@ jobs: docker compose -f env/temporal_tls/docker-compose.yml up -d --remove-orphans sleep 60 - go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v5/... -coverprofile=./coverage-ci/rrt_tls.out -covermode=atomic ./tls + go test -timeout 20m -v -race -cover -tags=debug -failfast -coverpkg=github.com/temporalio/roadrunner-temporal/v6/... -coverprofile=./coverage-ci/rrt_tls.out -covermode=atomic ./tls docker compose -f env/temporal_tls/docker-compose.yml down @@ -342,8 +342,8 @@ jobs: tail -q -n +2 *.out >> summary.txt awk ' NR == 1 { print; next } - /^github\.com\/temporalio\/roadrunner-temporal\/v5\// { - sub(/^github\.com\/temporalio\/roadrunner-temporal\/v5\//, "", $0) + /^github\.com\/temporalio\/roadrunner-temporal\/v6\// { + sub(/^github\.com\/temporalio\/roadrunner-temporal\/v6\//, "", $0) print } ' summary.txt > summary.filtered.txt From 1f05ec29880bfed78315cf6e2c2a33d885d45956 Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Fri, 12 Jun 2026 14:10:24 +0200 Subject: [PATCH 10/11] fix: complete the slog migration in the plugin sources --- aggregatedpool/activity.go | 6 +- aggregatedpool/handler.go | 115 +++++++++++++++---------------- aggregatedpool/local_activity.go | 8 +-- aggregatedpool/workers.go | 14 ++-- aggregatedpool/workflow.go | 28 ++++---- api/interfaces.go | 6 +- go.work.sum | 5 ++ internal.go | 9 ++- internal/codec/proto/proto.go | 12 ++-- metrics.go | 8 +-- plugin.go | 27 ++++---- rpc.go | 61 ++++++++-------- 12 files changed, 149 insertions(+), 150 deletions(-) diff --git a/aggregatedpool/activity.go b/aggregatedpool/activity.go index 2451ebdc..ec10356f 100644 --- a/aggregatedpool/activity.go +++ b/aggregatedpool/activity.go @@ -2,6 +2,7 @@ package aggregatedpool import ( "context" + "log/slog" "sync" "sync/atomic" "unsafe" @@ -14,7 +15,6 @@ import ( commonpb "go.temporal.io/api/common/v1" tActivity "go.temporal.io/sdk/activity" "go.temporal.io/sdk/temporal" - "go.uber.org/zap" ) const ( @@ -26,7 +26,7 @@ const ( type Activity struct { codec api.Codec pool api.Pool - log *zap.Logger + log *slog.Logger seqID uint64 running sync.Map @@ -34,7 +34,7 @@ type Activity struct { disableActivityWorkers bool } -func NewActivityDefinition(ac api.Codec, p api.Pool, log *zap.Logger, disableActivityWorkers bool) *Activity { +func NewActivityDefinition(ac api.Codec, p api.Pool, log *slog.Logger, disableActivityWorkers bool) *Activity { return &Activity{ log: log, codec: ac, diff --git a/aggregatedpool/handler.go b/aggregatedpool/handler.go index e373c325..c8c4c719 100644 --- a/aggregatedpool/handler.go +++ b/aggregatedpool/handler.go @@ -15,7 +15,6 @@ import ( bindings "go.temporal.io/sdk/internalbindings" "go.temporal.io/sdk/temporal" "go.temporal.io/sdk/workflow" - "go.uber.org/zap" ) const ( @@ -38,7 +37,7 @@ func (wp *Workflow) getContext() *internal.Context { } func (wp *Workflow) handleUpdate(name string, id string, input *commonpb.Payloads, header *commonpb.Header, callbacks bindings.UpdateCallbacks) { - wp.log.Debug("update request received", zap.String("RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID), zap.String("name", name), zap.String("id", id)) + wp.log.Debug("update request received", "RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID, "name", name, "id", id) // save update name wp.updatesQueue[name] = struct{}{} @@ -48,7 +47,7 @@ func (wp *Workflow) handleUpdate(name string, id string, input *commonpb.Payload updatesQueueCb := func() { // validate callback wp.updateValidateCb[id] = func(msg *internal.Message) { - wp.log.Debug("validate request callback", zap.String("RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID), zap.String("name", name), zap.String("id", id), zap.Bool("is_replaying", wp.env.IsReplaying()), zap.Any("result", msg)) + wp.log.Debug("validate request callback", "RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID, "name", name, "id", id, "is_replaying", wp.env.IsReplaying(), "result", msg) if !wp.env.IsReplaying() { // before acceptance, we have only one option - reject if msg.Failure != nil { @@ -63,7 +62,7 @@ func (wp *Workflow) handleUpdate(name string, id string, input *commonpb.Payload // execute callback wp.updateCompleteCb[id] = func(msg *internal.Message) { - wp.log.Debug("update request callback", zap.String("RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID), zap.String("name", name), zap.String("id", id), zap.Any("result", msg)) + wp.log.Debug("update request callback", "RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID, "name", name, "id", id, "result", msg) if msg.Failure != nil { callbacks.Complete(nil, temporal.GetDefaultFailureConverter().FailureToError(msg.Failure)) return @@ -101,7 +100,7 @@ func (wp *Workflow) handleCancel() { // schedule the signal processing func (wp *Workflow) handleSignal(name string, input *commonpb.Payloads, header *commonpb.Header) error { - wp.log.Debug("signal request", zap.String("RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID), zap.String("name", name)) + wp.log.Debug("signal request", "RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID, "name", name) wp.mq.PushCommand( internal.InvokeSignal{ RunID: wp.env.WorkflowInfo().WorkflowExecution.RunID, @@ -119,7 +118,7 @@ func (wp *Workflow) handleSignal(name string, input *commonpb.Payloads, header * func (wp *Workflow) handleQuery(queryType string, queryArgs *commonpb.Payloads, header *commonpb.Header) (*commonpb.Payloads, error) { const op = errors.Op("workflow_process_handle_query") - wp.log.Debug("query request", zap.String("RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID), zap.String("name", queryType)) + wp.log.Debug("query request", "RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID, "name", queryType) result, err := wp.runCommand(internal.InvokeQuery{ RunID: wp.env.WorkflowInfo().WorkflowExecution.RunID, @@ -143,28 +142,28 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { switch command := msg.Command.(type) { case *internal.ExecuteActivity: - wp.log.Debug("activity request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("activity request", "ID", msg.ID) params := command.ActivityParams(wp.env, msg.Payloads, msg.Header) activityID := wp.env.ExecuteActivity(params, wp.createCallback(msg.ID, "activity")) wp.canceller.Register(msg.ID, func() error { - wp.log.Debug("registering activity canceller", zap.String("activityID", activityID.String())) + wp.log.Debug("registering activity canceller", "activityID", activityID.String()) wp.env.RequestCancelActivity(activityID) return nil }) case *internal.ExecuteLocalActivity: - wp.log.Debug("local activity request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("local activity request", "ID", msg.ID) params := command.LocalActivityParams(wp.env, wp.la, msg.Payloads, msg.Header) activityID := wp.env.ExecuteLocalActivity(params, wp.createLocalActivityCallback(msg.ID)) wp.canceller.Register(msg.ID, func() error { - wp.log.Debug("registering local activity canceller", zap.String("activityID", activityID.String())) + wp.log.Debug("registering local activity canceller", "activityID", activityID.String()) wp.env.RequestCancelLocalActivity(activityID) return nil }) case *internal.ExecuteChildWorkflow: - wp.log.Debug("execute child workflow request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("execute child workflow request", "ID", msg.ID) params := command.WorkflowParams(wp.env, msg.Payloads, msg.Header) // always use deterministic id @@ -183,7 +182,7 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { }) case *internal.GetChildWorkflowExecution: - wp.log.Debug("get child workflow execution request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("get child workflow execution request", "ID", msg.ID) wp.ids.Listen(command.ID, func(w bindings.WorkflowExecution, err error) { cl := wp.createCallback(msg.ID, "GetChildWorkflow") @@ -201,20 +200,20 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { }) case *internal.NewTimer: - wp.log.Debug("timer request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("timer request", "ID", msg.ID) timerID := wp.env.NewTimer(command.ToDuration(), workflow.TimerOptions{ Summary: command.Summary, }, wp.createCallback(msg.ID, "NewTimer")) wp.canceller.Register(msg.ID, func() error { if timerID != nil { - wp.log.Debug("cancel timer request", zap.String("timerID", timerID.String())) + wp.log.Debug("cancel timer request", "timerID", timerID.String()) wp.env.RequestCancelTimer(*timerID) } return nil }) case *internal.GetVersion: - wp.log.Debug("get version request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("get version request", "ID", msg.ID) version := wp.env.GetVersion( command.ChangeID, workflow.Version(command.MinSupported), @@ -233,7 +232,7 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { } case *internal.SideEffect: - wp.log.Debug("side-effect request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("side-effect request", "ID", msg.ID) wp.env.SideEffect( func() (*commonpb.Payloads, error) { return msg.Payloads, nil @@ -243,15 +242,15 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { ) case *internal.UpdateCompleted: - wp.log.Debug("complete update request", zap.String("update id", command.ID)) + wp.log.Debug("complete update request", "update id", command.ID) if command.ID == "" { - wp.log.Error("update id is empty, can't complete update", zap.String("workflow id", wp.env.WorkflowInfo().WorkflowExecution.ID), zap.String("run id", wp.env.WorkflowInfo().WorkflowExecution.RunID)) + wp.log.Error("update id is empty, can't complete update", "workflow id", wp.env.WorkflowInfo().WorkflowExecution.ID, "run id", wp.env.WorkflowInfo().WorkflowExecution.RunID) return errors.Str("update id is empty, can't complete update") } if _, ok := wp.updateCompleteCb[command.ID]; !ok { - wp.log.Warn("no such update ID, can't complete update", zap.String("requested id", command.ID)) + wp.log.Warn("no such update ID, can't complete update", "requested id", command.ID) // TODO(rustatian): error here? return nil } @@ -260,15 +259,15 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { delete(wp.updateCompleteCb, command.ID) case *internal.UpdateValidated: - wp.log.Debug("validate update request", zap.String("update id", command.ID)) + wp.log.Debug("validate update request", "update id", command.ID) if command.ID == "" { - wp.log.Error("update id is empty, can't validate update", zap.String("workflow id", wp.env.WorkflowInfo().WorkflowExecution.ID), zap.String("run id", wp.env.WorkflowInfo().WorkflowExecution.RunID)) + wp.log.Error("update id is empty, can't validate update", "workflow id", wp.env.WorkflowInfo().WorkflowExecution.ID, "run id", wp.env.WorkflowInfo().WorkflowExecution.RunID) return errors.Str("update id is empty, can't validate update") } if _, ok := wp.updateValidateCb[command.ID]; !ok { - wp.log.Warn("no such update ID, can't validate update", zap.String("requested id", command.ID)) + wp.log.Warn("no such update ID, can't validate update", "requested id", command.ID) // TODO(rustatian): error here? return nil } @@ -281,7 +280,7 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { } case *internal.CompleteWorkflow: - wp.log.Debug("complete workflow request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("complete workflow request", "ID", msg.ID) result, _ := wp.env.GetDataConverter().ToPayloads(completed) wp.mq.PushResponse(msg.ID, result, wp.getWorkflowWorkerPid()) @@ -293,7 +292,7 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { wp.env.Complete(nil, temporal.GetDefaultFailureConverter().FailureToError(msg.Failure)) case *internal.ContinueAsNew: - wp.log.Debug("continue-as-new request", zap.Uint64("ID", msg.ID), zap.String("name", command.Name)) + wp.log.Debug("continue-as-new request", "ID", msg.ID, "name", command.Name) result, _ := wp.env.GetDataConverter().ToPayloads(completed) wp.mq.PushResponse(msg.ID, result, wp.getWorkflowWorkerPid()) @@ -309,14 +308,14 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { }) case *internal.UpsertWorkflowSearchAttributes: - wp.log.Debug("upsert search attributes request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("upsert search attributes request", "ID", msg.ID) err := wp.env.UpsertSearchAttributes(command.SearchAttributes) if err != nil { return errors.E(op, err) } case *internal.UpsertWorkflowTypedSearchAttributes: - wp.log.Debug("upsert typed search attributes request", zap.Uint64("ID", msg.ID), zap.Any("search_attributes", command.SearchAttributes)) + wp.log.Debug("upsert typed search attributes request", "ID", msg.ID, "search_attributes", command.SearchAttributes) var sau []temporal.SearchAttributeUpdate for k, v := range command.SearchAttributes { @@ -327,14 +326,14 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { continue } if v.Value == nil { - wp.log.Warn("field value is not set", zap.String("key", k)) + wp.log.Warn("field value is not set", "key", k) continue } if tt, ok := v.Value.(bool); ok { sau = append(sau, temporal.NewSearchAttributeKeyBool(k).ValueSet(tt)) } else { - wp.log.Warn("field value is not a bool type", zap.String("key", k), zap.Any("value", v.Value)) + wp.log.Warn("field value is not a bool type", "key", k, "value", v.Value) } case internal.FloatType: @@ -344,14 +343,14 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { } if v.Value == nil { - wp.log.Warn("field value is not set", zap.String("key", k)) + wp.log.Warn("field value is not set", "key", k) continue } if tt, ok := v.Value.(float64); ok { sau = append(sau, temporal.NewSearchAttributeKeyFloat64(k).ValueSet(tt)) } else { - wp.log.Warn("field value is not a float64 type", zap.String("key", k), zap.Any("value", v.Value)) + wp.log.Warn("field value is not a float64 type", "key", k, "value", v.Value) } case internal.IntType: @@ -361,7 +360,7 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { } if v.Value == nil { - wp.log.Warn("field value is not set", zap.String("key", k)) + wp.log.Warn("field value is not set", "key", k) continue } @@ -381,12 +380,12 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { case string: i, err := strconv.ParseInt(ti, 10, 64) if err != nil { - wp.log.Warn("failed to parse int", zap.Error(err)) + wp.log.Warn("failed to parse int", "error", err) continue } sau = append(sau, temporal.NewSearchAttributeKeyInt64(k).ValueSet(i)) default: - wp.log.Warn("field value is not an int type", zap.String("key", k), zap.Any("value", v.Value)) + wp.log.Warn("field value is not an int type", "key", k, "value", v.Value) } case internal.KeywordType: @@ -396,14 +395,14 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { } if v.Value == nil { - wp.log.Warn("field value is not set", zap.String("key", k)) + wp.log.Warn("field value is not set", "key", k) continue } if tt, ok := v.Value.(string); ok { sau = append(sau, temporal.NewSearchAttributeKeyKeyword(k).ValueSet(tt)) } else { - wp.log.Warn("field value is not a string type", zap.String("key", k), zap.Any("value", v.Value)) + wp.log.Warn("field value is not a string type", "key", k, "value", v.Value) } case internal.KeywordListType: if v.Operation == internal.TypedSearchAttributeOperationUnset { @@ -412,7 +411,7 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { } if v.Value == nil { - wp.log.Warn("field value is not set", zap.String("key", k)) + wp.log.Warn("field value is not set", "key", k) continue } @@ -428,7 +427,7 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { } sau = append(sau, temporal.NewSearchAttributeKeyKeywordList(k).ValueSet(res)) default: - wp.log.Warn("field value is not a []string (strings array) type", zap.String("key", k), zap.Any("value", v.Value)) + wp.log.Warn("field value is not a []string (strings array) type", "key", k, "value", v.Value) } case internal.StringType: @@ -438,14 +437,14 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { } if v.Value == nil { - wp.log.Warn("field value is not set", zap.String("key", k)) + wp.log.Warn("field value is not set", "key", k) continue } if tt, ok := v.Value.(string); ok { sau = append(sau, temporal.NewSearchAttributeKeyString(k).ValueSet(tt)) } else { - wp.log.Warn("field value is not a string type", zap.String("key", k), zap.Any("value", v.Value)) + wp.log.Warn("field value is not a string type", "key", k, "value", v.Value) } case internal.DatetimeType: if v.Operation == internal.TypedSearchAttributeOperationUnset { @@ -454,7 +453,7 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { } if v.Value == nil { - wp.log.Warn("field value is not set", zap.String("key", k)) + wp.log.Warn("field value is not set", "key", k) continue } @@ -466,7 +465,7 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { sau = append(sau, temporal.NewSearchAttributeKeyTime(k).ValueSet(tm)) } else { - wp.log.Warn("bool field value is not a bool type", zap.String("key", k), zap.Any("value", v.Value)) + wp.log.Warn("bool field value is not a bool type", "key", k, "value", v.Value) } } } @@ -482,7 +481,7 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { } case *internal.SignalExternalWorkflow: - wp.log.Debug("signal external workflow request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("signal external workflow request", "ID", msg.ID) wp.env.SignalExternalWorkflow( command.Namespace, command.WorkflowID, @@ -496,11 +495,11 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { ) case *internal.CancelExternalWorkflow: - wp.log.Debug("cancel external workflow request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("cancel external workflow request", "ID", msg.ID) wp.env.RequestCancelExternalWorkflow(command.Namespace, command.WorkflowID, command.RunID, wp.createCallback(msg.ID, "CancelExternalWorkflow")) case *internal.Cancel: - wp.log.Debug("cancel request", zap.Uint64("ID", msg.ID)) + wp.log.Debug("cancel request", "ID", msg.ID) err := wp.canceller.Cancel(command.CommandIDs...) if err != nil { return errors.E(op, err) @@ -515,12 +514,12 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { } case *internal.Panic: - wp.log.Debug("panic", zap.String("failure", msg.Failure.String())) + wp.log.Debug("panic", "failure", msg.Failure.String()) // do not wrap error to pass it directly to Temporal return temporal.GetDefaultFailureConverter().FailureToError(msg.Failure) case *internal.UpsertMemo: - wp.log.Debug("upsert memo request", zap.Uint64("ID", msg.ID), zap.Any("memos", command.Memo)) + wp.log.Debug("upsert memo request", "ID", msg.ID, "memos", command.Memo) if len(command.Memo) == 0 { return nil } @@ -539,29 +538,29 @@ func (wp *Workflow) handleMessage(msg *internal.Message) error { func (wp *Workflow) createLocalActivityCallback(id uint64) bindings.LocalActivityResultHandler { callback := func(lar *bindings.LocalActivityResultWrapper) { - wp.log.Debug("executing local activity callback", zap.Uint64("ID", id)) + wp.log.Debug("executing local activity callback", "ID", id) wp.canceller.Discard(id) if lar.Err != nil { - wp.log.Debug("error", zap.Error(lar.Err), zap.Int32("attempt", lar.Attempt), zap.Duration("backoff", lar.Backoff)) + wp.log.Debug("error", "error", lar.Err, "attempt", lar.Attempt, "backoff", lar.Backoff) wp.mq.PushError(id, temporal.GetDefaultFailureConverter().ErrorToFailure(lar.Err), wp.getWorkflowWorkerPid()) return } - wp.log.Debug("pushing local activity response", zap.Uint64("ID", id)) + wp.log.Debug("pushing local activity response", "ID", id) wp.mq.PushResponse(id, lar.Result, wp.getWorkflowWorkerPid()) } return func(lar *bindings.LocalActivityResultWrapper) { // timer cancel callback can happen inside the loop if atomic.LoadUint32(&wp.inLoop) == 1 { - wp.log.Debug("calling local activity callback IN LOOP", zap.Uint64("ID", id)) + wp.log.Debug("calling local activity callback IN LOOP", "ID", id) callback(lar) return } wp.callbacks = append(wp.callbacks, func() error { - wp.log.Debug("appending local activity callback", zap.Uint64("ID", id)) + wp.log.Debug("appending local activity callback", "ID", id) callback(lar) return nil }) @@ -570,16 +569,16 @@ func (wp *Workflow) createLocalActivityCallback(id uint64) bindings.LocalActivit func (wp *Workflow) createCallback(id uint64, t string) bindings.ResultHandler { callback := func(result *commonpb.Payloads, err error) { - wp.log.Debug("executing callback", zap.Uint64("ID", id), zap.String("type", t)) + wp.log.Debug("executing callback", "ID", id, "type", t) wp.canceller.Discard(id) if err != nil { - wp.log.Debug("error", zap.Error(err), zap.String("type", t)) + wp.log.Debug("error", "error", err, "type", t) wp.mq.PushError(id, temporal.GetDefaultFailureConverter().ErrorToFailure(err), wp.getWorkflowWorkerPid()) return } - wp.log.Debug("pushing response", zap.Uint64("ID", id), zap.String("type", t)) + wp.log.Debug("pushing response", "ID", id, "type", t) // fetch original payload wp.mq.PushResponse(id, result, wp.getWorkflowWorkerPid()) } @@ -587,13 +586,13 @@ func (wp *Workflow) createCallback(id uint64, t string) bindings.ResultHandler { return func(result *commonpb.Payloads, err error) { // timer cancel callback can happen inside the loop if atomic.LoadUint32(&wp.inLoop) == 1 { - wp.log.Debug("calling callback IN LOOP", zap.Uint64("ID", id), zap.String("type", t)) + wp.log.Debug("calling callback IN LOOP", "ID", id, "type", t) callback(result, err) return } wp.callbacks = append(wp.callbacks, func() error { - wp.log.Debug("appending callback", zap.Uint64("ID", id), zap.String("type", t)) + wp.log.Debug("appending callback", "ID", id, "type", t) callback(result, err) return nil }) @@ -603,7 +602,7 @@ func (wp *Workflow) createCallback(id uint64, t string) bindings.ResultHandler { // callback to be called inside the queue processing, adds new messages at the end of the queue func (wp *Workflow) createContinuableCallback(id uint64, t string) bindings.ResultHandler { callback := func(result *commonpb.Payloads, err error) { - wp.log.Debug("executing continuable callback", zap.Uint64("ID", id), zap.String("type", t)) + wp.log.Debug("executing continuable callback", "ID", id, "type", t) wp.canceller.Discard(id) if err != nil { @@ -744,7 +743,7 @@ func (wp *Workflow) getWorkflowWorkerPid() int { wp.log.Debug("fetching workflow worker pid") wfw := wp.pool.Workers() if len(wfw) > 0 { - wp.log.Debug("workflow worker pid found", zap.Int("pid", int(wfw[0].Pid()))) + wp.log.Debug("workflow worker pid found", "pid", int(wfw[0].Pid())) return int(wfw[0].Pid()) } wp.log.Debug("workflow worker pid not found") diff --git a/aggregatedpool/local_activity.go b/aggregatedpool/local_activity.go index 46627f42..9a8ec008 100644 --- a/aggregatedpool/local_activity.go +++ b/aggregatedpool/local_activity.go @@ -2,6 +2,7 @@ package aggregatedpool import ( "context" + "log/slog" "sync" "sync/atomic" @@ -14,17 +15,16 @@ import ( commonpb "go.temporal.io/api/common/v1" tActivity "go.temporal.io/sdk/activity" "go.temporal.io/sdk/temporal" - "go.uber.org/zap" ) type LocalActivityFn struct { codec api.Codec pool api.Pool - log *zap.Logger + log *slog.Logger seqID uint64 } -func NewLocalActivityFn(codec api.Codec, pool api.Pool, log *zap.Logger) *LocalActivityFn { +func NewLocalActivityFn(codec api.Codec, pool api.Pool, log *slog.Logger) *LocalActivityFn { return &LocalActivityFn{ codec: codec, pool: pool, @@ -54,7 +54,7 @@ func (la *LocalActivityFn) ExecuteLA(ctx context.Context, hdr *commonpb.Header, Header: hdr, } - la.log.Debug("executing local activity fn", zap.Uint64("ID", msg.ID), zap.String("task-queue", info.TaskQueue), zap.String("la ID", info.ActivityID)) + la.log.Debug("executing local activity fn", "ID", msg.ID, "task-queue", info.TaskQueue, "la ID", info.ActivityID) pl := getPld() defer putPld(pl) diff --git a/aggregatedpool/workers.go b/aggregatedpool/workers.go index c4d41f33..d6a2123a 100644 --- a/aggregatedpool/workers.go +++ b/aggregatedpool/workers.go @@ -2,6 +2,7 @@ package aggregatedpool import ( "fmt" + "log/slog" "strings" "github.com/google/uuid" @@ -14,7 +15,6 @@ import ( sdkinterceptor "go.temporal.io/sdk/interceptor" "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" - "go.uber.org/zap" ) const tq = "taskqueue" @@ -116,7 +116,7 @@ func registerWorkflow(register func(), name, taskQueue string) (err error) { return nil } -func TemporalWorkers(wDef *Workflow, actDef *Activity, wi []*internal.WorkerInfo, log *zap.Logger, tc temporalClient.Client, interceptors map[string]api.Interceptor, configuredInterceptors []string) ([]worker.Worker, error) { +func TemporalWorkers(wDef *Workflow, actDef *Activity, wi []*internal.WorkerInfo, log *slog.Logger, tc temporalClient.Client, interceptors map[string]api.Interceptor, configuredInterceptors []string) ([]worker.Worker, error) { resolved, err := ResolveInterceptors(interceptors, configuredInterceptors) if err != nil { return nil, err @@ -125,7 +125,7 @@ func TemporalWorkers(wDef *Workflow, actDef *Activity, wi []*internal.WorkerInfo workers := make([]worker.Worker, 0, len(wi)) for i := range wi { - log.Debug("worker info", zap.Any("worker_info", wi[i])) + log.Debug("worker info", "worker_info", wi[i]) // Override to 0: RoadRunner manages worker lifecycle independently wi[i].Options.WorkerStopTimeout = 0 @@ -160,11 +160,11 @@ func TemporalWorkers(wDef *Workflow, actDef *Activity, wi []*internal.WorkerInfo return nil, err } - log.Debug("workflow registered", zap.String(tq, wi[i].TaskQueue), zap.Any("workflow name", wf.Name), zap.Int("versioning_behavior", int(wf.VersioningBehavior))) + log.Debug("workflow registered", tq, wi[i].TaskQueue, "workflow name", wf.Name, "versioning_behavior", int(wf.VersioningBehavior)) } if actDef.disableActivityWorkers { - log.Debug("activity workers disabled", zap.String(tq, wi[i].TaskQueue)) + log.Debug("activity workers disabled", tq, wi[i].TaskQueue) // add worker to the pool without activities workers = append(workers, wrk) continue @@ -177,13 +177,13 @@ func TemporalWorkers(wDef *Workflow, actDef *Activity, wi []*internal.WorkerInfo SkipInvalidStructFunctions: false, }) - log.Debug("activity registered", zap.String(tq, wi[i].TaskQueue), zap.Any("workflow name", wi[i].Activities[j].Name)) + log.Debug("activity registered", tq, wi[i].TaskQueue, "workflow name", wi[i].Activities[j].Name) } // add worker to the pool workers = append(workers, wrk) } - log.Debug("workers initialized", zap.Int("num_workers", len(workers))) + log.Debug("workers initialized", "num_workers", len(workers)) return workers, nil } diff --git a/aggregatedpool/workflow.go b/aggregatedpool/workflow.go index 93f0ecc3..c63a2d0e 100644 --- a/aggregatedpool/workflow.go +++ b/aggregatedpool/workflow.go @@ -3,6 +3,7 @@ package aggregatedpool import ( "context" "fmt" + "log/slog" "strconv" "sync" "sync/atomic" @@ -19,7 +20,6 @@ import ( enumspb "go.temporal.io/api/enums/v1" temporalClient "go.temporal.io/sdk/client" bindings "go.temporal.io/sdk/internalbindings" - "go.uber.org/zap" ) // implements WorkflowDefinition interface @@ -67,7 +67,7 @@ type Workflow struct { updateCompleteCb map[string]func(res *internal.Message) updateValidateCb map[string]func(res *internal.Message) - log *zap.Logger + log *slog.Logger mh temporalClient.MetricsHandler // objects pool @@ -75,7 +75,7 @@ type Workflow struct { } // NewWorkflowDefinition ... WorkflowDefinition Constructor -func NewWorkflowDefinition(codec api.Codec, la LaFn, pool api.Pool, log *zap.Logger) *Workflow { +func NewWorkflowDefinition(codec api.Codec, la LaFn, pool api.Pool, log *slog.Logger) *Workflow { return &Workflow{ rrID: uuid.NewString(), log: log, @@ -116,7 +116,7 @@ func (wp *Workflow) NewWorkflowDefinition() bindings.WorkflowDefinition { // Execute implementation must be asynchronous. func (wp *Workflow) Execute(env bindings.WorkflowEnvironment, header *commonpb.Header, input *commonpb.Payloads) { - wp.log.Debug("workflow execute", zap.String("runID", env.WorkflowInfo().WorkflowExecution.RunID), zap.Any("workflow info", env.WorkflowInfo())) + wp.log.Debug("workflow execute", "runID", env.WorkflowInfo().WorkflowExecution.RunID, "workflow info", env.WorkflowInfo()) wp.mh = env.GetMetricsHandler() wp.env = env @@ -164,7 +164,7 @@ func (wp *Workflow) Execute(env bindings.WorkflowEnvironment, header *commonpb.H case enumspb.INDEXED_VALUE_TYPE_TEXT: str, ok := v.(string) if !ok { - wp.log.Warn("typed search attribute found, but it is not a string", zap.String("key", k.GetName())) + wp.log.Warn("typed search attribute found, but it is not a string", "key", k.GetName()) continue } tsaParsed[k.GetName()] = &internal.TypedSearchAttribute{ @@ -174,7 +174,7 @@ func (wp *Workflow) Execute(env bindings.WorkflowEnvironment, header *commonpb.H case enumspb.INDEXED_VALUE_TYPE_KEYWORD: str, ok := v.(string) if !ok { - wp.log.Warn("typed search attribute found, but it is not a string[keyword]", zap.String("key", k.GetName())) + wp.log.Warn("typed search attribute found, but it is not a string[keyword]", "key", k.GetName()) continue } tsaParsed[k.GetName()] = &internal.TypedSearchAttribute{ @@ -196,7 +196,7 @@ func (wp *Workflow) Execute(env bindings.WorkflowEnvironment, header *commonpb.H case string: res, err := strconv.Atoi(tt) if err != nil { - wp.log.Warn("typed search attribute found, but it is not an int", zap.Error(err), zap.String("key", k.GetName())) + wp.log.Warn("typed search attribute found, but it is not an int", "error", err, "key", k.GetName()) continue } tsaParsed[k.GetName()] = &internal.TypedSearchAttribute{ @@ -204,13 +204,13 @@ func (wp *Workflow) Execute(env bindings.WorkflowEnvironment, header *commonpb.H Value: res, } default: - wp.log.Warn("typed search attribute found, but it is not an int", zap.String("key", k.GetName())) + wp.log.Warn("typed search attribute found, but it is not an int", "key", k.GetName()) continue } case enumspb.INDEXED_VALUE_TYPE_DOUBLE: str, ok := v.(float64) if !ok { - wp.log.Warn("typed search attribute found, but it is not a float64", zap.String("key", k.GetName())) + wp.log.Warn("typed search attribute found, but it is not a float64", "key", k.GetName()) continue } tsaParsed[k.GetName()] = &internal.TypedSearchAttribute{ @@ -220,7 +220,7 @@ func (wp *Workflow) Execute(env bindings.WorkflowEnvironment, header *commonpb.H case enumspb.INDEXED_VALUE_TYPE_BOOL: str, ok := v.(bool) if !ok { - wp.log.Warn("typed search attribute found, but it is not a bool", zap.String("key", k.GetName())) + wp.log.Warn("typed search attribute found, but it is not a bool", "key", k.GetName()) continue } tsaParsed[k.GetName()] = &internal.TypedSearchAttribute{ @@ -230,7 +230,7 @@ func (wp *Workflow) Execute(env bindings.WorkflowEnvironment, header *commonpb.H case enumspb.INDEXED_VALUE_TYPE_DATETIME: str, ok := v.(time.Time) if !ok { - wp.log.Warn("typed search attribute found, but it is not a datetime", zap.String("key", k.GetName())) + wp.log.Warn("typed search attribute found, but it is not a datetime", "key", k.GetName()) continue } tsaParsed[k.GetName()] = &internal.TypedSearchAttribute{ @@ -240,7 +240,7 @@ func (wp *Workflow) Execute(env bindings.WorkflowEnvironment, header *commonpb.H case enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST: str, ok := v.([]string) if !ok { - wp.log.Warn("typed search attribute found, but it is not a []string", zap.String("key", k.GetName())) + wp.log.Warn("typed search attribute found, but it is not a []string", "key", k.GetName()) continue } tsaParsed[k.GetName()] = &internal.TypedSearchAttribute{ @@ -284,7 +284,7 @@ func (wp *Workflow) OnWorkflowTaskStarted(t time.Duration) { atomic.StoreUint32(&wp.inLoop, 0) }() - wp.log.Debug("workflow task started", zap.Duration("time", t)) + wp.log.Debug("workflow task started", "time", t) var err error // do not copy @@ -361,7 +361,7 @@ func (wp *Workflow) StackTrace() string { } func (wp *Workflow) Close() { - wp.log.Debug("close workflow", zap.String("RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID)) + wp.log.Debug("close workflow", "RunID", wp.env.WorkflowInfo().WorkflowExecution.RunID) // when closing the workflow, we should drain(execute) unhandled updates if wp.env.DrainUnhandledUpdates() { wp.log.Info("drained unhandled updates") diff --git a/api/interfaces.go b/api/interfaces.go index c6dc3190..2a3ed3ad 100644 --- a/api/interfaces.go +++ b/api/interfaces.go @@ -2,6 +2,7 @@ package api import ( "context" + "log/slog" "time" "github.com/roadrunner-server/pool/v2/payload" @@ -10,7 +11,6 @@ import ( "github.com/roadrunner-server/pool/v2/worker" "github.com/temporalio/roadrunner-temporal/v6/internal" "go.temporal.io/sdk/interceptor" - "go.uber.org/zap" staticPool "github.com/roadrunner-server/pool/v2/pool/static_pool" ) @@ -64,6 +64,6 @@ type Configurer interface { // Server creates workers for the application. type Server interface { - NewPool(ctx context.Context, cfg *pool.Config, env map[string]string, _ *zap.Logger) (*staticPool.Pool, error) - NewPoolWithOptions(ctx context.Context, cfg *pool.Config, env map[string]string, _ *zap.Logger, options ...staticPool.Options) (*staticPool.Pool, error) + NewPool(ctx context.Context, cfg *pool.Config, env map[string]string, _ *slog.Logger) (*staticPool.Pool, error) + NewPoolWithOptions(ctx context.Context, cfg *pool.Config, env map[string]string, _ *slog.Logger, options ...staticPool.Options) (*staticPool.Pool, error) } diff --git a/go.work.sum b/go.work.sum index 24084c55..0ab6ced7 100644 --- a/go.work.sum +++ b/go.work.sum @@ -687,6 +687,7 @@ github.com/apache/thrift v0.16.0 h1:qEy6UW60iVOlUy+b9ZR0d5WzUWYGOo4HfopoyBaNmoY= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/apache/thrift v0.21.0 h1:tdPmh/ptjE1IJnhbhrcl2++TauVjy242rkV/UzJChnE= github.com/apache/thrift v0.21.0/go.mod h1:W1H8aR/QRtYNvrPeFXBtobyRkd0/YVhTc6i07XIAgDw= +github.com/apache/thrift v0.23.0/go.mod h1:zPt6WxgvTOM6hF92y8C+MkEM5LMxZuk4JcQOiU4Esvs= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -1681,6 +1682,7 @@ golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= +golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1791,6 +1793,7 @@ golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= +golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -1978,6 +1981,7 @@ golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= +golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -2085,6 +2089,7 @@ golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= +golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= diff --git a/internal.go b/internal.go index 3982613f..ac14aaf2 100644 --- a/internal.go +++ b/internal.go @@ -11,11 +11,10 @@ import ( "github.com/temporalio/roadrunner-temporal/v6/aggregatedpool" "github.com/temporalio/roadrunner-temporal/v6/dataconverter" "github.com/temporalio/roadrunner-temporal/v6/internal/codec/proto" - "github.com/temporalio/roadrunner-temporal/v6/internal/logger" tclient "go.temporal.io/sdk/client" "go.temporal.io/sdk/converter" + tlog "go.temporal.io/sdk/log" "go.temporal.io/sdk/worker" - "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/metadata" @@ -159,7 +158,7 @@ func (p *Plugin) initTemporalClient(phpSdkVersion string, flags map[string]strin if val, ok := flags[APIKey]; ok { if val != "" { - p.apiKey.Store(ptr(val)) + p.apiKey.Store(new(val)) } } @@ -176,7 +175,7 @@ func (p *Plugin) initTemporalClient(phpSdkVersion string, flags map[string]strin HostPort: p.config.Address, MetricsHandler: p.temporal.mh, Namespace: p.config.Namespace, - Logger: logger.NewZapAdapter(p.log), + Logger: tlog.NewStructuredLogger(p.log), DataConverter: dc, ConnectionOptions: tclient.ConnectionOptions{ TLS: p.temporal.tlsCfg, @@ -200,7 +199,7 @@ func (p *Plugin) initTemporalClient(phpSdkVersion string, flags map[string]strin return connectError(p.config.Address, err) } - p.log.Info("connected to temporal server", zap.String("address", p.config.Address)) + p.log.Info("connected to temporal server", "address", p.config.Address) return nil } diff --git a/internal/codec/proto/proto.go b/internal/codec/proto/proto.go index 8cf15a8e..223d537f 100644 --- a/internal/codec/proto/proto.go +++ b/internal/codec/proto/proto.go @@ -1,6 +1,7 @@ package proto import ( + "log/slog" "sync" "github.com/goccy/go-json" @@ -9,19 +10,18 @@ import ( "github.com/roadrunner-server/pool/v2/payload" "github.com/temporalio/roadrunner-temporal/v6/internal" "go.temporal.io/sdk/converter" - "go.uber.org/zap" "google.golang.org/protobuf/proto" ) // Codec uses protobuf to exchange messages with underlying workers. type Codec struct { - log *zap.Logger + log *slog.Logger dc converter.DataConverter frPool sync.Pool } // NewCodec creates new Proto communication Codec. -func NewCodec(log *zap.Logger, dc converter.DataConverter) *Codec { +func NewCodec(log *slog.Logger, dc converter.DataConverter) *Codec { return &Codec{ log: log, dc: dc, @@ -52,7 +52,7 @@ func (c *Codec) Encode(ctx *internal.Context, p *payload.Payload, msg ...*intern } request.Messages[i] = pm - c.log.Debug("outgoing message", zap.Uint64("id", pm.Id), zap.ByteString("data", p.Body), zap.ByteString("context", p.Context)) + c.log.Debug("outgoing message", "id", pm.Id, "data", p.Body, "context", p.Context) } // context is always in JSON format @@ -94,7 +94,7 @@ func (c *Codec) Decode(pld *payload.Payload, result *[]*internal.Message) error return errM } - c.log.Debug("received message", zap.Any("command", msg.Command), zap.Uint64("id", msg.ID), zap.ByteString("data", pld.Body)) + c.log.Debug("received message", "command", msg.Command, "id", msg.ID, "data", pld.Body) *result = append(*result, msg) } @@ -115,7 +115,7 @@ func (c *Codec) DecodeWorkerInfo(p *payload.Payload, wi *[]*internal.WorkerInfo) } if len(info) != 1 { - c.log.Error("received not valid workflow info", zap.Any("data", info)) + c.log.Error("received not valid workflow info", "data", info) return errors.E(op, errors.Str("unable to read worker info")) } diff --git a/metrics.go b/metrics.go index 33e7e186..b57ad12b 100644 --- a/metrics.go +++ b/metrics.go @@ -2,6 +2,7 @@ package rrtemporal import ( "io" + "log/slog" "strconv" "time" @@ -15,7 +16,6 @@ import ( tclient "go.temporal.io/sdk/client" ttally "go.temporal.io/sdk/contrib/tally" // temporal tally hanlders statsdreporter "go.temporal.io/server/common/metrics/tally/statsd" - "go.uber.org/zap" ) const ( @@ -46,12 +46,12 @@ func newStatsExporter(stats Informer) *StatsExporter { } } -func newPrometheusScope(c prometheus.Configuration, prefix string, log *zap.Logger) (tally.Scope, io.Closer, error) { +func newPrometheusScope(c prometheus.Configuration, prefix string, log *slog.Logger) (tally.Scope, io.Closer, error) { reporter, err := c.NewReporter( prometheus.ConfigurationOptions{ Registry: prom.NewRegistry(), OnError: func(err error) { - log.Error("prometheus registry", zap.Error(err)) + log.Error("prometheus registry", "error", err) }, }, ) @@ -123,7 +123,7 @@ func newStatsdScope(statsdConfig *Statsd) (tally.Scope, io.Closer, error) { } // init RR metrics -func initMetrics(cfg *Config, log *zap.Logger) (tclient.MetricsHandler, io.Closer, error) { +func initMetrics(cfg *Config, log *slog.Logger) (tclient.MetricsHandler, io.Closer, error) { switch cfg.Metrics.Driver { case driverPrometheus: ms, cl, err := newPrometheusScope(prometheus.Configuration{ diff --git a/plugin.go b/plugin.go index 303282b4..797a3ea7 100644 --- a/plugin.go +++ b/plugin.go @@ -25,7 +25,8 @@ import ( tclient "go.temporal.io/sdk/client" "go.temporal.io/sdk/converter" "go.temporal.io/sdk/worker" - "go.uber.org/zap" + + "log/slog" "github.com/roadrunner-server/pool/v2/pool/static_pool" ) @@ -50,7 +51,7 @@ const ( ) type Logger interface { - NamedLogger(name string) *zap.Logger + NamedLogger(name string) *slog.Logger } // temporal structure contains temporal specific structures @@ -73,7 +74,7 @@ type Plugin struct { mu sync.RWMutex server api.Server - log *zap.Logger + log *slog.Logger config *Config statsExporter *StatsExporter codec *proto.Codec @@ -167,7 +168,7 @@ func (p *Plugin) Init(cfg api.Configurer, log Logger, server api.Server) error { p.temporal.interceptors = make(map[string]api.Interceptor) p.temporal.dataConverters = make(map[string]converter.PayloadConverter) // Initialize with empty API key; populated from PHP SDK flags during pool init. - p.apiKey.Store(ptr("")) + p.apiKey.Store(new("")) return nil } @@ -209,7 +210,7 @@ func (p *Plugin) Serve() chan error { switch strings.Contains(ev.Message(), strconv.Itoa(p.wwPID)) { // stopped workflow worker -> full reset case true: - p.log.Debug("workflow worker stopped, resetting", zap.String("message", ev.Message())) + p.log.Debug("workflow worker stopped, resetting", "message", ev.Message()) errR := p.Reset() if errR != nil { errCh <- errors.E(op, errors.Errorf("error during reset: %#v, event: %s", errR, ev.Message())) @@ -217,7 +218,7 @@ func (p *Plugin) Serve() chan error { } // stopped one of the activity workers -> already replaced by the pool, nothing to do case false: - p.log.Debug("activity worker stopped, replaced by the pool", zap.String("message", ev.Message())) + p.log.Debug("activity worker stopped, replaced by the pool", "message", ev.Message()) } case <-p.stopCh: @@ -260,7 +261,7 @@ func (p *Plugin) Stop(ctx context.Context) error { // might be nil if the user didn't set the metrics if p.temporal.tallyCloser != nil { if err := p.temporal.tallyCloser.Close(); err != nil { - p.log.Error("failed to close tally metrics", zap.Error(err)) + p.log.Error("failed to close tally metrics", "error", err) } } @@ -293,7 +294,7 @@ func (p *Plugin) Workers() []*process.State { st, err := process.WorkerProcessState(wfPw[i]) if err != nil { // log the error and continue - p.log.Error("worker process state error", zap.Error(err)) + p.log.Error("worker process state error", "error", err) continue } @@ -304,7 +305,7 @@ func (p *Plugin) Workers() []*process.State { st, err := process.WorkerProcessState(actPw[i]) if err != nil { // log the error and continue - p.log.Error("worker process state error", zap.Error(err)) + p.log.Error("worker process state error", "error", err) continue } @@ -396,7 +397,7 @@ func (p *Plugin) Collects() []*dep.In { p.mu.Lock() if _, exists := p.temporal.interceptors[mdw.Name()]; exists { p.log.Warn("interceptor with this name is already registered, overwriting", - zap.String("name", mdw.Name()), + "name", mdw.Name(), ) } p.temporal.interceptors[mdw.Name()] = mdw @@ -407,7 +408,7 @@ func (p *Plugin) Collects() []*dep.In { p.mu.Lock() if _, exists := p.temporal.dataConverters[pc.Encoding()]; exists { p.log.Warn("data converter with this encoding is already registered, overwriting", - zap.String("encoding", pc.Encoding()), + "encoding", pc.Encoding(), ) } p.temporal.dataConverters[pc.Encoding()] = pc @@ -425,7 +426,3 @@ func (p *Plugin) Name() string { func (p *Plugin) RPC() (string, http.Handler) { return temporalV1connect.NewTemporalServiceHandler(&rpc{plugin: p}) } - -func ptr[T any](v T) *T { - return &v -} diff --git a/rpc.go b/rpc.go index a8f9ffe3..a2cf01c2 100644 --- a/rpc.go +++ b/rpc.go @@ -11,14 +11,13 @@ import ( protoApi "github.com/roadrunner-server/api-go/v6/temporal/v1" "github.com/roadrunner-server/api-go/v6/temporal/v1/temporalV1connect" "github.com/roadrunner-server/errors" - "github.com/temporalio/roadrunner-temporal/v6/internal/logger" commonpb "go.temporal.io/api/common/v1" "go.temporal.io/api/enums/v1" "go.temporal.io/api/history/v1" "go.temporal.io/sdk/activity" + tlog "go.temporal.io/sdk/log" "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" - "go.uber.org/zap" "google.golang.org/grpc/codes" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" @@ -114,15 +113,15 @@ func (r *rpc) ReplayWorkflow(_ context.Context, req *connect.Request[protoApi.Re out := &protoApi.ReplayResponse{} r.plugin.log.Debug("replay workflow request", - zap.String("run_id", in.GetWorkflowExecution().GetRunId()), - zap.String("workflow_id", in.GetWorkflowExecution().GetWorkflowId()), - zap.String("workflow_name", in.GetWorkflowType().GetName())) + "run_id", in.GetWorkflowExecution().GetRunId(), + "workflow_id", in.GetWorkflowExecution().GetWorkflowId(), + "workflow_name", in.GetWorkflowType().GetName()) if in.GetWorkflowExecution() == nil || in.GetWorkflowType() == nil || in.GetWorkflowExecution().GetRunId() == "" || in.GetWorkflowExecution().GetWorkflowId() == "" || in.GetWorkflowType().GetName() == "" { out.Status = newStatus(codes.InvalidArgument, "run_id, workflow_id or workflow_name should not be empty") - r.plugin.log.Error("replay workflow request", zap.String("error", "run_id, workflow_id or workflow_name should not be empty")) + r.plugin.log.Error("replay workflow request", "error", "run_id, workflow_id or workflow_name should not be empty") return connect.NewResponse(out), nil } @@ -136,7 +135,7 @@ func (r *rpc) ReplayWorkflow(_ context.Context, req *connect.Request[protoApi.Re if err != nil { out.Status = newStatus(codes.Internal, err.Error()) - r.plugin.log.Error("history iteration error", zap.Error(err)) + r.plugin.log.Error("history iteration error", "error", err) return connect.NewResponse(out), nil } hist.Events = append(hist.Events, event) @@ -154,11 +153,11 @@ func (r *rpc) ReplayWorkflow(_ context.Context, req *connect.Request[protoApi.Re DisableAlreadyRegisteredCheck: false, }) - err := replayer.ReplayWorkflowHistory(logger.NewZapAdapter(r.plugin.log), &hist) + err := replayer.ReplayWorkflowHistory(tlog.NewStructuredLogger(r.plugin.log), &hist) if err != nil { out.Status = newStatus(codes.FailedPrecondition, err.Error()) - r.plugin.log.Error("replay error", zap.Error(err)) + r.plugin.log.Error("replay error", "error", err) return connect.NewResponse(out), nil } @@ -174,15 +173,15 @@ func (r *rpc) DownloadWorkflowHistory(_ context.Context, req *connect.Request[pr out := &protoApi.ReplayResponse{} r.plugin.log.Debug("replay workflow request", - zap.String("run_id", in.GetWorkflowExecution().GetRunId()), - zap.String("workflow_id", in.GetWorkflowExecution().GetWorkflowId()), - zap.String("save_path", in.GetSavePath())) + "run_id", in.GetWorkflowExecution().GetRunId(), + "workflow_id", in.GetWorkflowExecution().GetWorkflowId(), + "save_path", in.GetSavePath()) if in.GetWorkflowExecution() == nil || in.GetWorkflowType() == nil || in.GetSavePath() == "" || in.GetWorkflowExecution().GetRunId() == "" || in.GetWorkflowExecution().GetWorkflowId() == "" || in.GetWorkflowType().GetName() == "" { out.Status = newStatus(codes.InvalidArgument, "run_id, workflow_id or save_path should not be empty") - r.plugin.log.Error("replay workflow request", zap.String("error", "run_id, workflow_id or save_path should not be empty")) + r.plugin.log.Error("replay workflow request", "error", "run_id, workflow_id or save_path should not be empty") return connect.NewResponse(out), nil } @@ -190,14 +189,14 @@ func (r *rpc) DownloadWorkflowHistory(_ context.Context, req *connect.Request[pr if err != nil { out.Status = newStatus(codes.Internal, err.Error()) - r.plugin.log.Error("failed to create the file", zap.Error(err)) + r.plugin.log.Error("failed to create the file", "error", err) return connect.NewResponse(out), nil } defer func() { err = file.Close() if err != nil { - r.plugin.log.Error("failed to close the file", zap.Error(err)) + r.plugin.log.Error("failed to close the file", "error", err) } }() @@ -212,7 +211,7 @@ func (r *rpc) DownloadWorkflowHistory(_ context.Context, req *connect.Request[pr if errn != nil { out.Status = newStatus(codes.Internal, errn.Error()) - r.plugin.log.Error("history iteration error", zap.Error(errn)) + r.plugin.log.Error("history iteration error", "error", errn) return connect.NewResponse(out), nil } @@ -223,7 +222,7 @@ func (r *rpc) DownloadWorkflowHistory(_ context.Context, req *connect.Request[pr if err != nil { out.Status = newStatus(codes.Internal, err.Error()) - r.plugin.log.Error("history marshal error", zap.Error(err)) + r.plugin.log.Error("history marshal error", "error", err) return connect.NewResponse(out), nil } @@ -231,13 +230,13 @@ func (r *rpc) DownloadWorkflowHistory(_ context.Context, req *connect.Request[pr if err != nil { out.Status = newStatus(codes.Internal, err.Error()) - r.plugin.log.Error("history marshal error", zap.Error(err)) + r.plugin.log.Error("history marshal error", "error", err) return connect.NewResponse(out), nil } out.Status = newStatus(codes.OK, "") - r.plugin.log.Debug("history saved", zap.String("location", in.GetSavePath())) + r.plugin.log.Debug("history saved", "location", in.GetSavePath()) return connect.NewResponse(out), nil } @@ -247,22 +246,22 @@ func (r *rpc) ReplayFromJSON(_ context.Context, req *connect.Request[protoApi.Re out := &protoApi.ReplayResponse{} r.plugin.log.Debug("replay from JSON request", - zap.String("workflow_name", in.GetWorkflowType().GetName()), - zap.String("save_path", in.GetSavePath()), - zap.Int64("last_event_id", in.GetLastEventId()), + "workflow_name", in.GetWorkflowType().GetName(), + "save_path", in.GetSavePath(), + "last_event_id", in.GetLastEventId(), ) if in.GetWorkflowType() == nil || in.GetSavePath() == "" { out.Status = newStatus(codes.InvalidArgument, "workflow_name and save_path should not be empty") - r.plugin.log.Error("replay from JSON request", zap.String("error", "workflow_name and save_path should not be empty")) + r.plugin.log.Error("replay from JSON request", "error", "workflow_name and save_path should not be empty") return connect.NewResponse(out), nil } if in.GetWorkflowType().GetName() == "" { out.Status = newStatus(codes.InvalidArgument, "workflow_name should not be empty") - r.plugin.log.Error("replay from JSON request", zap.String("error", "workflow_name should not be empty")) + r.plugin.log.Error("replay from JSON request", "error", "workflow_name should not be empty") return connect.NewResponse(out), nil } @@ -281,20 +280,20 @@ func (r *rpc) ReplayFromJSON(_ context.Context, req *connect.Request[protoApi.Re switch in.GetLastEventId() { // we don't have last event ID case 0: - err := replayer.ReplayWorkflowHistoryFromJSONFile(logger.NewZapAdapter(r.plugin.log), in.GetSavePath()) + err := replayer.ReplayWorkflowHistoryFromJSONFile(tlog.NewStructuredLogger(r.plugin.log), in.GetSavePath()) if err != nil { out.Status = newStatus(codes.FailedPrecondition, err.Error()) - r.plugin.log.Error("replay from JSON request", zap.Error(err)) + r.plugin.log.Error("replay from JSON request", "error", err) return connect.NewResponse(out), nil } default: // we have last event ID - err := replayer.ReplayPartialWorkflowHistoryFromJSONFile(logger.NewZapAdapter(r.plugin.log), in.GetSavePath(), in.GetLastEventId()) + err := replayer.ReplayPartialWorkflowHistoryFromJSONFile(tlog.NewStructuredLogger(r.plugin.log), in.GetSavePath(), in.GetLastEventId()) if err != nil { out.Status = newStatus(codes.FailedPrecondition, err.Error()) - r.plugin.log.Error("replay from JSON request (partial workflow history)", zap.Int64("id", in.GetLastEventId()), zap.Error(err)) + r.plugin.log.Error("replay from JSON request (partial workflow history)", "id", in.GetLastEventId(), "error", err) return connect.NewResponse(out), nil } } @@ -311,7 +310,7 @@ func (r *rpc) ReplayWorkflowHistory(_ context.Context, req *connect.Request[prot out := &protoApi.ReplayResponse{} r.plugin.log.Debug("replay from workflow history request", - zap.String("workflow_name", in.GetWorkflowType().GetName()), + "workflow_name", in.GetWorkflowType().GetName(), ) if in.GetHistory() == nil || in.GetWorkflowType().GetName() == "" { @@ -333,11 +332,11 @@ func (r *rpc) ReplayWorkflowHistory(_ context.Context, req *connect.Request[prot DisableAlreadyRegisteredCheck: false, }) - err := replayer.ReplayWorkflowHistory(logger.NewZapAdapter(r.plugin.log), in.GetHistory()) + err := replayer.ReplayWorkflowHistory(tlog.NewStructuredLogger(r.plugin.log), in.GetHistory()) if err != nil { out.Status = newStatus(codes.FailedPrecondition, err.Error()) - r.plugin.log.Error("replay workflow history", zap.Error(err)) + r.plugin.log.Error("replay workflow history", "error", err) return connect.NewResponse(out), nil } From 10c75351aa38b5b768cbbcc929d5100f8de2eb1b Mon Sep 17 00:00:00 2001 From: Valery Piashchynski Date: Fri, 12 Jun 2026 14:25:19 +0200 Subject: [PATCH 11/11] test: fail gracefully when the php worker delivered no heartbeat --- tests/general/hp_test.go | 3 +++ tests/tls/hp_tls_test.go | 3 +++ 2 files changed, 6 insertions(+) diff --git a/tests/general/hp_test.go b/tests/general/hp_test.go index 0903e223..0f2ec4a5 100644 --- a/tests/general/hp_test.go +++ b/tests/general/hp_test.go @@ -544,6 +544,9 @@ func Test_ActivityHeartbeatProto(t *testing.T) { require.Len(t, we.PendingActivities, 1) act := we.PendingActivities[0] + // heartbeats are delivered by the PHP worker through the RR control-plane + // RPC; fail instead of panicking when none arrived + require.NotNil(t, act.HeartbeatDetails) require.Len(t, act.HeartbeatDetails.Payloads, 1) assert.Equal(t, `{"value":2}`, string(act.HeartbeatDetails.Payloads[0].Data)) diff --git a/tests/tls/hp_tls_test.go b/tests/tls/hp_tls_test.go index 7d590637..00b0deef 100644 --- a/tests/tls/hp_tls_test.go +++ b/tests/tls/hp_tls_test.go @@ -542,6 +542,9 @@ func Test_ActivityHeartbeatProto(t *testing.T) { require.Len(t, we.PendingActivities, 1) act := we.PendingActivities[0] + // heartbeats are delivered by the PHP worker through the RR control-plane + // RPC; fail instead of panicking when none arrived + require.NotNil(t, act.HeartbeatDetails) require.Len(t, act.HeartbeatDetails.Payloads, 1) assert.Equal(t, `{"value":2}`, string(act.HeartbeatDetails.Payloads[0].Data))