MCPcopy Index your code
hub / github.com/coder/coder / SendLoop

Method SendLoop

codersdk/agentsdk/logs.go:362–459  ·  view source on GitHub ↗

SendLoop sends any pending logs until it hits an error or the context is canceled. It does not retry as it is expected that a higher layer retries establishing connection to the agent API and calls SendLoop again.

(ctx context.Context, dest LogDest)

Source from the content-addressed store, hash-verified

360// retry as it is expected that a higher layer retries establishing connection to the agent API and
361// calls SendLoop again.
362func (l *LogSender) SendLoop(ctx context.Context, dest LogDest) error {
363 l.L.Lock()
364 defer l.L.Unlock()
365 if l.exceededLogLimit {
366 l.logger.Debug(ctx, "aborting SendLoop because log limit is already exceeded")
367 return ErrLogLimitExceeded
368 }
369
370 ctxDone := false
371 defer l.logger.Debug(ctx, "log sender send loop exiting")
372
373 // wake 4 times per Flush interval to check if anything needs to be flushed
374 ctx, cancel := context.WithCancel(ctx)
375 defer cancel()
376 go func() {
377 tkr := time.NewTicker(flushInterval / 4)
378 defer tkr.Stop()
379 for {
380 select {
381 // also monitor the context here, so we notice immediately, rather
382 // than waiting for the next tick or logs
383 case <-ctx.Done():
384 l.L.Lock()
385 ctxDone = true
386 l.L.Unlock()
387 l.Broadcast()
388 return
389 case <-tkr.C:
390 l.Broadcast()
391 }
392 }
393 }()
394
395 for {
396 for !ctxDone && !l.hasPendingWorkLocked() {
397 l.Wait()
398 }
399 if ctxDone {
400 return ctx.Err()
401 }
402
403 src, q := l.getPendingWorkLocked()
404 logger := l.logger.With(slog.F("log_source_id", src))
405 q.flushRequested = false // clear flag since we're now flushing
406 req := &proto.BatchCreateLogsRequest{
407 LogSourceId: src[:],
408 }
409
410 // outputToSend keeps track of the size of the protobuf message we send, while
411 // outputToRemove keeps track of the size of the output we'll remove from the queues on
412 // success. They are different because outputToSend also counts protocol message overheads.
413 outputToSend := 0
414 outputToRemove := 0
415 n := 0
416 for n < len(q.logs) {
417 log := q.logs[n]
418 outputToSend += len(log.Output) + overheadPerLog
419 if outputToSend > maxBytesPerBatch {

Callers 8

TestLogSender_MainlineFunction · 0.95
TestLogSender_BatchFunction · 0.95
TestLogSender_SendErrorFunction · 0.95
runMethod · 0.80

Calls 10

hasPendingWorkLockedMethod · 0.95
getPendingWorkLockedMethod · 0.95
ErrMethod · 0.80
StopMethod · 0.65
WaitMethod · 0.65
BatchCreateLogsMethod · 0.65
LockMethod · 0.45
UnlockMethod · 0.45
DoneMethod · 0.45
ErrorfMethod · 0.45

Tested by 7

TestLogSender_MainlineFunction · 0.76
TestLogSender_BatchFunction · 0.76
TestLogSender_SendErrorFunction · 0.76