Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit359baae

Browse files
committed
feat: use v2 API for agent metadata updates
1 parentc17735d commit359baae

File tree

5 files changed

+130
-56
lines changed

5 files changed

+130
-56
lines changed

‎agent/agent.go‎

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ type Options struct {
9090

9191
typeClientinterface {
9292
ConnectRPC(ctx context.Context) (drpc.Conn,error)
93-
PostMetadata(ctx context.Context,req agentsdk.PostMetadataRequest)error
9493
RewriteDERPMap(derpMap*tailcfg.DERPMap)
9594
}
9695

@@ -298,7 +297,6 @@ func (a *agent) init() {
298297
// may be happening, but regardless after the intermittent
299298
// failure, you'll want the agent to reconnect.
300299
func (a*agent)runLoop() {
301-
goa.reportMetadataUntilGracefulShutdown()
302300
goa.manageProcessPriorityUntilGracefulShutdown()
303301

304302
// need to keep retrying up to the hardCtx so that we can send graceful shutdown-related
@@ -405,9 +403,8 @@ func (t *trySingleflight) Do(key string, fn func()) {
405403
fn()
406404
}
407405

408-
func (a*agent)reportMetadataUntilGracefulShutdown() {
406+
func (a*agent)reportMetadata(ctx context.Context,conn drpc.Conn)error {
409407
// metadata reporting can cease as soon as we start gracefully shutting down.
410-
ctx:=a.gracefulCtx
411408
tickerDone:=make(chanstruct{})
412409
collectDone:=make(chanstruct{})
413410
ctx,cancel:=context.WithCancel(ctx)
@@ -567,51 +564,58 @@ func (a *agent) reportMetadataUntilGracefulShutdown() {
567564
var (
568565
updatedMetadata=make(map[string]*codersdk.WorkspaceAgentMetadataResult)
569566
reportTimeout=30*time.Second
570-
reportSemaphore=make(chanstruct{},1)
567+
reportError=make(chanerror,1)
568+
reportInFlight=false
569+
aAPI=proto.NewDRPCAgentClient(conn)
571570
)
572-
reportSemaphore<-struct{}{}
573571

574572
for {
575573
select {
576574
case<-ctx.Done():
577-
return
575+
returnctx.Err()
578576
casemr:=<-metadataResults:
579577
// This can overwrite unsent values, but that's fine because
580578
// we're only interested about up-to-date values.
581579
updatedMetadata[mr.key]=mr.result
582580
continue
581+
caseerr:=<-reportError:
582+
a.logger.Debug(ctx,"batch update metadata complete",slog.Error(err))
583+
iferr!=nil {
584+
returnxerrors.Errorf("failed to report metadata: %w",err)
585+
}
586+
reportInFlight=false
583587
case<-report:
584-
iflen(updatedMetadata)>0 {
585-
select {
586-
case<-reportSemaphore:
587-
default:
588-
// If there's already a report in flight, don't send
589-
// another one, wait for next tick instead.
590-
continue
591-
}
592-
593-
metadata:=make([]agentsdk.Metadata,0,len(updatedMetadata))
594-
forkey,result:=rangeupdatedMetadata {
595-
metadata=append(metadata, agentsdk.Metadata{
596-
Key:key,
597-
WorkspaceAgentMetadataResult:*result,
598-
})
599-
delete(updatedMetadata,key)
600-
}
588+
ifreportInFlight {
589+
// If there's already a report in flight, don't send
590+
// another one, wait for next tick instead.
591+
a.logger.Debug(ctx,"skipped metadata report tick because report in flight")
592+
continue
593+
}
594+
iflen(updatedMetadata)==0 {
595+
continue
596+
}
597+
metadata:=make([]*proto.Metadata,0,len(updatedMetadata))
598+
forkey,result:=rangeupdatedMetadata {
599+
pr:=agentsdk.ProtoFromMetadataResult(*result)
600+
metadata=append(metadata,&proto.Metadata{
601+
Key:key,
602+
Result:pr,
603+
})
604+
delete(updatedMetadata,key)
605+
}
601606

602-
gofunc() {
603-
ctx,cancel:=context.WithTimeout(ctx,reportTimeout)
604-
deferfunc() {
605-
cancel()
606-
reportSemaphore<-struct{}{}
607-
}()
607+
reportInFlight=true
608+
gofunc() {
609+
a.logger.Debug(ctx,"batch updating metadata")
610+
ctx,cancel:=context.WithTimeout(ctx,reportTimeout)
611+
defercancel()
608612

609-
err:=a.client.PostMetadata(ctx,agentsdk.PostMetadataRequest{Metadata:metadata})
610-
iferr!=nil {
611-
a.logger.Error(ctx,"agent failed to report metadata",slog.Error(err))
612-
}
613-
}()
614-
}
613+
_,err:=aAPI.BatchUpdateMetadata(ctx,&proto.BatchUpdateMetadataRequest{Metadata:metadata})
614+
iferr!=nil {
615+
a.logger.Error(ctx,"agent failed to report metadata",slog.Error(err))
616+
}
617+
reportError<-err
618+
}()
615619
}
616620
}
617621
}
@@ -783,6 +787,8 @@ func (a *agent) run() (retErr error) {
783787
// lifecycle reporting has to be via gracefulShutdownBehaviorRemain
784788
connMan.start("report lifecycle",gracefulShutdownBehaviorRemain,a.reportLifecycle)
785789

790+
connMan.start("report metadata",gracefulShutdownBehaviorStop,a.reportMetadata)
791+
786792
// channels to sync goroutines below
787793
// handle manifest
788794
// |

‎agent/agenttest/client.go‎

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ type Client struct {
8282
t testing.TB
8383
logger slog.Logger
8484
agentID uuid.UUID
85-
metadatamap[string]agentsdk.Metadata
8685
coordinator tailnet.Coordinator
8786
server*drpcserver.Server
8887
fakeAgentAPI*FakeAgentAPI
@@ -131,22 +130,7 @@ func (c *Client) GetStartup() <-chan *agentproto.Startup {
131130
}
132131

133132
func (c*Client)GetMetadata()map[string]agentsdk.Metadata {
134-
c.mu.Lock()
135-
deferc.mu.Unlock()
136-
returnmaps.Clone(c.metadata)
137-
}
138-
139-
func (c*Client)PostMetadata(ctx context.Context,req agentsdk.PostMetadataRequest)error {
140-
c.mu.Lock()
141-
deferc.mu.Unlock()
142-
ifc.metadata==nil {
143-
c.metadata=make(map[string]agentsdk.Metadata)
144-
}
145-
for_,md:=rangereq.Metadata {
146-
c.metadata[md.Key]=md
147-
c.logger.Debug(ctx,"post metadata",slog.F("key",md.Key),slog.F("md",md))
148-
}
149-
returnnil
133+
returnc.fakeAgentAPI.GetMetadata()
150134
}
151135

152136
func (c*Client)GetStartupLogs() []agentsdk.Log {
@@ -186,6 +170,7 @@ type FakeAgentAPI struct {
186170
appHealthChchan*agentproto.BatchUpdateAppHealthRequest
187171
logsChchan<-*agentproto.BatchCreateLogsRequest
188172
lifecycleStates []codersdk.WorkspaceAgentLifecycle
173+
metadatamap[string]agentsdk.Metadata
189174

190175
getServiceBannerFuncfunc() (codersdk.ServiceBannerConfig,error)
191176
}
@@ -254,9 +239,24 @@ func (f *FakeAgentAPI) UpdateStartup(_ context.Context, req *agentproto.UpdateSt
254239
returnreq.GetStartup(),nil
255240
}
256241

257-
func (*FakeAgentAPI)BatchUpdateMetadata(context.Context,*agentproto.BatchUpdateMetadataRequest) (*agentproto.BatchUpdateMetadataResponse,error) {
258-
// TODO implement me
259-
panic("implement me")
242+
func (f*FakeAgentAPI)GetMetadata()map[string]agentsdk.Metadata {
243+
f.Lock()
244+
deferf.Unlock()
245+
returnmaps.Clone(f.metadata)
246+
}
247+
248+
func (f*FakeAgentAPI)BatchUpdateMetadata(ctx context.Context,req*agentproto.BatchUpdateMetadataRequest) (*agentproto.BatchUpdateMetadataResponse,error) {
249+
f.Lock()
250+
deferf.Unlock()
251+
iff.metadata==nil {
252+
f.metadata=make(map[string]agentsdk.Metadata)
253+
}
254+
for_,md:=rangereq.Metadata {
255+
smd:=agentsdk.MetadataFromProto(md)
256+
f.metadata[md.Key]=smd
257+
f.logger.Debug(ctx,"post metadata",slog.F("key",md.Key),slog.F("md",md))
258+
}
259+
return&agentproto.BatchUpdateMetadataResponse{},nil
260260
}
261261

262262
func (f*FakeAgentAPI)SetLogsChannel(chchan<-*agentproto.BatchCreateLogsRequest) {

‎codersdk/agentsdk/agentsdk.go‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ type PostMetadataRequest struct {
8585
// performance.
8686
typePostMetadataRequestDeprecated= codersdk.WorkspaceAgentMetadataResult
8787

88+
// PostMetadata posts agent metadata to the Coder server.
89+
//
90+
// Deprecated: use BatchUpdateMetadata on the agent dRPC API instead
8891
func (c*Client)PostMetadata(ctx context.Context,reqPostMetadataRequest)error {
8992
res,err:=c.SDK.Request(ctx,http.MethodPost,"/api/v2/workspaceagents/me/metadata",req)
9093
iferr!=nil {

‎codersdk/agentsdk/convert.go‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,31 @@ func ProtoFromMetadataDescription(d codersdk.WorkspaceAgentMetadataDescription)
112112
}
113113
}
114114

115+
funcProtoFromMetadataResult(r codersdk.WorkspaceAgentMetadataResult)*proto.WorkspaceAgentMetadata_Result {
116+
return&proto.WorkspaceAgentMetadata_Result{
117+
CollectedAt:timestamppb.New(r.CollectedAt),
118+
Age:r.Age,
119+
Value:r.Value,
120+
Error:r.Error,
121+
}
122+
}
123+
124+
funcMetadataResultFromProto(r*proto.WorkspaceAgentMetadata_Result) codersdk.WorkspaceAgentMetadataResult {
125+
return codersdk.WorkspaceAgentMetadataResult{
126+
CollectedAt:r.GetCollectedAt().AsTime(),
127+
Age:r.GetAge(),
128+
Value:r.GetValue(),
129+
Error:r.GetError(),
130+
}
131+
}
132+
133+
funcMetadataFromProto(m*proto.Metadata)Metadata {
134+
returnMetadata{
135+
Key:m.GetKey(),
136+
WorkspaceAgentMetadataResult:MetadataResultFromProto(m.GetResult()),
137+
}
138+
}
139+
115140
funcAgentScriptsFromProto(protoScripts []*proto.WorkspaceAgentScript) ([]codersdk.WorkspaceAgentScript,error) {
116141
ret:=make([]codersdk.WorkspaceAgentScript,len(protoScripts))
117142
fori,protoScript:=rangeprotoScripts {

‎codersdk/agentsdk/convert_test.go‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/google/uuid"
88
"github.com/stretchr/testify/require"
9+
"google.golang.org/protobuf/types/known/timestamppb"
910
"tailscale.com/tailcfg"
1011

1112
"github.com/coder/coder/v2/agent/proto"
@@ -176,3 +177,42 @@ func TestProtoFromLifecycle(t *testing.T) {
176177
require.Equal(t,s,state)
177178
}
178179
}
180+
181+
funcTestProtoFromMetadataResult(t*testing.T) {
182+
t.Parallel()
183+
now:=dbtime.Now()
184+
result:= codersdk.WorkspaceAgentMetadataResult{
185+
CollectedAt:now,
186+
Age:4,
187+
Value:"lemons",
188+
Error:"rats",
189+
}
190+
pr:=agentsdk.ProtoFromMetadataResult(result)
191+
require.NotNil(t,pr)
192+
require.Equal(t,now,pr.CollectedAt.AsTime())
193+
require.EqualValues(t,4,pr.Age)
194+
require.Equal(t,"lemons",pr.Value)
195+
require.Equal(t,"rats",pr.Error)
196+
result2:=agentsdk.MetadataResultFromProto(pr)
197+
require.Equal(t,result,result2)
198+
}
199+
200+
funcTestMetadataFromProto(t*testing.T) {
201+
t.Parallel()
202+
now:=dbtime.Now()
203+
pmd:=&proto.Metadata{
204+
Key:"a flat",
205+
Result:&proto.WorkspaceAgentMetadata_Result{
206+
CollectedAt:timestamppb.New(now),
207+
Age:88,
208+
Value:"lemons",
209+
Error:"rats",
210+
},
211+
}
212+
smd:=agentsdk.MetadataFromProto(pmd)
213+
require.Equal(t,"a flat",smd.Key)
214+
require.Equal(t,now,smd.CollectedAt)
215+
require.EqualValues(t,88,smd.Age)
216+
require.Equal(t,"lemons",smd.Value)
217+
require.Equal(t,"rats",smd.Error)
218+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp