Skip to content

Commit

Permalink
fix container re-use issues. stability enhancement.
Browse files Browse the repository at this point in the history
  • Loading branch information
tmaiaroto committed Dec 10, 2017
1 parent 7e77d13 commit 76cd359
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 233 deletions.
2 changes: 1 addition & 1 deletion cmd/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func compress(fileName string) string {
// log.Println("aegis_app file mode:", aegisAppFileInfo.Mode())
// header.SetMode(aegisAppFileInfo.Mode())
zipWriter, _ := zipper.Writer.CreateHeader(header)
log.Println("zip header", header)
// log.Println("zip header", header)

content, err := ioutil.ReadFile(aegisAppName)
if err == nil {
Expand Down
22 changes: 16 additions & 6 deletions lambda/lambda.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ package lambda
import (
"encoding/json"
"fmt"
"github.com/Sirupsen/logrus"
"github.com/aws/aws-sdk-go/aws"
"github.com/tmaiaroto/logrus-cloudwatchlogs"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"strconv"

"github.com/Sirupsen/logrus"
"github.com/aws/aws-sdk-go/aws"
"github.com/tmaiaroto/logrus-cloudwatchlogs"
)

type (
Expand Down Expand Up @@ -113,6 +114,7 @@ type (
// },
// "body": "{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":\"value3\"}"
// }
// Will adding ID break it?
ProxyResponse struct {
StatusCode string `json:"statusCode"`
Headers map[string]string `json:"headers"`
Expand Down Expand Up @@ -165,7 +167,7 @@ func RunStream(handler Handler, Stdin io.Reader, Stdout io.Writer) {
cfg := aws.NewConfig()
hook, err := logrus_cloudwatchlogs.NewHook(payload.Context.LogGroupName, payload.Context.LogStreamName, cfg)
if err != nil {
log.Println("Error setting up logrus hook for CloudWatch")
log.Println("[aegis] Error setting up logrus hook for CloudWatch")
log.Fatal(err)
}
Log.Hooks.Add(hook)
Expand All @@ -176,6 +178,15 @@ func RunStream(handler Handler, Stdin io.Reader, Stdout io.Writer) {
payload.Event.HandlerStartTime = payload.Event.HandlerStartTimeMs * 1000000
resp := handler(payload.Context, payload.Event)

// Set the request id in the response... Does this break things? Lambda Proxy requires a specific format with statusCode, body, etc.
// Can we add more? We need this to keep track of concurrent callbacks in the Node.js wrapper (until go support is available early 2018).
// resp.ID = payload.Event.RequestContext.RequestID
// maybe doesn't work...
// If this doesn't work, then we can stick it in the header. Which isn't a bad place to stick it anyway.
// In fact, we want to ensure X-Ray has whatever it needs there too.
// The trick is just ensuring that we are appending to and not replacing whatever the user application sets for headers.
resp.Headers["request-id"] = payload.Event.RequestContext.RequestID

if err != nil {
// If thre's an error, the statusCode has to be in the 500's.
// If it isn't, use generic 500.
Expand All @@ -191,10 +202,9 @@ func RunStream(handler Handler, Stdin io.Reader, Stdout io.Writer) {
}(); err != nil {
if encErr := stdout.Encode(NewProxyResponse(http.StatusInternalServerError, map[string]string{}, "", err)); encErr != nil {
// bad times
log.Println("Failed to encode err response!", encErr.Error())
log.Println("[aegis] Failed to encode err response!", encErr.Error())
}
}

}

// HandleProxy handles an AWS Lambda function as proxy via API Gateway directly
Expand Down
56 changes: 29 additions & 27 deletions lambda/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,35 +108,37 @@ func runMiddleware(ctx *Context, evt *Event, res *ProxyResponse, params url.Valu

// Listen will start the internal router and listen for Lambda events to forward to registered routes.
func (r *Router) Listen() {
RunStream(func(ctx *Context, evt *Event) *ProxyResponse {
// url.Values are typically used for qureystring parameters.
// However, this router uses them for path params.
// Querystring parameters can be picked up from the *Event though.
params := url.Values{}
// New empty response with a 200 status code since nothing has gone wrong yet, it's just empty.
res := NewProxyResponse(200, map[string]string{}, "", nil)

// use the Path and HTTPMethod from the event to figure out the route
node, _ := r.tree.traverse(strings.Split(evt.Path, "/")[1:], params)
if handler := node.methods[evt.HTTPMethod]; handler != nil {
// Middleware must return true in order to continue.
// If it returns false, it will catch and halt everything.
if !runMiddleware(ctx, evt, res, params, handler.middleware...) {
// TODO: Figure out what to do here. I'm not sure what makes sense.
// Should it return the response in its current state?
return res
// Or should it return an error?
// Typically it leaves the request hanging if it returns false.
// The middleware would need to write something back to the client.
// return NewProxyResponse(500, map[string]string{}, "", nil)
for {
RunStream(func(ctx *Context, evt *Event) *ProxyResponse {
// url.Values are typically used for qureystring parameters.
// However, this router uses them for path params.
// Querystring parameters can be picked up from the *Event though.
params := url.Values{}
// New empty response with a 200 status code since nothing has gone wrong yet, it's just empty.
res := NewProxyResponse(200, map[string]string{}, "", nil)

// use the Path and HTTPMethod from the event to figure out the route
node, _ := r.tree.traverse(strings.Split(evt.Path, "/")[1:], params)
if handler := node.methods[evt.HTTPMethod]; handler != nil {
// Middleware must return true in order to continue.
// If it returns false, it will catch and halt everything.
if !runMiddleware(ctx, evt, res, params, handler.middleware...) {
// TODO: Figure out what to do here. I'm not sure what makes sense.
// Should it return the response in its current state?
return res
// Or should it return an error?
// Typically it leaves the request hanging if it returns false.
// The middleware would need to write something back to the client.
// return NewProxyResponse(500, map[string]string{}, "", nil)
}
handler.handler(ctx, evt, res, params)
} else {
r.rootHandler(ctx, evt, res, params)
}
handler.handler(ctx, evt, res, params)
} else {
r.rootHandler(ctx, evt, res, params)
}

return res
}, os.Stdin, os.Stdout)
return res
}, os.Stdin, os.Stdout)
}
}

// gatewayHandler is a Router that implements an http.Handler interface
Expand Down
6 changes: 3 additions & 3 deletions lambda/shim/bindata.go

Large diffs are not rendered by default.

Loading

0 comments on commit 76cd359

Please sign in to comment.