Merge pull request #6 from platform9/top-level-package

Move some fission structs to top level package
This commit is contained in:
Soam Vasani
2016-09-09 15:10:09 -07:00
committed by GitHub
8 changed files with 66 additions and 37 deletions
+6 -4
View File
@@ -22,12 +22,14 @@ import (
"net/http" "net/http"
"net/http/httputil" "net/http/httputil"
"net/url" "net/url"
"github.com/platform9/fission"
) )
type functionHandler struct { type functionHandler struct {
fmap *functionServiceMap fmap *functionServiceMap
poolManagerUrl string poolManagerUrl string
function fission.Function
} }
func (*functionHandler) getServiceForFunction() (*url.URL, error) { func (*functionHandler) getServiceForFunction() (*url.URL, error) {
@@ -35,20 +37,20 @@ func (*functionHandler) getServiceForFunction() (*url.URL, error) {
} }
func (fh *functionHandler) handler(responseWriter http.ResponseWriter, request *http.Request) { func (fh *functionHandler) handler(responseWriter http.ResponseWriter, request *http.Request) {
serviceUrl, err := fh.fmap.lookup(&fh.function) serviceUrl, err := fh.fmap.lookup(&fh.Function)
if err != nil { if err != nil {
// Cache miss: request the Pool Manager to make a new service. // Cache miss: request the Pool Manager to make a new service.
serviceUrl, poolErr := fh.getServiceForFunction() serviceUrl, poolErr := fh.getServiceForFunction()
if poolErr != nil { if poolErr != nil {
// now we're really screwed // now we're really screwed
log.Printf("Failed to get service for function (%v,%v): %v", log.Printf("Failed to get service for function (%v,%v): %v",
fh.function.name, fh.function.uid, poolErr) fh.Function.Name, fh.Function.Uid, poolErr)
responseWriter.WriteHeader(500) // TODO: make this smarter based on the actual error responseWriter.WriteHeader(500) // TODO: make this smarter based on the actual error
return return
} }
// add it to the map // add it to the map
fh.fmap.assign(&fh.function, serviceUrl) fh.fmap.assign(&fh.Function, serviceUrl)
} }
// Proxy off our request to the serviceUrl, and send the response back. // Proxy off our request to the serviceUrl, and send the response back.
+5 -4
View File
@@ -19,10 +19,11 @@ package router
import ( import (
"log" "log"
"net/http" "net/http"
"testing"
// "net/http/httputil"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"testing"
"github.com/platform9/fission"
) )
func createBackendService(testResponseString string) *url.URL { func createBackendService(testResponseString string) *url.URL {
@@ -48,11 +49,11 @@ func TestFunctionProxying(t *testing.T) {
backendURL := createBackendService(testResponseString) backendURL := createBackendService(testResponseString)
log.Printf("Created backend svc at %v", backendURL) log.Printf("Created backend svc at %v", backendURL)
fn := &function{name: "foo", uid: "xxx"} fn := &fission.Function{Name: "foo", Uid: "xxx"}
fmap := makeFunctionServiceMap() fmap := makeFunctionServiceMap()
fmap.assign(fn, backendURL) fmap.assign(fn, backendURL)
fh := &functionHandler{fmap: fmap, function: *fn} fh := &functionHandler{fmap: fmap, Function: *fn}
functionHandlerServer := httptest.NewServer(http.HandlerFunc(fh.handler)) functionHandlerServer := httptest.NewServer(http.HandlerFunc(fh.handler))
fhURL := functionHandlerServer.URL fhURL := functionHandlerServer.URL
+11 -9
View File
@@ -20,6 +20,8 @@ import (
"errors" "errors"
"log" "log"
"net/url" "net/url"
"github.com/platform9/fission"
) )
type requestType int type requestType int
@@ -36,7 +38,7 @@ type functionServiceMapResponse struct {
error error
} }
type functionServiceMapRequest struct { type functionServiceMapRequest struct {
function fission.Function
serviceUrl url.URL serviceUrl url.URL
requestType requestType
responseChannel chan<- functionServiceMapResponse responseChannel chan<- functionServiceMapResponse
@@ -48,7 +50,7 @@ type functionServiceMapEntry struct {
type functionServiceMap struct { type functionServiceMap struct {
// map (funcname, uid) -> url // map (funcname, uid) -> url
svc map[function]functionServiceMapEntry svc map[fission.Function]functionServiceMapEntry
currentGeneration uint64 currentGeneration uint64
requestChannel chan *functionServiceMapRequest requestChannel chan *functionServiceMapRequest
} }
@@ -56,7 +58,7 @@ type functionServiceMap struct {
func makeFunctionServiceMap() *functionServiceMap { func makeFunctionServiceMap() *functionServiceMap {
fmap := &functionServiceMap{} fmap := &functionServiceMap{}
fmap.requestChannel = make(chan *functionServiceMapRequest) fmap.requestChannel = make(chan *functionServiceMapRequest)
fmap.svc = make(map[function]functionServiceMapEntry) fmap.svc = make(map[fission.Function]functionServiceMapEntry)
go fmap.functionServiceMapWork() go fmap.functionServiceMapWork()
return fmap return fmap
} }
@@ -66,14 +68,14 @@ func (fmap *functionServiceMap) functionServiceMapWork() {
req := <-fmap.requestChannel req := <-fmap.requestChannel
switch req.requestType { switch req.requestType {
case LOOKUP: case LOOKUP:
e, present := fmap.svc[req.function] e, present := fmap.svc[req.Function]
if present { if present {
req.responseChannel <- functionServiceMapResponse{serviceUrl: e.serviceUrl} req.responseChannel <- functionServiceMapResponse{serviceUrl: e.serviceUrl}
} else { } else {
req.responseChannel <- functionServiceMapResponse{error: errors.New("not found")} req.responseChannel <- functionServiceMapResponse{error: errors.New("not found")}
} }
case ASSIGN: case ASSIGN:
fmap.svc[req.function] = fmap.svc[req.Function] =
functionServiceMapEntry{serviceUrl: req.serviceUrl, generation: fmap.currentGeneration} functionServiceMapEntry{serviceUrl: req.serviceUrl, generation: fmap.currentGeneration}
// no response // no response
case NEXT_GEN: case NEXT_GEN:
@@ -87,9 +89,9 @@ func (fmap *functionServiceMap) functionServiceMapWork() {
} }
} }
func (fmap *functionServiceMap) lookup(f *function) (*url.URL, error) { func (fmap *functionServiceMap) lookup(f *fission.Function) (*url.URL, error) {
respChannel := make(chan functionServiceMapResponse) respChannel := make(chan functionServiceMapResponse)
fmap.requestChannel <- &functionServiceMapRequest{function: *f, requestType: LOOKUP, responseChannel: respChannel} fmap.requestChannel <- &functionServiceMapRequest{Function: *f, requestType: LOOKUP, responseChannel: respChannel}
resp := <-respChannel resp := <-respChannel
if resp.error != nil { if resp.error != nil {
return nil, resp.error return nil, resp.error
@@ -98,8 +100,8 @@ func (fmap *functionServiceMap) lookup(f *function) (*url.URL, error) {
} }
} }
func (fmap *functionServiceMap) assign(f *function, serviceUrl *url.URL) { func (fmap *functionServiceMap) assign(f *fission.Function, serviceUrl *url.URL) {
fmap.requestChannel <- &functionServiceMapRequest{function: *f, serviceUrl: *serviceUrl, requestType: ASSIGN} fmap.requestChannel <- &functionServiceMapRequest{Function: *f, serviceUrl: *serviceUrl, requestType: ASSIGN}
} }
func (fmap *functionServiceMap) nextGen() { func (fmap *functionServiceMap) nextGen() {
+4 -2
View File
@@ -19,11 +19,13 @@ package router
import ( import (
"net/url" "net/url"
"testing" "testing"
"github.com/platform9/fission"
) )
func TestFunctionServiceMap(t *testing.T) { func TestFunctionServiceMap(t *testing.T) {
m := makeFunctionServiceMap() m := makeFunctionServiceMap()
fn := &function{name: "foo", uid: "012"} fn := &fission.Function{Name: "foo", Uid: "012"}
u, err := url.Parse("/foo012") u, err := url.Parse("/foo012")
if err != nil { if err != nil {
t.Errorf("can't parse url") t.Errorf("can't parse url")
@@ -39,7 +41,7 @@ func TestFunctionServiceMap(t *testing.T) {
t.Errorf("Expected %#v, got %#v", u, v) t.Errorf("Expected %#v, got %#v", u, v)
} }
fn.name = "bar" fn.Name = "bar"
_, err2 := m.lookup(fn) _, err2 := m.lookup(fn)
if err2 == nil { if err2 == nil {
t.Errorf("No error on missing entry") t.Errorf("No error on missing entry")
+5 -4
View File
@@ -18,6 +18,7 @@ package router
import ( import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/platform9/fission"
) )
type HTTPTriggerSet struct { type HTTPTriggerSet struct {
@@ -25,11 +26,11 @@ type HTTPTriggerSet struct {
*mutableRouter *mutableRouter
controllerUrl string controllerUrl string
poolManagerUrl string poolManagerUrl string
triggers []httptrigger triggers []fission.HTTPTrigger
} }
func makeHTTPTriggerSet(fmap *functionServiceMap, controllerUrl string, poolManagerUrl string) *HTTPTriggerSet { func makeHTTPTriggerSet(fmap *functionServiceMap, controllerUrl string, poolManagerUrl string) *HTTPTriggerSet {
triggers := make([]httptrigger, 1) triggers := make([]fission.HTTPTrigger, 1)
return &HTTPTriggerSet{ return &HTTPTriggerSet{
functionServiceMap: fmap, functionServiceMap: fmap,
triggers: triggers, triggers: triggers,
@@ -49,10 +50,10 @@ func (triggers *HTTPTriggerSet) getRouterFromTriggers() *mux.Router {
for _, trigger := range triggers.triggers { for _, trigger := range triggers.triggers {
fh := &functionHandler{ fh := &functionHandler{
fmap: triggers.functionServiceMap, fmap: triggers.functionServiceMap,
function: trigger.function, Function: trigger.Function,
poolManagerUrl: triggers.poolManagerUrl, poolManagerUrl: triggers.poolManagerUrl,
} }
muxRouter.HandleFunc(trigger.urlPattern, fh.handler) muxRouter.HandleFunc(trigger.UrlPattern, fh.handler)
} }
return muxRouter return muxRouter
} }
+2 -12
View File
@@ -47,16 +47,6 @@ import (
) )
type ( type (
function struct {
name string
uid string
}
httptrigger struct {
urlPattern string
function
}
options struct { options struct {
port int port int
poolManagerUrl string poolManagerUrl string
@@ -65,9 +55,9 @@ type (
} }
) )
// request url ---[mux]---> function(name,uid) ----[fmap]----> k8s service url // request url ---[mux]---> Function(name,uid) ----[fmap]----> k8s service url
// request url ---[trigger]---> function(name, deployment) ----[deployment]----> function(name, uid) ----[pool mgr]---> k8s service url // request url ---[trigger]---> Function(name, deployment) ----[deployment]----> Function(name, uid) ----[pool mgr]---> k8s service url
func router(httpTriggerSet *HTTPTriggerSet) *mutableRouter { func router(httpTriggerSet *HTTPTriggerSet) *mutableRouter {
muxRouter := mux.NewRouter() muxRouter := mux.NewRouter()
+4 -2
View File
@@ -20,11 +20,13 @@ import (
"fmt" "fmt"
"testing" "testing"
"time" "time"
"github.com/platform9/fission"
) )
func TestRouter(t *testing.T) { func TestRouter(t *testing.T) {
fmap := makeFunctionServiceMap() fmap := makeFunctionServiceMap()
fn := &function{name: "foo", uid: "xxx"} fn := &fission.Function{Name: "foo", Uid: "xxx"}
testResponseString := "hi" testResponseString := "hi"
testServiceUrl := createBackendService(testResponseString) testServiceUrl := createBackendService(testResponseString)
@@ -33,7 +35,7 @@ func TestRouter(t *testing.T) {
triggers := makeHTTPTriggerSet(fmap, "", "") triggers := makeHTTPTriggerSet(fmap, "", "")
triggerUrl := "/foo" triggerUrl := "/foo"
triggers.triggers = append(triggers.triggers, httptrigger{triggerUrl, *fn}) triggers.triggers = append(triggers.triggers, fission.HTTPTrigger{triggerUrl, *fn})
port := 4242 port := 4242
go server(port, triggers) go server(port, triggers)
+29
View File
@@ -0,0 +1,29 @@
/*
Copyright 2016 The Fission Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fission
type (
Function struct {
Name string
Uid string
}
HTTPTrigger struct {
UrlPattern string
Function
}
)