This repository has no description
streamplace docs go-conventions.md
4.0 kB
Markdown
at next

Streamplace Go conventions #

How we write Go in Streamplace. The linter may not catch these conventions, but we expect you to follow them in this repo.

Logging #

Log through stream.place/streamplace/pkg/log. Each call takes the context first, then the message, then alternating key-value pairs:

log.Log(ctx, "started ingest", "streamer", did, "rtmpPort", port)

Pick the level by what happened. The number is the glog -v level that a process needs to print the line. The default is -v=3. At the default, Error, Warn, and Log always print. Debug and Trace print only at a higher -v.

Call min -v Use it for
log.Error 1 An operation failed and could not complete.
log.Warn 2 Something was wrong, but the code recovered.
log.Log 3 General information. This is the info level.
log.Debug 4 Detail for debugging. Prints only at -v=4.
log.Trace 9 Detailed tracing. Prints only at -v=9.

There is no log.Info. log.Log is the info level.

Common mistakes:

  • The key-value arguments come in pairs. An odd number of arguments prints a warning at runtime and may corrupt the line. Always check the arguments after you edit a call.
  • Do not pass a caller key. The logger adds one for you.

A value such as a request id or a streamer did can apply to every log line from a context. To attach such a value, derive a new context with log.WithLogValues. You do not need to pass the value to every call:

ctx = log.WithLogValues(ctx, "streamer", did)

Error wrapping #

Wrap errors with %w, not %v, so callers can inspect the cause with errors.Is and errors.As:

return fmt.Errorf("failed to combine segments: %w", err)

%v converts the error to a string and breaks the error chain. A caller can no longer match the underlying error. Use %v only when you want to hide the cause.

HTTP handlers #

Write error responses with the helpers in stream.place/streamplace/pkg/errors. Do not call w.WriteHeader and encode JSON yourself, as the function will do it for you:

if err != nil {
    errors.WriteHTTPBadRequest(w, "Error parsing PUSH_REWRITE payload", err)
    return
}
Helper Status Notes
WriteHTTPBadRequest 400
WriteHTTPUnauthorized 401
WriteHTTPForbidden 403
WriteHTTPNotFound 404
WriteHTTPUnsupportedMediaType 415
WriteHTTPTooManyRequests 429 takes no err argument
WriteHTTPInternalServerError 500
WriteHTTPNotImplemented 501

Each helper returns an APIError{Msg, Status, Err}. Most handlers ignore it and return after they write the response. Use the return value only when the caller needs the status or the message.

Tests #

Assert with github.com/stretchr/testify/require, not assert. require fails the test immediately (t.FailNow) on the first broken precondition. A failed setup then stops at once, instead of causing nil-pointer panics in the assertions that follow:

require.NoError(t, err)
require.Equal(t, "sync", cmd.Name)

Media tests using withNoGSTLeaks must stop their pipelines and cancel their contexts before returning. The leak helper waits for finalizer passes before requesting the native snapshot; keep that barrier synchronous and never block the finalizer queue, which also releases Go-owned GStreamer references. Verify changes to the helper with race-enabled media tests without disabling leak assertions.