From 0bf42cac77dafc36e15f740ac91429079ad70fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Og=C3=B3rek?= Date: Mon, 1 Jul 2019 14:56:20 +0200 Subject: [PATCH] docs: Go async delivery and goroutines hub (#1085) * docs: Create a note regarding default async events delivery in Go * docs: Create documentation for scopes usage inside Goroutines * Apply suggestions from code review Co-Authored-By: Anton Ovchinnikov --- __tests__/__snapshots__/documentation.js.snap | 1 + .../_documentation/platforms/go/goroutines.md | 53 +++++++++++++++++++ .../_documentation/platforms/go/index.md | 15 ++++++ .../platforms/go/integrations.md | 2 +- 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/collections/_documentation/platforms/go/goroutines.md diff --git a/__tests__/__snapshots__/documentation.js.snap b/__tests__/__snapshots__/documentation.js.snap index c4e0d683b52b1..3329333c5feee 100644 --- a/__tests__/__snapshots__/documentation.js.snap +++ b/__tests__/__snapshots__/documentation.js.snap @@ -276,6 +276,7 @@ Array [ "platforms/go/config/index.html", "platforms/go/echo/index.html", "platforms/go/gin/index.html", + "platforms/go/goroutines/index.html", "platforms/go/http/index.html", "platforms/go/index.html", "platforms/go/integrations/index.html", diff --git a/src/collections/_documentation/platforms/go/goroutines.md b/src/collections/_documentation/platforms/go/goroutines.md new file mode 100644 index 0000000000000..33c36dd6e08f2 --- /dev/null +++ b/src/collections/_documentation/platforms/go/goroutines.md @@ -0,0 +1,53 @@ +--- +title: Goroutines +sidebar_order: 4 +--- + +A goroutine is a lightweight thread managed by the Go runtime. Goroutines can run concurrently, and because of this, every goroutine has to keep track of its own Sentry-related data locally. Otherwise, there is a chance that you will override your data stored in the Scope. More on this in [Scopes and Hubs]({%- link _documentation/enriching-error-data/scopes.md -%}?platform={{ include.platform }}) section. + +The easiest way to handle this, is to create a new `Hub` for every goroutine you start, however this would require you to rebind the current `Client` and handle `Scope` yourself. That is why we provide a helper method called `Clone`. It takes care of creating a `Hub`, cloning existing `Scope` and reassigning it alongside `Client` to newly create instance. + +Once cloned, `Hub` is completly isolated and can be used safely inside concurrent call. However, instead of using globally exposed methods, they should be called directly on the `Hub`. + +Here are two examples: one that is non-deterministic, would leak information between threads, and could trigger a concurrent-write panic; and one that is totally safe, and should be used instead. + +```go +// Example of __INCORRECT__ use of scopes inside a Goroutines - DON'T USE IT! + +go func() { + sentry.ConfigureScope(func(scope *sentry.Scope) { + scope.SetTag("secretTag", "go#1") + }) + sentry.CaptureMessage("Hello from Goroutine! #1") +}() + +go func() { + sentry.ConfigureScope(func(scope *sentry.Scope) { + scope.SetTag("secretTag", "go#2") + }) + sentry.CaptureMessage("Hello from Goroutine! #2") +}() + +// at this point both events can have either `go#1` tag or `go#2` tag or it can panic with concurrent writes. We'll never know. +``` + +```go +// Example of __CORRECT__ use of scopes inside a Goroutines + +go func(localHub *sentry.Hub) { + // as goroutine argument + localHub.ConfigureScope(func(scope *sentry.Scope) { + scope.SetTag("secretTag", "go#1") + }) + localHub.CaptureMessage("Hello from Goroutine! #1") +}(sentry.CurrentHub().Clone()) + +go func() { + // or created locally + localHub := sentry.CurrentHub().Clone() + localHub.ConfigureScope(func(scope *sentry.Scope) { + scope.SetTag("secretTag", "go#2") + }) + localHub.CaptureMessage("Hello from Goroutine! #2") +}() +``` diff --git a/src/collections/_documentation/platforms/go/index.md b/src/collections/_documentation/platforms/go/index.md index 000c58a5721ee..4625c1bdeab73 100644 --- a/src/collections/_documentation/platforms/go/index.md +++ b/src/collections/_documentation/platforms/go/index.md @@ -42,12 +42,24 @@ To use `sentry-go`, you’ll need to import the `sentry-go` package and initiali More on this in [Configuration]({%- link _documentation/platforms/go/config.md -%}) section. +## Usage {#usage} + +{% capture __alert_content -%} + By default, Sentry Go SDK uses asynchronous transport, which in the code example below requires an explicit awaiting for event delivery to be finished using `sentry.Flush` method. It is necessary, because otherwise the program would not wait for the async HTTP calls to return a response, and exit the process immediately when it reached the end of the `main` function. It would not be required inside a running goroutine or if you would use `HTTPSyncTransport`, which you can read about in `Transports` section. +{%- endcapture -%} +{%- include components/alert.html + level="info" + title="Awaiting Event Delivery" + content=__alert_content +%} + ```go package main import ( "fmt" "os" + "time" "github.com/getsentry/sentry-go" ) @@ -64,9 +76,11 @@ func main() { f, err := os.Open("filename.ext") if err != nil { sentry.CaptureException(err) + sentry.Flush(time.Second * 5) } } ``` + ## Next Steps @@ -77,6 +91,7 @@ For more detailed information about how to get the most out of `sentry-go` there - [Error Reporting]({%- link _documentation/error-reporting/quickstart.md -%}?platform={{ include.platform }}) - [Enriching Error Data]({%- link _documentation/enriching-error-data/context.md -%}?platform={{ include.platform }}) - [Transports]({%- link _documentation/platforms/go/transports.md -%}) +- [Goroutines]({%- link _documentation/platforms/go/goroutines.md -%}) - [Integrations]({%- link _documentation/platforms/go/integrations.md -%}) - [net/http]({%- link _documentation/platforms/go/http.md -%}) - [echo]({%- link _documentation/platforms/go/echo.md -%}) diff --git a/src/collections/_documentation/platforms/go/integrations.md b/src/collections/_documentation/platforms/go/integrations.md index 776f0d11db555..1dc2a1a00a8fd 100644 --- a/src/collections/_documentation/platforms/go/integrations.md +++ b/src/collections/_documentation/platforms/go/integrations.md @@ -1,6 +1,6 @@ --- title: Integrations -sidebar_order: 4 +sidebar_order: 5 --- The sentry-go package currently comes with an integration for the native `net/http` package, `echo`, `gin`, `iris`, `martini` and `negroni` to make it easy to handle common scenarios.