mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Fix race condition during initialization (#163)
Currently, async workers are started before HTTP interface is available
to get their requests. It fixes by ensuring that async workers are
started after HTTP interface is up.
Essentially we are getting rid of an error message during bootstrap:
ERRO[0000] Could not fetch task error=Get http://127.0.0.1:8080/tasks: dial tcp 127.0.0.1:8080: getsockopt: connection refused
This commit is contained in:
committed by
Seif Lotfy سيف لطفي
parent
34b4b25092
commit
df3d5b48ce
@@ -96,8 +96,11 @@ func runTask(task *models.Task) (drivers.RunResult, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RunAsyncRunner pulls tasks off a queue and processes them
|
// RunAsyncRunner pulls tasks off a queue and processes them
|
||||||
func RunAsyncRunner(ctx context.Context, wgAsync *sync.WaitGroup, tasksrv, port string, n int) {
|
func RunAsyncRunner(ctx context.Context, tasksrv, port string, n int) {
|
||||||
u := tasksrvURL(tasksrv, port)
|
u, h := tasksrvURL(tasksrv, port)
|
||||||
|
if isHostOpen(h) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
@@ -107,7 +110,15 @@ func RunAsyncRunner(ctx context.Context, wgAsync *sync.WaitGroup, tasksrv, port
|
|||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
wgAsync.Done()
|
}
|
||||||
|
|
||||||
|
func isHostOpen(host string) bool {
|
||||||
|
conn, err := net.Dial("tcp", host)
|
||||||
|
available := err == nil
|
||||||
|
if available {
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
return available
|
||||||
}
|
}
|
||||||
|
|
||||||
func startAsyncRunners(ctx context.Context, wg *sync.WaitGroup, i int, url string, runTask func(task *models.Task) (drivers.RunResult, error)) {
|
func startAsyncRunners(ctx context.Context, wg *sync.WaitGroup, i int, url string, runTask func(task *models.Task) (drivers.RunResult, error)) {
|
||||||
@@ -150,7 +161,7 @@ func startAsyncRunners(ctx context.Context, wg *sync.WaitGroup, i int, url strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func tasksrvURL(tasksrv, port string) string {
|
func tasksrvURL(tasksrv, port string) (parsedURL, host string) {
|
||||||
parsed, err := url.Parse(tasksrv)
|
parsed, err := url.Parse(tasksrv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("cannot parse TASKSRV endpoint: %v", err)
|
log.Fatalf("cannot parse TASKSRV endpoint: %v", err)
|
||||||
@@ -168,5 +179,5 @@ func tasksrvURL(tasksrv, port string) string {
|
|||||||
parsed.Host = net.JoinHostPort(parsed.Host, port)
|
parsed.Host = net.JoinHostPort(parsed.Host, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsed.String()
|
return parsed.String(), parsed.Host
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ func TestTasksrvURL(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
if got := tasksrvURL(tt.in, tt.port); got != tt.out {
|
if got, _ := tasksrvURL(tt.in, tt.port); got != tt.out {
|
||||||
t.Errorf("port: %s\ttasksrv: %s\texpected: %s\tgot: %s", tt.port, tt.in, tt.out, got)
|
t.Errorf("port: %s\ttasksrv: %s\texpected: %s\tgot: %s", tt.port, tt.in, tt.out, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,8 @@ func (s *Server) Run(ctx context.Context) {
|
|||||||
|
|
||||||
// By default it serves on :8080 unless a
|
// By default it serves on :8080 unless a
|
||||||
// PORT environment variable was defined.
|
// PORT environment variable was defined.
|
||||||
s.Router.Run()
|
go s.Router.Run()
|
||||||
|
<-ctx.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
func bindHandlers(engine *gin.Engine, reqHandler func(ginC *gin.Context), taskHandler func(ginC *gin.Context)) {
|
func bindHandlers(engine *gin.Engine, reqHandler func(ginC *gin.Context), taskHandler func(ginC *gin.Context)) {
|
||||||
|
|||||||
20
glide.lock
generated
20
glide.lock
generated
@@ -1,6 +1,8 @@
|
|||||||
hash: 5ebe9893c89f9d0b31b71bd27fb37bf4fae1662e6fbc429d566b0d75ca7ffcfc
|
hash: 25de4b7591e695585ed10d0a2b6c6419576f5aab60e28b84f07fb77908eca9e1
|
||||||
updated: 2016-10-11T18:10:30.697966926-07:00
|
updated: 2016-10-13T19:37:24.59686575+02:00
|
||||||
imports:
|
imports:
|
||||||
|
- name: cirello.io/supervisor
|
||||||
|
version: dd9fbc61e43585f9b73af69d598816902b643fb0
|
||||||
- name: github.com/amir/raidman
|
- name: github.com/amir/raidman
|
||||||
version: c74861fe6a7bb8ede0a010ce4485bdbb4fc4c985
|
version: c74861fe6a7bb8ede0a010ce4485bdbb4fc4c985
|
||||||
subpackages:
|
subpackages:
|
||||||
@@ -13,6 +15,16 @@ imports:
|
|||||||
version: 91c326c3f7bd20f0226d3d1c289dd9f8ce28d33d
|
version: 91c326c3f7bd20f0226d3d1c289dd9f8ce28d33d
|
||||||
subpackages:
|
subpackages:
|
||||||
- statsd
|
- statsd
|
||||||
|
- name: github.com/cenkalti/backoff
|
||||||
|
version: 8edc80b07f38c27352fb186d971c628a6c32552b
|
||||||
|
- name: github.com/dghubble/go-twitter
|
||||||
|
version: 12e5387804e84bf20dc60ba964f59437553e16a6
|
||||||
|
subpackages:
|
||||||
|
- twitter
|
||||||
|
- name: github.com/dghubble/oauth1
|
||||||
|
version: 4385816142116aade2d97d0f320f9d3666e74cd9
|
||||||
|
- name: github.com/dghubble/sling
|
||||||
|
version: c961a4334054e64299d16f8a31bd686ee2565ae4
|
||||||
- name: github.com/dgrijalva/jwt-go
|
- name: github.com/dgrijalva/jwt-go
|
||||||
version: 268038b363c7a8d7306b8e35bf77a1fde4b0c402
|
version: 268038b363c7a8d7306b8e35bf77a1fde4b0c402
|
||||||
- name: github.com/docker/distribution
|
- name: github.com/docker/distribution
|
||||||
@@ -86,6 +98,10 @@ imports:
|
|||||||
- proto
|
- proto
|
||||||
- name: github.com/google/btree
|
- name: github.com/google/btree
|
||||||
version: 925471ac9e2131377a91e1595defec898166fe49
|
version: 925471ac9e2131377a91e1595defec898166fe49
|
||||||
|
- name: github.com/google/go-querystring
|
||||||
|
version: 9235644dd9e52eeae6fa48efd539fdc351a0af53
|
||||||
|
subpackages:
|
||||||
|
- query
|
||||||
- name: github.com/gorilla/context
|
- name: github.com/gorilla/context
|
||||||
version: 14f550f51af52180c2eefed15e5fd18d63c0a64a
|
version: 14f550f51af52180c2eefed15e5fd18d63c0a64a
|
||||||
- name: github.com/gorilla/mux
|
- name: github.com/gorilla/mux
|
||||||
|
|||||||
@@ -37,3 +37,5 @@ import:
|
|||||||
version: ^3.1.0
|
version: ^3.1.0
|
||||||
subpackages:
|
subpackages:
|
||||||
- statsd
|
- statsd
|
||||||
|
- package: cirello.io/supervisor
|
||||||
|
version: v0.5.0
|
||||||
|
|||||||
28
main.go
28
main.go
@@ -6,8 +6,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
|
|
||||||
|
"cirello.io/supervisor"
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/iron-io/functions/api/datastore"
|
"github.com/iron-io/functions/api/datastore"
|
||||||
@@ -79,16 +79,24 @@ func main() {
|
|||||||
log.WithError(err).Fatalln("Failed to create a runner")
|
log.WithError(err).Fatalln("Failed to create a runner")
|
||||||
}
|
}
|
||||||
|
|
||||||
apiURL, port, numAsync := viper.GetString(envAPIURL), viper.GetString(envPort), viper.GetInt(envNumAsync)
|
svr := &supervisor.Supervisor{
|
||||||
log.Debug("async workers:", numAsync)
|
Log: func(msg interface{}) {
|
||||||
var wgAsync sync.WaitGroup
|
log.Debug("supervisor: ", msg)
|
||||||
if numAsync > 0 {
|
},
|
||||||
wgAsync.Add(1)
|
|
||||||
go runner.RunAsyncRunner(ctx, &wgAsync, apiURL, port, numAsync)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svr.AddFunc(func(ctx context.Context) {
|
||||||
srv := server.New(ds, mqType, rnr)
|
srv := server.New(ds, mqType, rnr)
|
||||||
go srv.Run(ctx)
|
srv.Run(ctx)
|
||||||
<-ctx.Done()
|
})
|
||||||
wgAsync.Wait()
|
|
||||||
|
apiURL, port, numAsync := viper.GetString(envAPIURL), viper.GetString(envPort), viper.GetInt(envNumAsync)
|
||||||
|
log.Debug("async workers:", numAsync)
|
||||||
|
if numAsync > 0 {
|
||||||
|
svr.AddFunc(func(ctx context.Context) {
|
||||||
|
runner.RunAsyncRunner(ctx, apiURL, port, numAsync)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
svr.Serve(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user