Initial work on async functions

This commit is contained in:
Seif Lotfy
2016-09-14 16:11:37 -07:00
committed by Seif Lotfy
parent bf6c4b0a4a
commit b623fc27e4
30 changed files with 1986 additions and 59 deletions

View File

@@ -44,7 +44,9 @@ func testRouter() *gin.Engine {
c.Set("ctx", ctx)
c.Next()
})
bindHandlers(r)
bindHandlers(r, func(ctx *gin.Context) {
handleRequest(ctx, nil)
})
return r
}

View File

@@ -52,6 +52,7 @@ func handleRouteCreate(c *gin.Context) {
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsGet))
return
}
if app == nil {
newapp := &models.App{Name: wroute.Route.AppName}
if err := newapp.Validate(); err != nil {

View File

@@ -17,6 +17,7 @@ import (
"github.com/iron-io/functions/api/models"
"github.com/iron-io/functions/api/runner"
titancommon "github.com/iron-io/worker/common"
"github.com/iron-io/worker/runner/drivers"
"github.com/satori/go.uuid"
)
@@ -31,7 +32,7 @@ func handleSpecial(c *gin.Context) {
}
}
func handleRunner(c *gin.Context) {
func handleRequest(c *gin.Context, enqueue models.Enqueue) {
if strings.HasPrefix(c.Request.URL.Path, "/v1") {
c.Status(http.StatusNotFound)
return
@@ -151,10 +152,29 @@ func handleRunner(c *gin.Context) {
Memory: el.Memory,
}
if result, err := Api.Runner.Run(c, cfg); err != nil {
log.WithError(err).Error(models.ErrRunnerRunRoute)
c.JSON(http.StatusInternalServerError, simpleError(models.ErrRunnerRunRoute))
} else {
// Request count metric
metricBaseName := "server.handleRequest." + appName + "."
runner.LogMetricCount(ctx, (metricBaseName + "requests"), 1)
metricStart := time.Now()
var err error
var result drivers.RunResult
switch el.Type {
case "async":
// TODO: Create Task
priority := int32(0)
task := &models.Task{}
task.Image = &cfg.Image
task.ID = cfg.ID
task.GroupName = cfg.AppName
task.Priority = &priority
// TODO: Push to queue
enqueue(task)
default:
if result, err = Api.Runner.Run(c, cfg); err != nil {
break
}
for k, v := range el.Headers {
c.Header(k, v[0])
}
@@ -166,6 +186,16 @@ func handleRunner(c *gin.Context) {
c.AbortWithStatus(http.StatusInternalServerError)
}
}
if err != nil {
log.WithError(err).Error(models.ErrRunnerRunRoute)
c.JSON(http.StatusInternalServerError, simpleError(models.ErrRunnerRunRoute))
}
// Execution time metric
metricElapsed := time.Since(metricStart)
runner.LogMetricTime(ctx, (metricBaseName + "time"), metricElapsed)
runner.LogMetricTime(ctx, "server.handleRunner.exec_time", metricElapsed)
return
}
}

View File

@@ -21,14 +21,16 @@ type Server struct {
Runner *runner.Runner
Router *gin.Engine
Datastore models.Datastore
MQ models.MessageQueue
AppListeners []ifaces.AppListener
SpecialHandlers []ifaces.SpecialHandler
}
func New(ds models.Datastore, r *runner.Runner) *Server {
func New(ds models.Datastore, mq models.MessageQueue, r *runner.Runner) *Server {
Api = &Server{
Router: gin.Default(),
Datastore: ds,
MQ: mq,
Runner: r,
}
return Api
@@ -75,10 +77,17 @@ func (s *Server) UseSpecialHandlers(ginC *gin.Context) error {
}
}
// now call the normal runner call
handleRunner(ginC)
handleRequest(ginC, nil)
return nil
}
func (s *Server) handleRequest(ginC *gin.Context) {
enqueue := func(task *models.Task) (*models.Task, error) {
return s.MQ.Push(task)
}
handleRequest(ginC, enqueue)
}
func extractFields(c *gin.Context) logrus.Fields {
fields := logrus.Fields{"action": path.Base(c.HandlerName())}
for _, param := range c.Params {
@@ -95,14 +104,14 @@ func (s *Server) Run(ctx context.Context) {
c.Next()
})
bindHandlers(s.Router)
bindHandlers(s.Router, s.handleRequest)
// By default it serves on :8080 unless a
// PORT environment variable was defined.
s.Router.Run()
}
func bindHandlers(engine *gin.Engine) {
func bindHandlers(engine *gin.Engine, reqHandler func(ginC *gin.Context)) {
engine.GET("/", handlePing)
engine.GET("/version", handleVersion)
@@ -127,7 +136,7 @@ func bindHandlers(engine *gin.Engine) {
}
}
engine.Any("/r/:app/*route", handleRunner)
engine.Any("/r/:app/*route", reqHandler)
// This final route is used for extensions, see Server.Add
engine.NoRoute(handleSpecial)