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
This repository was archived by the owner on Aug 30, 2024. It is now read-only.
/coder-v1-cliPublic archive

Commit4115a09

Browse files
committed
Usage metric pushing
1 parentc2eda4a commit4115a09

File tree

7 files changed

+149
-19
lines changed

7 files changed

+149
-19
lines changed

‎cmd/coder/shell.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"go.coder.com/cli"
1717
"go.coder.com/flog"
1818

19+
"cdr.dev/coder-cli/internal/activity"
1920
"cdr.dev/wsep"
2021
)
2122

@@ -145,7 +146,11 @@ func runCommand(ctx context.Context, envName string, command string, args []stri
145146
gofunc() {
146147
stdin:=process.Stdin()
147148
deferstdin.Close()
148-
_,err:=io.Copy(stdin,os.Stdin)
149+
150+
ap:=&activity.Pusher{Source:"ssh",EnvID:env.ID,Client:entClient}
151+
deferap.Start()()
152+
153+
_,err:=activity.Copy(ap,stdin,os.Stdin)
149154
iferr!=nil {
150155
cancel()
151156
}

‎cmd/coder/sync.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,11 @@ func (cmd *syncCmd) Run(fl *pflag.FlagSet) {
6969
}
7070

7171
s:= sync.Sync{
72-
Init:cmd.init,
73-
Environment:env,
74-
RemoteDir:remoteDir,
75-
LocalDir:absLocal,
76-
Client:entClient,
72+
Init:cmd.init,
73+
Env:env,
74+
RemoteDir:remoteDir,
75+
LocalDir:absLocal,
76+
Client:entClient,
7777
}
7878
forerr==nil||err==sync.ErrRestartSync {
7979
err=s.Run()

‎cmd/coder/url.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ import (
1111
"go.coder.com/flog"
1212
)
1313

14-
typeurlCmdstruct {
15-
}
14+
typeurlCmdstruct{}
1615

1716
typeDevURLstruct {
1817
Urlstring`json:"url"`

‎internal/activity/copy.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package activity
2+
3+
import"io"
4+
5+
// Copy copyes src to dst, pushing activity when bytes are read from src.
6+
funcCopy(p*Pusher,dst io.Writer,src io.Reader) (writtenint64,errerror) {
7+
buf:=make([]byte,32*1024)
8+
9+
for {
10+
nr,er:=src.Read(buf)
11+
ifnr>0 {
12+
p.Push()
13+
14+
nw,ew:=dst.Write(buf[0:nr])
15+
ifnw>0 {
16+
written+=int64(nw)
17+
}
18+
ifew!=nil {
19+
err=ew
20+
break
21+
}
22+
ifnr!=nw {
23+
err=io.ErrShortWrite
24+
break
25+
}
26+
}
27+
ifer!=nil {
28+
ifer!=io.EOF {
29+
err=er
30+
}
31+
break
32+
}
33+
}
34+
35+
returnwritten,err
36+
}

‎internal/activity/pusher.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package activity
2+
3+
import (
4+
"context"
5+
"sync/atomic"
6+
"time"
7+
8+
"cdr.dev/coder-cli/internal/entclient"
9+
"go.coder.com/flog"
10+
)
11+
12+
constpushInterval=time.Minute
13+
14+
// Pusher pushes activity metrics no more than once per pushInterval. Pushes
15+
// within the same interval are a no-op.
16+
typePusherstruct {
17+
Sourcestring
18+
EnvIDstring
19+
Client*entclient.Client
20+
21+
stateint64
22+
}
23+
24+
func (p*Pusher)Push() {
25+
ifatomic.CompareAndSwapInt64(&p.state,0,1) {
26+
err:=p.Client.PushActivity(p.Source,p.EnvID)
27+
iferr!=nil {
28+
flog.Error("failed to push activity: %s",err.Error())
29+
}
30+
}
31+
}
32+
33+
// Start starts the reset routine. It resets the state every pushInterval,
34+
// allowing Push to push a new activity.
35+
func (p*Pusher)Start() (endfunc()) {
36+
ctx,cancel:=context.WithCancel(context.Background())
37+
gofunc() {
38+
tick:=time.NewTicker(pushInterval)
39+
defertick.Stop()
40+
41+
for {
42+
select {
43+
case<-ctx.Done():
44+
return
45+
case<-tick.C:
46+
atomic.StoreInt64(&p.state,0)
47+
}
48+
49+
}
50+
}()
51+
52+
returnfunc() {
53+
cancel()
54+
}
55+
}

‎internal/entclient/activity.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package entclient
2+
3+
import"net/http"
4+
5+
func (cClient)PushActivity(sourcestring,envIDstring)error {
6+
res,err:=c.request("POST","/api/metrics/usage/push",map[string]string{
7+
"source":source,
8+
"environment_id":envID,
9+
})
10+
iferr!=nil {
11+
returnerr
12+
}
13+
14+
ifres.StatusCode!=http.StatusOK {
15+
returnbodyError(res)
16+
}
17+
18+
returnnil
19+
}

‎internal/sync/sync.go

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
"go.coder.com/flog"
2323

24+
"cdr.dev/coder-cli/internal/activity"
2425
"cdr.dev/coder-cli/internal/entclient"
2526
"cdr.dev/wsep"
2627
)
@@ -33,8 +34,11 @@ type Sync struct {
3334
LocalDirstring
3435
// RemoteDir is an absolute path.
3536
RemoteDirstring
36-
entclient.Environment
37-
*entclient.Client
37+
// DisableMetrics disables activity metric pushing.
38+
DisableMetricsbool
39+
40+
Env entclient.Environment
41+
Client*entclient.Client
3842
}
3943

4044
func (sSync)syncPaths(deletebool,local,remotestring)error {
@@ -43,7 +47,7 @@ func (s Sync) syncPaths(delete bool, local, remote string) error {
4347
args:= []string{"-zz",
4448
"-a",
4549
"--delete",
46-
"-e",self+" sh",local,s.Environment.Name+":"+remote,
50+
"-e",self+" sh",local,s.Env.Name+":"+remote,
4751
}
4852
ifdelete {
4953
args=append([]string{"--delete"},args...)
@@ -68,7 +72,7 @@ func (s Sync) syncPaths(delete bool, local, remote string) error {
6872
}
6973

7074
func (sSync)remoteRm(ctx context.Context,remotestring)error {
71-
conn,err:=s.Client.DialWsep(ctx,s.Environment)
75+
conn,err:=s.Client.DialWsep(ctx,s.Env)
7276
iferr!=nil {
7377
returnerr
7478
}
@@ -229,13 +233,16 @@ func (s Sync) workEventGroup(evs []timedEvent) {
229233
}
230234

231235
const (
232-
// maxinflightInotify sets the maximum number of inotifies before the sync just restarts.
233-
// Syncing a large amount of small files (e.g .git or node_modules) is impossible to do performantly
234-
// with individual rsyncs.
236+
// maxinflightInotify sets the maximum number of inotifies before the
237+
// sync just restarts. Syncing a large amount of small files (e.g .git
238+
// or node_modules) is impossible to do performantly with individual
239+
// rsyncs.
235240
maxInflightInotify=8
236241
maxEventDelay=time.Second*7
237-
// maxAcceptableDispatch is the maximum amount of time before an event should begin its journey to the server.
238-
// This sets a lower bound for perceivable latency, but the higher it is, the better the optimization.
242+
// maxAcceptableDispatch is the maximum amount of time before an event
243+
// should begin its journey to the server. This sets a lower bound for
244+
// perceivable latency, but the higher it is, the better the
245+
// optimization.
239246
maxAcceptableDispatch=time.Millisecond*50
240247
)
241248

@@ -245,13 +252,18 @@ const (
245252
func (sSync)Run()error {
246253
events:=make(chan notify.EventInfo,maxInflightInotify)
247254
// Set up a recursive watch.
248-
// We do this before the initial sync so we can capture any changes that may have happened during sync.
255+
// We do this before the initial sync so we can capture any changes
256+
// that may have happened during sync.
249257
err:=notify.Watch(path.Join(s.LocalDir,"..."),events,notify.All)
250258
iferr!=nil {
251259
returnxerrors.Errorf("create watch: %w",err)
252260
}
253261
defernotify.Stop(events)
254262

263+
ap:= activity.Pusher{Source:activityName,EnvID:s.Env.ID,Client:s.Client}
264+
deferap.Start()()
265+
ap.Push()
266+
255267
setConsoleTitle("⏳ syncing project")
256268
err=s.initSync()
257269
iferr!=nil {
@@ -265,7 +277,8 @@ func (s Sync) Run() error {
265277
flog.Info("watching %s for changes",s.LocalDir)
266278

267279
vardroppedEventsuint64
268-
// Timed events lets us track how long each individual file takes to update.
280+
// Timed events lets us track how long each individual file takes to
281+
// update.
269282
timedEvents:=make(chantimedEvent,cap(events))
270283
gofunc() {
271284
deferclose(timedEvents)
@@ -309,6 +322,9 @@ func (s Sync) Run() error {
309322
}
310323
s.workEventGroup(eventGroup)
311324
eventGroup=eventGroup[:0]
325+
ap.Push()
312326
}
313327
}
314328
}
329+
330+
constactivityName="sync"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp