General afrouter cleanup.
- Separated backend.go into multiple files.
- Replaced array indexing hack with enum pattern.
- Various renaming for better consistency.
- Removed a few unused structs.
- Replaced a thread with an atomic operation.
Change-Id: I2239692cac21ddb7f513b6d8c247ffa8789714ac
diff --git a/afrouter/afrouter/server.go b/afrouter/afrouter/server.go
index 0691da1..dff1519 100644
--- a/afrouter/afrouter/server.go
+++ b/afrouter/afrouter/server.go
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-// gRPC affinity router with active/active backends
package afrouter
@@ -24,7 +23,6 @@
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"net"
- "regexp"
"strconv"
)
@@ -35,38 +33,18 @@
}
)
-const (
- REQ_ALL = 0
- REQ_PACKAGE = 1
- REQ_SERVICE = 2
- REQ_METHOD = 3
-)
-
type server struct {
running bool
name string
- stype nbi
proxyListener net.Listener
routers map[string]map[string]Router
proxyServer *grpc.Server
}
-type nbRequest struct {
- srv interface{}
- serverStream grpc.ServerStream
- r Router
- mthdSlice []string
- metaKey string // There should be at most one key specified. More than one is an error.
- metaVal string // This is the value extracted from the meta key if it exists or "" otherwise
-}
-
-var mthdSlicerExp string = `^/([a-zA-Z][a-zA-Z0-9]+)\.([a-zA-Z][a-zA-Z0-9]+)/([a-zA-Z][a-zA-Z0-9]+)`
-var mthdSlicer *regexp.Regexp // The compiled regex to extract the package/service/method
-
func newServer(config *ServerConfig) (*server, error) {
var err error = nil
- var rtrn_err bool = false
- var srvr *server
+ var rtrn_err = false
+ var s *server
// Change over to the new configuration format
// Validate the configuration
// There should be a name
@@ -98,20 +76,20 @@
rtrn_err = true
}
- if rtrn_err == true {
+ if rtrn_err {
return nil, errors.New("Server configuration failed")
} else {
// The configuration is valid, create a server and configure it.
- srvr = &server{name: config.Name, routers: make(map[string]map[string]Router)}
+ s = &server{name: config.Name, routers: make(map[string]map[string]Router)}
// The listener
- if srvr.proxyListener, err =
+ if s.proxyListener, err =
net.Listen("tcp", config.Addr+":"+
strconv.Itoa(int(config.Port))); err != nil {
log.Error(err)
return nil, err
}
// Create the routers
- log.Debugf("Configuring the routers for server %s", srvr.name)
+ log.Debugf("Configuring the routers for server %s", s.name)
for p, r := range config.routers {
log.Debugf("Processing router %s for package %s", r.Name, p)
if dr, err := newRouter(r); err != nil {
@@ -119,25 +97,23 @@
return nil, err
} else {
log.Debugf("Adding router %s to the server %s for package %s and service %s",
- dr.Name(), srvr.name, p, dr.Service())
- if _, ok := srvr.routers[p]; ok {
- srvr.routers[p][dr.Service()] = dr
+ dr.Name(), s.name, p, dr.Service())
+ if _, ok := s.routers[p]; ok {
+ s.routers[p][dr.Service()] = dr
} else {
- srvr.routers[p] = make(map[string]Router)
- srvr.routers[p][dr.Service()] = dr
+ s.routers[p] = make(map[string]Router)
+ s.routers[p][dr.Service()] = dr
}
}
}
// Configure the grpc handler
- srvr.proxyServer = grpc.NewServer(
+ s.proxyServer = grpc.NewServer(
grpc.CustomCodec(Codec()),
- grpc.UnknownServiceHandler(srvr.TransparentHandler()),
+ grpc.UnknownServiceHandler(s.TransparentHandler()),
)
}
- // Compile the regular expression to extract the method
- mthdSlicer = regexp.MustCompile(mthdSlicerExp)
- return srvr, nil
+ return s, nil
}
func (s *server) Name() string {
@@ -148,12 +124,12 @@
return s.handler
}
-func (s *server) getRouter(pkg *string, service *string) (Router, bool) {
- if fn, ok := s.routers[*pkg][*service]; ok { // Both specified
+func (s *server) getRouter(pkg string, service string) (Router, bool) {
+ if fn, ok := s.routers[pkg][service]; ok { // Both specified
return fn, ok
- } else if fn, ok = s.routers["*"][*service]; ok { // Package wild card
+ } else if fn, ok = s.routers["*"][service]; ok { // Package wild card
return fn, ok
- } else if fn, ok = s.routers[*pkg]["*"]; ok { // Service wild card
+ } else if fn, ok = s.routers[pkg]["*"]; ok { // Service wild card
return fn, ok
} else if fn, ok = s.routers["*"]["*"]; ok { // Both Wildcarded
return fn, ok
@@ -169,23 +145,14 @@
return grpc.Errorf(codes.Internal, "lowLevelServerStream doesn't exist in context")
}
log.Debugf("Processing grpc request %s on server %s", fullMethodName, s.name)
- // The full method name is structured as follows:
- // <package name>.<service>/<method>
- mthdSlice := mthdSlicer.FindStringSubmatch(fullMethodName)
- if mthdSlice == nil {
- log.Errorf("Faled to slice full method %s, result: %v", fullMethodName, mthdSlice)
- } else {
- log.Debugf("Sliced full method %s: %v", fullMethodName, mthdSlice)
- }
- r, ok := s.getRouter(&mthdSlice[REQ_PACKAGE], &mthdSlice[REQ_SERVICE])
- //fn, ok := s.routers[mthdSlice[REQ_PACKAGE]][mthdSlice[REQ_SERVICE]]
+ methodInfo := newMethodDetails(fullMethodName)
+ r, ok := s.getRouter(methodInfo.pkg, methodInfo.service)
+ //fn, ok := s.routers[methodInfo.pkg][methodInfo.service]
if !ok {
// TODO: Should this be punted to a default transparent router??
// Probably not, if one is defined yes otherwise just crap out.
- err := errors.New(
- fmt.Sprintf("Unable to dispatch! Service '%s' for package '%s' not found.",
- mthdSlice[REQ_SERVICE], mthdSlice[REQ_PACKAGE]))
+ err := fmt.Errorf("Unable to dispatch! Service '%s' for package '%s' not found.", methodInfo.service, methodInfo.pkg)
log.Error(err)
return err
}
@@ -197,13 +164,13 @@
return err
}
- //nbR := &nbRequest(srv:srv,serverStream:serverStream,r:r,mthdSlice:mthdSlice,metaKey:mk,metaVal:mv)
+ //nbR := &nbRequest(srv:srv,serverStream:serverStream,r:r,methodInfo:methodInfo,metaKey:mk,metaVal:mv)
// Extract the cluster from the selected router and use it to manage the transfer
- if bkndClstr, err := r.BackendCluster(mthdSlice[REQ_METHOD], mk); err != nil {
+ if cluster, err := r.BackendCluster(methodInfo.method, mk); err != nil {
return err
} else {
- //return bkndClstr.handler(nbR)
- return bkndClstr.handler(srv, serverStream, r, mthdSlice, mk, mv)
+ //return beCluster.handler(nbR)
+ return cluster.handler(srv, serverStream, r, methodInfo, mk, mv)
}
}