Skip to content

[RFC] remove handler func support #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
os:
- linux
- osx

language: go

go:
- 1.7.1
- 1.9.x

install: true
before_install:
- make deps

script:
- make deps
- gx-go rewrite
- go get github.com/mattn/goveralls
- goveralls -service=travis-ci
- bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh)

cache:
directories:
- $GOPATH/src/gx

notifications:
email: false

env: GOTFLAGS="-race"
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
gx:
go get -u github.com/whyrusleeping/gx
go get -u github.com/whyrusleeping/gx-go
go get github.com/whyrusleeping/gx
go get github.com/whyrusleeping/gx-go

deps: gx
gx --verbose install --global
gx-go rewrite

publish:
gx-go rewrite --undo

81 changes: 19 additions & 62 deletions multistream.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,16 @@ const ProtocolID = "/multistream/1.0.0"
// handle a protocol/stream.
type HandlerFunc func(protocol string, rwc io.ReadWriteCloser) error

// Handler is a wrapper to HandlerFunc which attaches a name (protocol) and a
// match function which can optionally be used to select a handler by other
// means than the name.
type Handler struct {
MatchFunc func(string) bool
Handle HandlerFunc
AddName string
}

// MultistreamMuxer is a muxer for multistream. Depending on the stream
// protocol tag it will select the right handler and hand the stream off to it.
type MultistreamMuxer struct {
handlerlock sync.Mutex
handlers []Handler
handlers map[string]HandlerFunc
}

// NewMultistreamMuxer creates a muxer.
func NewMultistreamMuxer() *MultistreamMuxer {
return new(MultistreamMuxer)
return &MultistreamMuxer{handlers: make(map[string]HandlerFunc)}
}

func writeUvarint(w io.Writer, i uint64) error {
Expand Down Expand Up @@ -107,54 +98,26 @@ func Ls(rw io.ReadWriter) ([]string, error) {
return out, nil
}

func fulltextMatch(s string) func(string) bool {
return func(a string) bool {
return a == s
}
}

// AddHandler attaches a new protocol handler to the muxer.
func (msm *MultistreamMuxer) AddHandler(protocol string, handler HandlerFunc) {
msm.AddHandlerWithFunc(protocol, fulltextMatch(protocol), handler)
}

// AddHandlerWithFunc attaches a new protocol handler to the muxer with a match.
// If the match function returns true for a given protocol tag, the protocol
// will be selected even if the handler name and protocol tags are different.
func (msm *MultistreamMuxer) AddHandlerWithFunc(protocol string, match func(string) bool, handler HandlerFunc) {
msm.handlerlock.Lock()
msm.removeHandler(protocol)
msm.handlers = append(msm.handlers, Handler{
MatchFunc: fulltextMatch(protocol),
Handle: handler,
AddName: protocol,
})
msm.handlers[protocol] = handler
msm.handlerlock.Unlock()
}

// RemoveHandler removes the handler with the given name from the muxer.
// RemoveHandler removes the protocol handler from the muxer.
func (msm *MultistreamMuxer) RemoveHandler(protocol string) {
msm.handlerlock.Lock()
defer msm.handlerlock.Unlock()

msm.removeHandler(protocol)
}

func (msm *MultistreamMuxer) removeHandler(protocol string) {
for i, h := range msm.handlers {
if h.AddName == protocol {
msm.handlers = append(msm.handlers[:i], msm.handlers[i+1:]...)
return
}
}
delete(msm.handlers, protocol)
msm.handlerlock.Unlock()
}

// Protocols returns the list of handler-names added to this this muxer.
func (msm *MultistreamMuxer) Protocols() []string {
var out []string
msm.handlerlock.Lock()
for _, h := range msm.handlers {
out = append(out, h.AddName)
for k := range msm.handlers {
out = append(out, k)
}
msm.handlerlock.Unlock()
return out
Expand All @@ -164,17 +127,11 @@ func (msm *MultistreamMuxer) Protocols() []string {
// fails because of a ProtocolID mismatch.
var ErrIncorrectVersion = errors.New("client connected with incorrect version")

func (msm *MultistreamMuxer) findHandler(proto string) *Handler {
func (msm *MultistreamMuxer) findHandler(proto string) (HandlerFunc, bool) {
msm.handlerlock.Lock()
defer msm.handlerlock.Unlock()

for _, h := range msm.handlers {
if h.MatchFunc(proto) {
return &h
}
}

return nil
f, ok := msm.handlers[proto]
return f, ok
}

// NegotiateLazy performs protocol selection and returns
Expand Down Expand Up @@ -243,8 +200,8 @@ loop:
return nil, "", nil, err
}
default:
h := msm.findHandler(tok)
if h == nil {
h, ok := msm.findHandler(tok)
if !ok {
select {
case pval <- "na":
case err := <-writeErr:
Expand All @@ -262,7 +219,7 @@ loop:
}

// hand off processing to the sub-protocol handler
return lzc, tok, h.Handle, nil
return lzc, tok, h, nil
}
}
}
Expand Down Expand Up @@ -301,8 +258,8 @@ loop:
return "", nil, err
}
default:
h := msm.findHandler(tok)
if h == nil {
h, ok := msm.findHandler(tok)
if !ok {
err := delimWriteBuffered(rwc, []byte("na"))
if err != nil {
return "", nil, err
Expand All @@ -316,7 +273,7 @@ loop:
}

// hand off processing to the sub-protocol handler
return tok, h.Handle, nil
return tok, h, nil
}
}

Expand All @@ -332,8 +289,8 @@ func (msm *MultistreamMuxer) Ls(w io.Writer) error {
return err
}

for _, h := range msm.handlers {
err := delimWrite(buf, []byte(h.AddName))
for k := range msm.handlers {
err := delimWrite(buf, []byte(k))
if err != nil {
msm.handlerlock.Unlock()
return err
Expand Down