vulcand icon indicating copy to clipboard operation
vulcand copied to clipboard

Multiple matching routes

Open bkeroackdsc opened this issue 9 years ago • 4 comments

After reading the documentation, I'm not clear on what would happen if an incoming request matches the routes associated with multiple frontends. Is it possible to set up some priority scheme among frontends?

The use case I'm thinking of is having one frontend with a set of path regexps and then having a second "fallback" frontend that matches everything else.

It's not clear from the docs how this might be accomplished.

bkeroackdsc avatar Jun 03 '15 19:06 bkeroackdsc

Yes, we had the same problem, and I made a small commit recently that allows you to set up a custom NotFound middleware upon startup.

My use-case was similar to yours, and I spent a lot of time thinking about specificity and priority. The problem for me was priorities change, are difficult to infer and difficult to manage. Specificity is worse still - looking at two regex's, it is very difficult, if not impossible, to define which one is more specific.

Since my use-case was WAY simpler, all I needed was a way to capture all unmatched requests and send them to one default route.

Here's a snippet we use - follow the middleware writing pattern:

func GetRegistry(nsqdendpoints []string, selfaddress string) (*plugin.Registry, error) { r := plugin.NewRegistry()

specs := []*plugin.MiddlewareSpec{

    connlimit.GetSpec(),

    ratelimit.GetSpec(),

    rewrite.GetSpec(),

    cbreaker.GetSpec(),

    trace.GetSpec(),
}

if notFoundMiddleware, err := custommiddleware.New(); err == nil {
    r.AddNotFoundMiddleware(notFoundMiddleware)
}

for _, spec := range specs {
    if err := r.AddSpec(spec); err != nil {
        return nil, err
    }
}
return r, nil

}

archisgore avatar Jun 03 '15 20:06 archisgore

@archisgore Thank you for that info. Looking at the source a bit, it's apparent that it simply executes the first matching route (stored in order of insertion). So we can prioritize (in a hackish way) by controlling the order of rule insertion.

It would be nice if this were documented somewhere ("Order of frontend insertion is significant"). It also would be great to have some additions to the routing language syntax: mailgun/route#8, mailgun/route#9.

bkeroackdsc avatar Jun 15 '15 21:06 bkeroackdsc

Yes, that's fair. Rather than add it to the routing language, I would prefer it if it were part of the frontend's structure that assigned each frontend a priority with an explicit contract that, two frontends with the same priority can be in arbitrary order.

Put concisely,

Each fronted struct will have:

type engine.Frontend struct { //some stuff priority int }

And on any frontend modification (upsert/delete), we do:

unstableSort(frontends)

About routing library, I'm going to open a new issue to discuss other ideas I have around it.

archisgore avatar Jun 23 '15 23:06 archisgore

I'm making this request in route: https://github.com/mailgun/route/pull/10

This is to allow us to rapidly run some trial-errors by plugging in variants of the routing library and test cases. Thanks to how go works, we can't easily fork vulcan/route/etc. and run it properly without replacing all import paths in thousands of files. By making it an interface, it'll allow me to work on various features like priorities, OR operator, and so forth.

archisgore avatar Jul 07 '15 21:07 archisgore