// Copyright 2020 Kentaro Hibino. All rights reserved.// Use of this source code is governed by a MIT license// that can be found in the LICENSE file.package asynqimport ()// ServeMux is a multiplexer for asynchronous tasks.// It matches the type of each task against a list of registered patterns// and calls the handler for the pattern that most closely matches the// task's type name.//// Longer patterns take precedence over shorter ones, so that if there are// handlers registered for both "images" and "images:thumbnails",// the latter handler will be called for tasks with a type name beginning with// "images:thumbnails" and the former will receive tasks with type name beginning// with "images".typeServeMuxstruct { mu sync.RWMutex m map[string]muxEntry es []muxEntry// slice of entries sorted from longest to shortest. mws []MiddlewareFunc}type muxEntry struct { h Handler pattern string}// MiddlewareFunc is a function which receives an asynq.Handler and returns another asynq.Handler.// Typically, the returned handler is a closure which does something with the context and task passed// to it, and then calls the handler passed as parameter to the MiddlewareFunc.typeMiddlewareFuncfunc(Handler) Handler// NewServeMux allocates and returns a new ServeMux.func () *ServeMux {returnnew(ServeMux)}// ProcessTask dispatches the task to the handler whose// pattern most closely matches the task type.func ( *ServeMux) ( context.Context, *Task) error { , := .Handler()return .ProcessTask(, )}// Handler returns the handler to use for the given task.// It always return a non-nil handler.//// Handler also returns the registered pattern that matches the task.//// If there is no registered handler that applies to the task,// handler returns a 'not found' handler which returns an error.func ( *ServeMux) ( *Task) ( Handler, string) { .mu.RLock()defer .mu.RUnlock() , = .match(.Type())if == nil { , = NotFoundHandler(), "" }for := len(.mws) - 1; >= 0; -- { = .mws[]() }return , }// Find a handler on a handler map given a typename string.// Most-specific (longest) pattern wins.func ( *ServeMux) ( string) ( Handler, string) {// Check for exact match first. , := .m[]if {return .h, .pattern }// Check for longest valid match. // mux.es contains all patterns from longest to shortest.for , := range .es {ifstrings.HasPrefix(, .pattern) {return .h, .pattern } }returnnil, ""}// Handle registers the handler for the given pattern.// If a handler already exists for pattern, Handle panics.func ( *ServeMux) ( string, Handler) { .mu.Lock()defer .mu.Unlock()ifstrings.TrimSpace() == "" {panic("asynq: invalid pattern") }if == nil {panic("asynq: nil handler") }if , := .m[]; {panic("asynq: multiple registrations for " + ) }if .m == nil { .m = make(map[string]muxEntry) } := muxEntry{h: , pattern: } .m[] = .es = appendSorted(.es, )}func appendSorted( []muxEntry, muxEntry) []muxEntry { := len() := sort.Search(, func( int) bool {returnlen([].pattern) < len(.pattern) })if == {returnappend(, ) }// we now know that i points at where we want to insert. = append(, muxEntry{}) // try to grow the slice in place, any entry works.copy([+1:], [:]) // shift shorter entries down. [] = return}// HandleFunc registers the handler function for the given pattern.func ( *ServeMux) ( string, func(context.Context, *Task) error) {if == nil {panic("asynq: nil handler") } .Handle(, HandlerFunc())}// Use appends a MiddlewareFunc to the chain.// Middlewares are executed in the order that they are applied to the ServeMux.func ( *ServeMux) ( ...MiddlewareFunc) { .mu.Lock()defer .mu.Unlock()for , := range { .mws = append(.mws, ) }}// NotFound returns an error indicating that the handler was not found for the given task.func ( context.Context, *Task) error {returnfmt.Errorf("handler not found for task %q", .Type())}// NotFoundHandler returns a simple task handler that returns a ``not found`` error.func () Handler { returnHandlerFunc(NotFound) }
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.