Use common controller/store for httpTriggerSet and functionReferenceResolver (#390)
This fixes a bug where functionReferenceResolver returned out-of-date function metadata and caused the router to proxy requests to old function pods. It also uses the go context package to shutdown the controller when the router is shutting down.
This commit is contained in:
committed by
Soam Vasani
parent
9694ba4fd1
commit
da07b35a96
+40
-49
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
@@ -24,8 +25,6 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/rest"
|
||||
k8sCache "k8s.io/client-go/tools/cache"
|
||||
|
||||
@@ -37,30 +36,42 @@ import (
|
||||
type HTTPTriggerSet struct {
|
||||
*functionServiceMap
|
||||
*mutableRouter
|
||||
fissionClient *crd.FissionClient
|
||||
poolmgr *poolmgrClient.Client
|
||||
resolver *functionReferenceResolver
|
||||
triggers []crd.HTTPTrigger
|
||||
triggerStore k8sCache.Store
|
||||
functions []crd.Function
|
||||
funcStore k8sCache.Store
|
||||
crdClient *rest.RESTClient
|
||||
fissionClient *crd.FissionClient
|
||||
poolmgr *poolmgrClient.Client
|
||||
resolver *functionReferenceResolver
|
||||
crdClient *rest.RESTClient
|
||||
triggers []crd.HTTPTrigger
|
||||
triggerStore k8sCache.Store
|
||||
triggerController k8sCache.Controller
|
||||
functions []crd.Function
|
||||
funcStore k8sCache.Store
|
||||
funcController k8sCache.Controller
|
||||
}
|
||||
|
||||
func makeHTTPTriggerSet(fmap *functionServiceMap, fissionClient *crd.FissionClient,
|
||||
poolmgr *poolmgrClient.Client, resolver *functionReferenceResolver, crdClient *rest.RESTClient) *HTTPTriggerSet {
|
||||
triggers := make([]crd.HTTPTrigger, 1)
|
||||
return &HTTPTriggerSet{
|
||||
poolmgr *poolmgrClient.Client, crdClient *rest.RESTClient) (*HTTPTriggerSet, k8sCache.Store, k8sCache.Store) {
|
||||
httpTriggerSet := &HTTPTriggerSet{
|
||||
functionServiceMap: fmap,
|
||||
triggers: triggers,
|
||||
triggers: []crd.HTTPTrigger{},
|
||||
fissionClient: fissionClient,
|
||||
poolmgr: poolmgr,
|
||||
resolver: resolver,
|
||||
crdClient: crdClient,
|
||||
}
|
||||
var tStore, fnStore k8sCache.Store
|
||||
var tController, fnController k8sCache.Controller
|
||||
if httpTriggerSet.crdClient != nil {
|
||||
tStore, tController = httpTriggerSet.initTriggerController()
|
||||
httpTriggerSet.triggerStore = tStore
|
||||
httpTriggerSet.triggerController = tController
|
||||
fnStore, fnController = httpTriggerSet.initFunctionController()
|
||||
httpTriggerSet.funcStore = fnStore
|
||||
httpTriggerSet.funcController = fnController
|
||||
}
|
||||
return httpTriggerSet, tStore, fnStore
|
||||
}
|
||||
|
||||
func (ts *HTTPTriggerSet) subscribeRouter(mr *mutableRouter) {
|
||||
func (ts *HTTPTriggerSet) subscribeRouter(ctx context.Context, mr *mutableRouter, resolver *functionReferenceResolver) {
|
||||
ts.resolver = resolver
|
||||
ts.mutableRouter = mr
|
||||
mr.updateRouter(ts.getRouter())
|
||||
|
||||
@@ -69,8 +80,8 @@ func (ts *HTTPTriggerSet) subscribeRouter(mr *mutableRouter) {
|
||||
log.Printf("Skipping continuous trigger updates")
|
||||
return
|
||||
}
|
||||
go ts.watchTriggers()
|
||||
go ts.watchFunctions()
|
||||
go ts.runWatcher(ctx, ts.funcController)
|
||||
go ts.runWatcher(ctx, ts.triggerController)
|
||||
}
|
||||
|
||||
func defaultHomeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -140,17 +151,9 @@ func (ts *HTTPTriggerSet) updateTriggerStatusFailed(ht *crd.HTTPTrigger, err err
|
||||
// TODO
|
||||
}
|
||||
|
||||
func (ts *HTTPTriggerSet) watchTriggers() {
|
||||
watchlist := k8sCache.NewListWatchFromClient(ts.crdClient, "httptriggers", metav1.NamespaceDefault, fields.Everything())
|
||||
listWatch := &k8sCache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
return watchlist.List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
return watchlist.Watch(options)
|
||||
},
|
||||
}
|
||||
func (ts *HTTPTriggerSet) initTriggerController() (k8sCache.Store, k8sCache.Controller) {
|
||||
resyncPeriod := 30 * time.Second
|
||||
listWatch := k8sCache.NewListWatchFromClient(ts.crdClient, "httptriggers", metav1.NamespaceDefault, fields.Everything())
|
||||
store, controller := k8sCache.NewInformer(listWatch, &crd.HTTPTrigger{}, resyncPeriod,
|
||||
k8sCache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
@@ -163,25 +166,12 @@ func (ts *HTTPTriggerSet) watchTriggers() {
|
||||
ts.syncTriggers()
|
||||
},
|
||||
})
|
||||
ts.triggerStore = store
|
||||
stop := make(chan struct{})
|
||||
defer func() {
|
||||
stop <- struct{}{}
|
||||
}()
|
||||
controller.Run(stop)
|
||||
return store, controller
|
||||
}
|
||||
|
||||
func (ts *HTTPTriggerSet) watchFunctions() {
|
||||
watchlist := k8sCache.NewListWatchFromClient(ts.crdClient, "functions", metav1.NamespaceDefault, fields.Everything())
|
||||
listWatch := &k8sCache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
return watchlist.List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
return watchlist.Watch(options)
|
||||
},
|
||||
}
|
||||
func (ts *HTTPTriggerSet) initFunctionController() (k8sCache.Store, k8sCache.Controller) {
|
||||
resyncPeriod := 30 * time.Second
|
||||
listWatch := k8sCache.NewListWatchFromClient(ts.crdClient, "functions", metav1.NamespaceDefault, fields.Everything())
|
||||
store, controller := k8sCache.NewInformer(listWatch, &crd.Function{}, resyncPeriod,
|
||||
k8sCache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
@@ -206,12 +196,13 @@ func (ts *HTTPTriggerSet) watchFunctions() {
|
||||
ts.syncTriggers()
|
||||
},
|
||||
})
|
||||
ts.funcStore = store
|
||||
stop := make(chan struct{})
|
||||
defer func() {
|
||||
stop <- struct{}{}
|
||||
return store, controller
|
||||
}
|
||||
|
||||
func (ts *HTTPTriggerSet) runWatcher(ctx context.Context, controller k8sCache.Controller) {
|
||||
go func() {
|
||||
controller.Run(ctx.Done())
|
||||
}()
|
||||
controller.Run(stop)
|
||||
}
|
||||
|
||||
func (ts *HTTPTriggerSet) syncTriggers() {
|
||||
|
||||
Reference in New Issue
Block a user