// start starts a pulling messages off of the queue and passing them to the // handler. func (q *SQSDispatcher) start(handle func(context.Context, *sqs.Message) error) { var wg sync.WaitGroup for { select { case <-q.stopped: wg.Wait() return default: ctx := q.Context resp, err := q.sqs.ReceiveMessage(&sqs.ReceiveMessageInput{ QueueUrl: aws.String(q.QueueURL), WaitTimeSeconds: aws.Int64(defaultWaitTime), }) if err != nil { reporter.Report(ctx, err) continue } for _, m := range resp.Messages { wg.Add(1) go func(m *sqs.Message) { defer wg.Done() if err := q.handle(ctx, handle, m); err != nil { reporter.Report(ctx, err) } }(m) } } } }
// Build builds the image. func (b *Builder) Build(ctx context.Context, w io.Writer, opts builder.BuildOptions) (image string, err error) { log.Printf("Starting build: id=%s repository=%s branch=%s sha=%s", opts.ID, opts.Repository, opts.Branch, opts.Sha, ) // Embed the reporter in the context.Context. ctx = reporter.WithReporter(ctx, b.reporter()) if b.Timeout != 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, b.Timeout) defer cancel() // Release resources. } reporter.AddContext(ctx, "options", opts) defer reporter.Monitor(ctx) defer func() { if err != nil { reporter.Report(ctx, err) } }() image, err = b.builder.Build(ctx, w, opts) return }
// ServeHTTPContext implements the httpx.Handler interface. It recovers from // panics and returns an error for upstream middleware to handle. func (h *Recovery) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, r *http.Request) (err error) { ctx = reporter.WithReporter(ctx, h.Reporter) // Add the request to the context. reporter.AddRequest(ctx, r) // Add the request id reporter.AddContext(ctx, "request_id", httpx.RequestID(ctx)) defer func() { if v := recover(); v != nil { err = fmt.Errorf("%v", v) if v, ok := v.(error); ok { err = v } reporter.Report(ctx, err) return } }() err = h.handler.ServeHTTPContext(ctx, w, r) return }
// ServeHTTPContext implements the httpx.Handler interface. func (s *Server) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, r *http.Request) error { if err := s.mux.ServeHTTPContext(ctx, w, r); err != nil { Error(w, err, http.StatusInternalServerError) reporter.Report(ctx, err) } return nil }
func (p *ECSServiceResource) create(ctx context.Context, clientToken string, properties *ECSServiceProperties) (string, string, error) { var loadBalancers []*ecs.LoadBalancer for _, v := range properties.LoadBalancers { loadBalancers = append(loadBalancers, &ecs.LoadBalancer{ ContainerName: v.ContainerName, ContainerPort: v.ContainerPort.Value(), LoadBalancerName: v.LoadBalancerName, TargetGroupArn: v.TargetGroupArn, }) } var serviceName *string if properties.ServiceName != nil { serviceName = aws.String(fmt.Sprintf("%s-%s", *properties.ServiceName, clientToken)) } resp, err := p.ecs.CreateService(&ecs.CreateServiceInput{ ClientToken: aws.String(clientToken), ServiceName: serviceName, Cluster: properties.Cluster, DesiredCount: properties.DesiredCount.Value(), Role: properties.Role, TaskDefinition: properties.TaskDefinition, LoadBalancers: loadBalancers, }) if err != nil { return "", "", fmt.Errorf("error creating service: %v", err) } d := primaryDeployment(resp.Service) if d == nil { return "", "", fmt.Errorf("no primary deployment found") } arn := resp.Service.ServiceArn stabilized := make(chan struct{}) go func() { if err := p.ecs.WaitUntilServicesStable(&ecs.DescribeServicesInput{ Cluster: properties.Cluster, Services: []*string{arn}, }); err != nil { // We're ignoring this error, because the service was created, // and if the service doesn't stabilize, it's better to just let // the stack finish creating than rolling back. reporter.Report(ctx, err) } close(stabilized) }() select { case <-stabilized: case <-ctx.Done(): return *arn, *d.Id, ctx.Err() } return *arn, *d.Id, nil }
func Example() { ctx := reporter.WithReporter(context.Background(), hb.NewReporter("dcb8affa")) req, _ := http.NewRequest("GET", "/api/foo", nil) req.Header.Set("Content-Type", "application/json") reporter.AddContext(ctx, "request_id", "1234") reporter.AddRequest(ctx, req) reporter.Report(ctx, errBoom) // Output: }
// ServeHTTPContext implements the httpx.Handler interface. func (s *Server) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, r *http.Request) error { h := Authenticate(s.mux, s.Authenticator) err := h.ServeHTTPContext(ctx, w, r) if err != nil { Error(w, err, http.StatusInternalServerError) reporter.Report(ctx, err) } return nil }
// Start starts pulling requests from the queue and provisioning them. func (c *CustomResourceProvisioner) Start() { t := time.Tick(10 * time.Second) for range t { ctx := c.Context resp, err := c.sqs.ReceiveMessage(&sqs.ReceiveMessageInput{ QueueUrl: aws.String(c.QueueURL), }) if err != nil { reporter.Report(ctx, err) continue } for _, m := range resp.Messages { go func(m *sqs.Message) { if err := c.handle(ctx, m); err != nil { reporter.Report(ctx, err) } }(m) } } }
// SAMLACS handles the SAML Response call. It will validate the SAML Response // and assertions, generate an API token, then present the token to the user. func (s *Server) SAMLACS(ctx context.Context, w http.ResponseWriter, r *http.Request) error { if s.ServiceProvider == nil { http.NotFound(w, r) return nil } assertion, err := s.ServiceProvider.Parse(w, r) if err != nil { if err, ok := err.(*saml.InvalidResponseError); ok { reporter.Report(ctx, err.PrivateErr) } http.Error(w, err.Error(), 403) return nil } // Create an Access Token for the API. login := assertion.Subject.NameID.Value user := &empire.User{ Name: login, } at, err := s.Heroku.AccessTokensCreate(&heroku.AccessToken{ ExpiresAt: &assertion.AuthnStatement.SessionNotOnOrAfter, User: user, }) if err != nil { http.Error(w, err.Error(), 403) return nil } switch r.Header.Get("Accept") { case "text/plain": w.Header().Set("Content-Type", "text/plain") io.WriteString(w, at.Token) default: w.Header().Set("Content-Type", "text/html") instructionsTemplate.Execute(w, &instructionsData{ URL: s.URL, User: user, Token: at, }) } return nil }
// ServeHTTPContext implements the httpx.Handler interface. It recovers from // panics and returns an error for upstream middleware to handle. func (h *Recovery) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, r *http.Request) (err error) { if _, ok := reporter.FromContext(ctx); ok { defer func() { if v := recover(); v != nil { err = fmt.Errorf("%v", v) if v, ok := v.(error); ok { err = v } reporter.Report(ctx, err) return } }() } err = h.handler.ServeHTTPContext(ctx, w, r) return }
// New creates the API routes and returns a new http.Handler to serve them. func New(e *empire.Empire, authenticator auth.Authenticator) httpx.Handler { r := httpx.NewRouter() // Apps r.Handle("/apps", &GetApps{e}).Methods("GET") // hk apps r.Handle("/apps/{app}", &GetAppInfo{e}).Methods("GET") // hk info r.Handle("/apps/{app}", &DeleteApp{e}).Methods("DELETE") // hk destroy r.Handle("/apps/{app}", &PatchApp{e}).Methods("PATCH") // hk destroy r.Handle("/apps/{app}/deploys", &DeployApp{e}).Methods("POST") // Deploy an image to an app r.Handle("/apps", &PostApps{e}).Methods("POST") // hk create r.Handle("/organizations/apps", &PostApps{e}).Methods("POST") // hk create // Domains r.Handle("/apps/{app}/domains", &GetDomains{e}).Methods("GET") // hk domains r.Handle("/apps/{app}/domains", &PostDomains{e}).Methods("POST") // hk domain-add r.Handle("/apps/{app}/domains/{hostname}", &DeleteDomain{e}).Methods("DELETE") // hk domain-remove // Deploys r.Handle("/deploys", &PostDeploys{e}).Methods("POST") // Deploy an app // Releases r.Handle("/apps/{app}/releases", &GetReleases{e}).Methods("GET") // hk releases r.Handle("/apps/{app}/releases/{version}", &GetRelease{e}).Methods("GET") // hk release-info r.Handle("/apps/{app}/releases", &PostReleases{e}).Methods("POST") // hk rollback // Configs r.Handle("/apps/{app}/config-vars", &GetConfigs{e}).Methods("GET") // hk env, hk get r.Handle("/apps/{app}/config-vars", &PatchConfigs{e}).Methods("PATCH") // hk set, hk unset // Processes r.Handle("/apps/{app}/dynos", &GetProcesses{e}).Methods("GET") // hk dynos r.Handle("/apps/{app}/dynos", &PostProcess{e}).Methods("POST") // hk run r.Handle("/apps/{app}/dynos", &DeleteProcesses{e}).Methods("DELETE") // hk restart r.Handle("/apps/{app}/dynos/{ptype}.{pid}", &DeleteProcesses{e}).Methods("DELETE") // hk restart web.1 r.Handle("/apps/{app}/dynos/{pid}", &DeleteProcesses{e}).Methods("DELETE") // hk restart web // Formations r.Handle("/apps/{app}/formation", &GetFormation{e}).Methods("GET") // hk scale -l r.Handle("/apps/{app}/formation", &PatchFormation{e}).Methods("PATCH") // hk scale // OAuth r.Handle("/oauth/authorizations", &PostAuthorizations{e}).Methods("POST") // SSL sslRemoved := errHandler(ErrSSLRemoved) r.Handle("/apps/{app}/ssl-endpoints", sslRemoved).Methods("GET") // hk ssl r.Handle("/apps/{app}/ssl-endpoints", sslRemoved).Methods("POST") // hk ssl-cert-add r.Handle("/apps/{app}/ssl-endpoints/{cert}", sslRemoved).Methods("PATCH") // hk ssl-cert-add, hk ssl-cert-rollback r.Handle("/apps/{app}/ssl-endpoints/{cert}", sslRemoved).Methods("DELETE") // hk ssl-destroy // Logs r.Handle("/apps/{app}/log-sessions", &PostLogs{e}).Methods("POST") // hk log api := Authenticate(r, authenticator) return httpx.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { err := api.ServeHTTPContext(ctx, w, r) if err != nil { Error(w, err, http.StatusInternalServerError) reporter.Report(ctx, err) } return nil }) }