Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions internal/dflog/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ func WithHostnameAndIP(hostname, ip string) *SugaredLoggerOnWith {
}
}

func WithSeedPeer(hostID, hostname, ip string, port int) *SugaredLoggerOnWith {
return &SugaredLoggerOnWith{
withArgs: []any{"seedPeerHostID", hostID, "seedPeerHostname", hostname, "seedPeerIP", ip, "seedPeerPort", port},
}
}

func WithGroupUUID(groupUUID string) *SugaredLoggerOnWith {
return &SugaredLoggerOnWith{
withArgs: []any{"groupUUID", groupUUID},
Expand Down
22 changes: 22 additions & 0 deletions pkg/rpc/dfdaemon/client/client_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import (
grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"golang.org/x/sync/singleflight"
"google.golang.org/grpc"
"google.golang.org/grpc/connectivity"
Expand Down Expand Up @@ -212,11 +214,25 @@ type v2 struct {
*pkgbalancer.ConsistentHashingPickerBuilder
}

// setPeerTargetAttributes sets OpenTelemetry span attributes for the target peer address.
func (v *v2) setPeerTargetAttributes(ctx context.Context) {
span := trace.SpanFromContext(ctx)
if !span.IsRecording() {
return
}

span.SetAttributes(
attribute.String("d7y.dfdaemon.target", v.Target()),
)
}

// SyncPieces syncs pieces from the other peers.
func (v *v2) SyncPieces(ctx context.Context, req *dfdaemonv2.SyncPiecesRequest, opts ...grpc.CallOption) (dfdaemonv2.DfdaemonUpload_SyncPiecesClient, error) {
ctx, cancel := context.WithTimeout(ctx, contextTimeout)
defer cancel()

v.setPeerTargetAttributes(ctx)

return v.DfdaemonUploadClient.SyncPieces(
context.WithValue(ctx, pkgbalancer.ContextKey, req.TaskId),
req,
Expand All @@ -226,6 +242,8 @@ func (v *v2) SyncPieces(ctx context.Context, req *dfdaemonv2.SyncPiecesRequest,

// DownloadTask downloads task from p2p network.
func (v *v2) DownloadTask(ctx context.Context, taskID string, req *dfdaemonv2.DownloadTaskRequest, opts ...grpc.CallOption) (dfdaemonv2.DfdaemonUpload_DownloadTaskClient, error) {
v.setPeerTargetAttributes(ctx)

return v.DfdaemonUploadClient.DownloadTask(
context.WithValue(ctx, pkgbalancer.ContextKey, taskID),
req,
Expand Down Expand Up @@ -260,6 +278,8 @@ func (v *v2) DeleteTask(ctx context.Context, req *dfdaemonv2.DeleteTaskRequest,

// DownloadPersistentTask downloads persistent task from p2p network.
func (v *v2) DownloadPersistentTask(ctx context.Context, req *dfdaemonv2.DownloadPersistentTaskRequest, opts ...grpc.CallOption) (dfdaemonv2.DfdaemonUpload_DownloadPersistentTaskClient, error) {
v.setPeerTargetAttributes(ctx)

return v.DfdaemonUploadClient.DownloadPersistentTask(ctx, req, opts...)
}

Expand Down Expand Up @@ -291,6 +311,8 @@ func (v *v2) DeletePersistentTask(ctx context.Context, req *dfdaemonv2.DeletePer

// DownloadPersistentCacheTask downloads persistent cache task from p2p network.
func (v *v2) DownloadPersistentCacheTask(ctx context.Context, req *dfdaemonv2.DownloadPersistentCacheTaskRequest, opts ...grpc.CallOption) (dfdaemonv2.DfdaemonUpload_DownloadPersistentCacheTaskClient, error) {
v.setPeerTargetAttributes(ctx)

return v.DfdaemonUploadClient.DownloadPersistentCacheTask(ctx, req, opts...)
}

Expand Down
8 changes: 8 additions & 0 deletions pkg/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,20 @@ import (
"os"
"strings"

"go.opentelemetry.io/otel/attribute"
"gopkg.in/yaml.v3"

commonv1 "d7y.io/api/v2/pkg/apis/common/v1"
commonv2 "d7y.io/api/v2/pkg/apis/common/v2"
)

const (
AttributeSeedPeerHostID = attribute.Key("d7y.scheduler.seed_peer.host_id")
AttributeSeedPeerHostname = attribute.Key("d7y.scheduler.seed_peer.hostname")
AttributeSeedPeerIP = attribute.Key("d7y.scheduler.seed_peer.ip")
AttributeSeedPeerPort = attribute.Key("d7y.scheduler.seed_peer.port")
)

// PEMContent supports load PEM format from file or just inline PEM format content
type PEMContent string

Expand Down
35 changes: 32 additions & 3 deletions scheduler/resource/standard/seed_peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"sync"
"time"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"google.golang.org/grpc"
"stathat.com/c/consistent"
Expand Down Expand Up @@ -129,7 +130,16 @@ func (s *seedPeer) TriggerDownloadTask(ctx context.Context, taskID string, req *
}

addr := net.JoinHostPort(selected.IP, strconv.Itoa(int(selected.Port)))
logger.Infof("selected seed peer %s for task %s", addr, taskID)
if span := trace.SpanFromContext(ctx); span.IsRecording() {
span.SetAttributes(
attribute.String("d7y.scheduler.seed_peer.host_id", selected.ID),
attribute.String("d7y.scheduler.seed_peer.hostname", selected.Hostname),
attribute.String("d7y.scheduler.seed_peer.ip", selected.IP),
attribute.Int("d7y.scheduler.seed_peer.port", int(selected.Port)),
)
}
logger.WithSeedPeer(selected.ID, selected.Hostname, selected.IP, int(selected.Port)).
Infof("selected seed peer %s for task %s", addr, taskID)

client, err := s.clientPool.Get(addr, s.dialOptions...)
if err != nil {
Expand Down Expand Up @@ -179,7 +189,16 @@ func (s *seedPeer) TriggerTask(ctx context.Context, rg *http.Range, task *Task)
}

addr := net.JoinHostPort(selected.IP, strconv.Itoa(int(selected.Port)))
logger.Infof("selected seed peer %s for task %s", addr, task.ID)
if span := trace.SpanFromContext(ctx); span.IsRecording() {
span.SetAttributes(
attribute.String("d7y.scheduler.seed_peer.host_id", selected.ID),
attribute.String("d7y.scheduler.seed_peer.hostname", selected.Hostname),
attribute.String("d7y.scheduler.seed_peer.ip", selected.IP),
attribute.Int("d7y.scheduler.seed_peer.port", int(selected.Port)),
)
}
logger.WithSeedPeer(selected.ID, selected.Hostname, selected.IP, int(selected.Port)).
Infof("selected seed peer %s for task %s", addr, task.ID)

// TODO(chlins): reuse the client if we encounter the performance issue in future.
client, err := cndsystemclient.GetClientByAddr(ctx, dfnet.NetAddr{Type: dfnet.TCP, Addr: addr}, s.dialOptions...)
Expand Down Expand Up @@ -300,7 +319,17 @@ func (s *seedPeer) Select(ctx context.Context, taskID string) (*Host, error) {
return nil, fmt.Errorf("failed to load host: %s", addr)
}

return host.(*Host), nil
selected := host.(*Host)
if span := trace.SpanFromContext(ctx); span.IsRecording() {
span.SetAttributes(
attribute.String("d7y.scheduler.seed_peer.selected.host_id", selected.ID),
attribute.String("d7y.scheduler.seed_peer.selected.hostname", selected.Hostname),
attribute.String("d7y.scheduler.seed_peer.selected.ip", selected.IP),
attribute.Int("d7y.scheduler.seed_peer.selected.port", int(selected.Port)),
)
}

return selected, nil
}

// HasAvailable returns whether there is any available seed peer.
Expand Down
10 changes: 9 additions & 1 deletion scheduler/service/service_v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"time"

"github.com/go-http-utils/headers"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"google.golang.org/grpc/status"

Expand Down Expand Up @@ -731,6 +732,11 @@ func (v *V1) triggerTask(ctx context.Context, req *schedulerv1.PeerTaskRequest,
}
peer.Log.Infof("peer priority is %d", priority)

// Set priority as a span attribute for traceability.
if span := trace.SpanFromContext(ctx); span.IsRecording() {
span.SetAttributes(attribute.String("d7y.scheduler.seed_peer.priority", priority.String()))
}

switch priority {
case commonv1.Priority_LEVEL6, commonv1.Priority_LEVEL0:
if v.resource.SeedPeer().HasAvailable() && !task.IsSeedPeerFailed() {
Expand Down Expand Up @@ -768,7 +774,9 @@ func (v *V1) triggerTask(ctx context.Context, req *schedulerv1.PeerTaskRequest,

// triggerSeedPeerTask starts to trigger seed peer task.
func (v *V1) triggerSeedPeerTask(ctx context.Context, rg *http.Range, task *resource.Task) {
ctx, cancel := context.WithTimeout(trace.ContextWithSpan(context.Background(), trace.SpanFromContext(ctx)), v.config.SeedPeer.TaskDownloadTimeout)
// Use a detached context to preserve trace propagation while allowing
// the seed peer download to complete independently.
ctx, cancel := context.WithTimeout(context.WithoutCancel(ctx), v.config.SeedPeer.TaskDownloadTimeout)
defer cancel()

task.Log.Info("trigger seed peer")
Expand Down
31 changes: 22 additions & 9 deletions scheduler/service/service_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"time"

"github.com/bits-and-blooms/bitset"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -1901,19 +1903,30 @@ func (v *V2) downloadTaskBySeedPeer(ctx context.Context, taskID string, download
// refer to https://github.com/dragonflyoss/api/blob/main/pkg/apis/common/v2/common.proto#L74.
priority := peer.CalculatePriority(v.dynconfig)
peer.Log.Infof("peer priority is %s", priority.String())

// Set priority as a span attribute for traceability.
if span := trace.SpanFromContext(ctx); span.IsRecording() {
span.SetAttributes(attribute.String("d7y.scheduler.seed_peer.priority", priority.String()))
}

// Use a detached context that preserves trace propagation but is not cancelled
// when the parent context is cancelled, so the seed peer download can complete
// independently as a fire-and-forget operation.
traceCtx := context.WithoutCancel(ctx)

switch priority {
case commonv2.Priority_LEVEL6, commonv2.Priority_LEVEL0:
// Super peer is first triggered to download back-to-source.
if !peer.Task.IsSeedPeerFailed() {
go func(ctx context.Context, taskID string, download *commonv2.Download, hostType types.HostType) {
go func(traceCtx context.Context, taskID string, download *commonv2.Download, hostType types.HostType) {
peer.Log.Infof("%s seed peer triggers download task", hostType.Name())
if err := v.resource.SeedPeer().TriggerDownloadTask(context.Background(), taskID, &dfdaemonv2.DownloadTaskRequest{Download: download}); err != nil {
if err := v.resource.SeedPeer().TriggerDownloadTask(traceCtx, taskID, &dfdaemonv2.DownloadTaskRequest{Download: download}); err != nil {
peer.Log.Errorf("%s seed peer triggers download task failed %s", hostType.Name(), err.Error())
return
}

peer.Log.Infof("%s seed peer triggers download task success", hostType.Name())
}(ctx, taskID, download, types.HostTypeSuperSeed)
}(traceCtx, taskID, download, types.HostTypeSuperSeed)

break
}
Expand All @@ -1922,15 +1935,15 @@ func (v *V2) downloadTaskBySeedPeer(ctx context.Context, taskID string, download
case commonv2.Priority_LEVEL5:
// Super peer is first triggered to download back-to-source.
if !peer.Task.IsSeedPeerFailed() {
go func(ctx context.Context, taskID string, download *commonv2.Download, hostType types.HostType) {
go func(traceCtx context.Context, taskID string, download *commonv2.Download, hostType types.HostType) {
peer.Log.Infof("%s seed peer triggers download task", hostType.Name())
if err := v.resource.SeedPeer().TriggerDownloadTask(context.Background(), taskID, &dfdaemonv2.DownloadTaskRequest{Download: download}); err != nil {
if err := v.resource.SeedPeer().TriggerDownloadTask(traceCtx, taskID, &dfdaemonv2.DownloadTaskRequest{Download: download}); err != nil {
peer.Log.Errorf("%s seed peer triggers download task failed %s", hostType.Name(), err.Error())
return
}

peer.Log.Infof("%s seed peer triggers download task success", hostType.Name())
}(ctx, taskID, download, types.HostTypeSuperSeed)
}(traceCtx, taskID, download, types.HostTypeSuperSeed)

break
}
Expand All @@ -1939,15 +1952,15 @@ func (v *V2) downloadTaskBySeedPeer(ctx context.Context, taskID string, download
case commonv2.Priority_LEVEL4:
// Super peer is first triggered to download back-to-source.
if !peer.Task.IsSeedPeerFailed() {
go func(ctx context.Context, taskID string, download *commonv2.Download, hostType types.HostType) {
go func(traceCtx context.Context, taskID string, download *commonv2.Download, hostType types.HostType) {
peer.Log.Infof("%s seed peer triggers download task", hostType.Name())
if err := v.resource.SeedPeer().TriggerDownloadTask(context.Background(), taskID, &dfdaemonv2.DownloadTaskRequest{Download: download}); err != nil {
if err := v.resource.SeedPeer().TriggerDownloadTask(traceCtx, taskID, &dfdaemonv2.DownloadTaskRequest{Download: download}); err != nil {
peer.Log.Errorf("%s seed peer triggers download task failed %s", hostType.Name(), err.Error())
return
}

peer.Log.Infof("%s seed peer triggers download task success", hostType.Name())
}(ctx, taskID, download, types.HostTypeSuperSeed)
}(traceCtx, taskID, download, types.HostTypeSuperSeed)

break
}
Expand Down
Loading