From ed5b846d82ce4e248384012fa57a94d29b4817ea Mon Sep 17 00:00:00 2001 From: Alex Lobunets Date: Tue, 18 Nov 2014 22:22:59 +0100 Subject: [PATCH] Revert 69dc796..524d050 This rolls back to commit 69dc796aadcb965bfcb734f656610b5edd2a6864. --- Godeps/Godeps.json | 36 - Godeps/Readme | 5 - Godeps/_workspace/.gitignore | 2 - .../src/github.com/bmizerany/pat/.gitignore | 3 - .../src/github.com/bmizerany/pat/README.md | 68 - .../github.com/bmizerany/pat/bench_test.go | 20 - .../github.com/bmizerany/pat/example/hello.go | 27 - .../pat/example/patexample/hello_appengine.go | 29 - .../src/github.com/bmizerany/pat/mux.go | 270 -- .../src/github.com/bmizerany/pat/mux_test.go | 241 -- .../github.com/codegangsta/cli/.travis.yml | 6 - .../src/github.com/codegangsta/cli/LICENSE | 21 - .../src/github.com/codegangsta/cli/README.md | 287 -- .../src/github.com/codegangsta/cli/app.go | 246 -- .../github.com/codegangsta/cli/app_test.go | 423 --- .../cli/autocomplete/bash_autocomplete | 13 - .../cli/autocomplete/zsh_autocomplete | 5 - .../src/github.com/codegangsta/cli/cli.go | 19 - .../github.com/codegangsta/cli/cli_test.go | 100 - .../src/github.com/codegangsta/cli/command.go | 144 - .../codegangsta/cli/command_test.go | 49 - .../src/github.com/codegangsta/cli/context.go | 315 -- .../codegangsta/cli/context_test.go | 77 - .../src/github.com/codegangsta/cli/flag.go | 410 --- .../github.com/codegangsta/cli/flag_test.go | 587 ---- .../src/github.com/codegangsta/cli/help.go | 224 -- .../codegangsta/cli/helpers_test.go | 19 - .../daviddengcn/go-colortext/.gitignore | 22 - .../daviddengcn/go-colortext/README.md | 17 - .../github.com/daviddengcn/go-colortext/ct.go | 37 - .../daviddengcn/go-colortext/ct_ansi.go | 35 - .../daviddengcn/go-colortext/ct_test.go | 26 - .../daviddengcn/go-colortext/ct_win.go | 139 - .../src/github.com/howeyc/fsnotify/.gitignore | 5 - .../src/github.com/howeyc/fsnotify/AUTHORS | 28 - .../github.com/howeyc/fsnotify/CHANGELOG.md | 160 - .../howeyc/fsnotify/CONTRIBUTING.md | 7 - .../src/github.com/howeyc/fsnotify/LICENSE | 28 - .../src/github.com/howeyc/fsnotify/README.md | 92 - .../howeyc/fsnotify/example_test.go | 34 - .../github.com/howeyc/fsnotify/fsnotify.go | 111 - .../howeyc/fsnotify/fsnotify_bsd.go | 496 --- .../howeyc/fsnotify/fsnotify_linux.go | 304 -- .../howeyc/fsnotify/fsnotify_open_bsd.go | 11 - .../howeyc/fsnotify/fsnotify_open_darwin.go | 11 - .../howeyc/fsnotify/fsnotify_symlink_test.go | 74 - .../howeyc/fsnotify/fsnotify_test.go | 1010 ------ .../howeyc/fsnotify/fsnotify_windows.go | 598 ---- .../src/github.com/oleksandr/fbp/LICENSE | 21 - .../src/github.com/oleksandr/fbp/README.md | 55 - .../src/github.com/oleksandr/fbp/grammar.peg | 86 - .../github.com/oleksandr/fbp/grammar.peg.go | 2844 ----------------- .../src/github.com/oleksandr/fbp/parser.go | 267 -- .../github.com/oleksandr/fbp/parser_test.go | 162 - .../src/github.com/pebbe/zmq4/LICENSE.txt | 25 - .../src/github.com/pebbe/zmq4/README.md | 58 - .../src/github.com/pebbe/zmq4/auth.go | 592 ---- .../src/github.com/pebbe/zmq4/auth_test.go | 117 - .../src/github.com/pebbe/zmq4/doc.go | 20 - .../src/github.com/pebbe/zmq4/errors.go | 92 - .../github.com/pebbe/zmq4/examples/Build.sh | 69 - .../github.com/pebbe/zmq4/examples/README.md | 2 - .../pebbe/zmq4/examples/asyncsrv.go | 138 - .../pebbe/zmq4/examples/bstar/bstar.go | 275 -- .../pebbe/zmq4/examples/bstarcli.go | 83 - .../pebbe/zmq4/examples/bstarsrv.go | 194 -- .../pebbe/zmq4/examples/bstarsrv2.go | 43 - .../pebbe/zmq4/examples/clone/clone.go | 304 -- .../pebbe/zmq4/examples/clonecli1.go | 31 - .../pebbe/zmq4/examples/clonecli2.go | 70 - .../pebbe/zmq4/examples/clonecli3.go | 83 - .../pebbe/zmq4/examples/clonecli4.go | 84 - .../pebbe/zmq4/examples/clonecli5.go | 85 - .../pebbe/zmq4/examples/clonecli6.go | 41 - .../pebbe/zmq4/examples/clonesrv1.go | 38 - .../pebbe/zmq4/examples/clonesrv2.go | 119 - .../pebbe/zmq4/examples/clonesrv3.go | 84 - .../pebbe/zmq4/examples/clonesrv4.go | 91 - .../pebbe/zmq4/examples/clonesrv5.go | 152 - .../pebbe/zmq4/examples/clonesrv6.go | 336 -- .../github.com/pebbe/zmq4/examples/eagain.go | 28 - .../pebbe/zmq4/examples/espresso.go | 89 - .../github.com/pebbe/zmq4/examples/fileio1.go | 98 - .../github.com/pebbe/zmq4/examples/fileio2.go | 98 - .../github.com/pebbe/zmq4/examples/fileio3.go | 111 - .../pebbe/zmq4/examples/flcliapi/flcliapi.go | 268 -- .../pebbe/zmq4/examples/flclient1.go | 77 - .../pebbe/zmq4/examples/flclient2.go | 118 - .../pebbe/zmq4/examples/flclient3.go | 35 - .../pebbe/zmq4/examples/flserver1.go | 32 - .../pebbe/zmq4/examples/flserver2.go | 39 - .../pebbe/zmq4/examples/flserver3.go | 57 - .../pebbe/zmq4/examples/hwclient.go | 32 - .../pebbe/zmq4/examples/hwserver.go | 34 - .../pebbe/zmq4/examples/identity.go | 62 - .../pebbe/zmq4/examples/interrupt.go | 57 - .../pebbe/zmq4/examples/intface/intface.go | 254 -- .../pebbe/zmq4/examples/kvmsg/kvmsg.go | 262 -- .../pebbe/zmq4/examples/kvmsg/kvmsg_test.go | 108 - .../pebbe/zmq4/examples/kvsimple/kvsimple.go | 157 - .../zmq4/examples/kvsimple/kvsimple_test.go | 64 - .../pebbe/zmq4/examples/lbbroker.go | 188 -- .../pebbe/zmq4/examples/lbbroker2.go | 147 - .../pebbe/zmq4/examples/lbbroker3.go | 157 - .../pebbe/zmq4/examples/lpclient.go | 88 - .../pebbe/zmq4/examples/lpserver.go | 42 - .../github.com/pebbe/zmq4/examples/lvcache.go | 69 - .../pebbe/zmq4/examples/mdapi/const.go | 30 - .../pebbe/zmq4/examples/mdapi/mdcliapi.go | 173 - .../pebbe/zmq4/examples/mdapi/mdcliapi2.go | 171 - .../pebbe/zmq4/examples/mdapi/mdwrkapi.go | 248 -- .../pebbe/zmq4/examples/mdbroker.go | 426 --- .../pebbe/zmq4/examples/mdclient.go | 32 - .../pebbe/zmq4/examples/mdclient2.go | 39 - .../pebbe/zmq4/examples/mdworker.go | 32 - .../github.com/pebbe/zmq4/examples/mmiecho.go | 32 - .../pebbe/zmq4/examples/msgqueue.go | 36 - .../pebbe/zmq4/examples/mspoller.go | 47 - .../pebbe/zmq4/examples/msreader.go | 55 - .../github.com/pebbe/zmq4/examples/mtrelay.go | 52 - .../pebbe/zmq4/examples/mtserver.go | 54 - .../pebbe/zmq4/examples/pathopub.go | 44 - .../pebbe/zmq4/examples/pathosub.go | 41 - .../pebbe/zmq4/examples/peering1.go | 66 - .../pebbe/zmq4/examples/peering2.go | 264 -- .../pebbe/zmq4/examples/peering3.go | 335 -- .../github.com/pebbe/zmq4/examples/ppqueue.go | 166 - .../pebbe/zmq4/examples/ppworker.go | 130 - .../pebbe/zmq4/examples/psenvpub.go | 27 - .../pebbe/zmq4/examples/psenvsub.go | 27 - .../pebbe/zmq4/examples/rrbroker.go | 53 - .../pebbe/zmq4/examples/rrclient.go | 25 - .../pebbe/zmq4/examples/rrworker.go | 33 - .../pebbe/zmq4/examples/rtdealer.go | 84 - .../github.com/pebbe/zmq4/examples/rtreq.go | 82 - .../github.com/pebbe/zmq4/examples/spqueue.go | 88 - .../pebbe/zmq4/examples/spworker.go | 55 - .../pebbe/zmq4/examples/suisnail.go | 83 - .../github.com/pebbe/zmq4/examples/sync.sh | 12 - .../github.com/pebbe/zmq4/examples/syncpub.go | 57 - .../github.com/pebbe/zmq4/examples/syncsub.go | 51 - .../pebbe/zmq4/examples/tasksink.go | 40 - .../pebbe/zmq4/examples/tasksink2.go | 48 - .../pebbe/zmq4/examples/taskvent.go | 51 - .../pebbe/zmq4/examples/taskwork.go | 44 - .../pebbe/zmq4/examples/taskwork2.go | 62 - .../pebbe/zmq4/examples/ticlient.go | 81 - .../github.com/pebbe/zmq4/examples/titanic.go | 235 -- .../pebbe/zmq4/examples/tripping.go | 82 - .../pebbe/zmq4/examples/udpping1.go | 103 - .../pebbe/zmq4/examples/udpping2.go | 62 - .../pebbe/zmq4/examples/udpping3.go | 25 - .../github.com/pebbe/zmq4/examples/version.go | 16 - .../pebbe/zmq4/examples/wuclient.go | 46 - .../github.com/pebbe/zmq4/examples/wuproxy.go | 29 - .../pebbe/zmq4/examples/wuserver.go | 40 - .../pebbe/zmq4/examples_security/Makefile | 5 - .../pebbe/zmq4/examples_security/README.md | 10 - .../zmq4/examples_security/grasslands.go | 49 - .../pebbe/zmq4/examples_security/ironhouse.go | 69 - .../zmq4/examples_security/stonehouse.go | 70 - .../zmq4/examples_security/strawhouse.go | 65 - .../pebbe/zmq4/examples_security/woodhouse.go | 62 - .../src/github.com/pebbe/zmq4/polling.go | 119 - .../src/github.com/pebbe/zmq4/reactor.go | 194 -- .../src/github.com/pebbe/zmq4/socketget.go | 360 --- .../github.com/pebbe/zmq4/socketget_unix.go | 15 - .../pebbe/zmq4/socketget_windows.go | 26 - .../src/github.com/pebbe/zmq4/socketset.go | 380 --- .../src/github.com/pebbe/zmq4/utils.go | 183 -- .../src/github.com/pebbe/zmq4/zmq4.go | 896 ------ .../src/github.com/pebbe/zmq4/zmq4_test.go | 1897 ----------- cmd/cascades/library.go | 2 +- cmd/cascades/main.go | 2 +- cmd/cascades/run.go | 4 +- cmd/cascades/serve.go | 2 +- components/core/console/main.go | 2 +- components/core/delay/main.go | 2 +- components/core/drop/main.go | 2 +- components/core/exec/main.go | 2 +- components/core/joiner/main.go | 2 +- components/core/passthru/main.go | 2 +- components/core/readfile/main.go | 2 +- components/core/splitter/main.go | 2 +- components/core/submatch/main.go | 2 +- components/core/switch/main.go | 2 +- components/core/template/main.go | 2 +- components/core/ticker/main.go | 2 +- components/debug/crasher/main.go | 2 +- components/debug/oneshot/main.go | 2 +- components/fs/walk/main.go | 2 +- components/fs/watchdog/main.go | 4 +- components/utils/zmq.go | 2 +- 193 files changed, 23 insertions(+), 24860 deletions(-) delete mode 100644 Godeps/Godeps.json delete mode 100644 Godeps/Readme delete mode 100644 Godeps/_workspace/.gitignore delete mode 100644 Godeps/_workspace/src/github.com/bmizerany/pat/.gitignore delete mode 100644 Godeps/_workspace/src/github.com/bmizerany/pat/README.md delete mode 100644 Godeps/_workspace/src/github.com/bmizerany/pat/bench_test.go delete mode 100644 Godeps/_workspace/src/github.com/bmizerany/pat/example/hello.go delete mode 100644 Godeps/_workspace/src/github.com/bmizerany/pat/example/patexample/hello_appengine.go delete mode 100644 Godeps/_workspace/src/github.com/bmizerany/pat/mux.go delete mode 100644 Godeps/_workspace/src/github.com/bmizerany/pat/mux_test.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/README.md delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/app.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/cli.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/command.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/context.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/flag.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/help.go delete mode 100644 Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go delete mode 100644 Godeps/_workspace/src/github.com/daviddengcn/go-colortext/.gitignore delete mode 100644 Godeps/_workspace/src/github.com/daviddengcn/go-colortext/README.md delete mode 100644 Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct.go delete mode 100644 Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_ansi.go delete mode 100644 Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_test.go delete mode 100644 Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_win.go delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/.gitignore delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/AUTHORS delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/CHANGELOG.md delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/CONTRIBUTING.md delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/LICENSE delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/README.md delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/example_test.go delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify.go delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_bsd.go delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_linux.go delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_open_bsd.go delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_open_darwin.go delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_symlink_test.go delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_test.go delete mode 100644 Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_windows.go delete mode 100644 Godeps/_workspace/src/github.com/oleksandr/fbp/LICENSE delete mode 100644 Godeps/_workspace/src/github.com/oleksandr/fbp/README.md delete mode 100644 Godeps/_workspace/src/github.com/oleksandr/fbp/grammar.peg delete mode 100644 Godeps/_workspace/src/github.com/oleksandr/fbp/grammar.peg.go delete mode 100644 Godeps/_workspace/src/github.com/oleksandr/fbp/parser.go delete mode 100644 Godeps/_workspace/src/github.com/oleksandr/fbp/parser_test.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/LICENSE.txt delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/README.md delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/auth.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/auth_test.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/doc.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/errors.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/Build.sh delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/README.md delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/asyncsrv.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstar/bstar.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarcli.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarsrv.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarsrv2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clone/clone.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli1.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli3.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli4.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli5.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli6.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv1.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv3.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv4.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv5.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv6.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/eagain.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/espresso.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio1.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio3.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flcliapi/flcliapi.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient1.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient3.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver1.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver3.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/hwclient.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/hwserver.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/identity.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/interrupt.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/intface/intface.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg/kvmsg.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg/kvmsg_test.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple/kvsimple.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple/kvsimple_test.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker3.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lpclient.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lpserver.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lvcache.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/const.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdcliapi.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdcliapi2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdwrkapi.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdbroker.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdclient.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdclient2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdworker.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mmiecho.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/msgqueue.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mspoller.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/msreader.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mtrelay.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mtserver.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/pathopub.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/pathosub.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering1.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering3.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ppqueue.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ppworker.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/psenvpub.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/psenvsub.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrbroker.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrclient.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrworker.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rtdealer.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rtreq.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/spqueue.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/spworker.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/suisnail.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/sync.sh delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/syncpub.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/syncsub.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tasksink.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tasksink2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskvent.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskwork.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskwork2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ticlient.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/titanic.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tripping.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping1.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping2.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping3.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/version.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuclient.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuproxy.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuserver.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/Makefile delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/README.md delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/grasslands.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/ironhouse.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/stonehouse.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/strawhouse.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/woodhouse.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/polling.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/reactor.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/socketget.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/socketget_unix.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/socketget_windows.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/socketset.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/utils.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/zmq4.go delete mode 100644 Godeps/_workspace/src/github.com/pebbe/zmq4/zmq4_test.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json deleted file mode 100644 index 4906c15..0000000 --- a/Godeps/Godeps.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "ImportPath": "github.com/cascades-fbp/cascades", - "GoVersion": "go1.3.3", - "Packages": [ - "github.com/cascades-fbp/cascades/cmd/...", - "github.com/cascades-fbp/cascades/components/..." - ], - "Deps": [ - { - "ImportPath": "github.com/bmizerany/pat", - "Rev": "b8a35001b773c267eb260a691f4e5499a3531600" - }, - { - "ImportPath": "github.com/codegangsta/cli", - "Comment": "1.2.0-26-gf7ebb76", - "Rev": "f7ebb761e83e21225d1d8954fde853bf8edd46c4" - }, - { - "ImportPath": "github.com/daviddengcn/go-colortext", - "Rev": "b5c0891944c2f150ccc9d02aecf51b76c14c2948" - }, - { - "ImportPath": "github.com/howeyc/fsnotify", - "Comment": "v0.9.0-11-g6b1ef89", - "Rev": "6b1ef893dc11e0447abda6da20a5203481878dda" - }, - { - "ImportPath": "github.com/oleksandr/fbp", - "Rev": "2781cd78c431ead1956f994e322285f746338c44" - }, - { - "ImportPath": "github.com/pebbe/zmq4", - "Rev": "31dba2dadf451d949a4169b7dfe24f18ac903c4e" - } - ] -} diff --git a/Godeps/Readme b/Godeps/Readme deleted file mode 100644 index 4cdaa53..0000000 --- a/Godeps/Readme +++ /dev/null @@ -1,5 +0,0 @@ -This directory tree is generated automatically by godep. - -Please do not edit. - -See https://github.com/tools/godep for more information. diff --git a/Godeps/_workspace/.gitignore b/Godeps/_workspace/.gitignore deleted file mode 100644 index f037d68..0000000 --- a/Godeps/_workspace/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/pkg -/bin diff --git a/Godeps/_workspace/src/github.com/bmizerany/pat/.gitignore b/Godeps/_workspace/src/github.com/bmizerany/pat/.gitignore deleted file mode 100644 index 72f13bd..0000000 --- a/Godeps/_workspace/src/github.com/bmizerany/pat/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.prof -*.out -example/example diff --git a/Godeps/_workspace/src/github.com/bmizerany/pat/README.md b/Godeps/_workspace/src/github.com/bmizerany/pat/README.md deleted file mode 100644 index 732acbc..0000000 --- a/Godeps/_workspace/src/github.com/bmizerany/pat/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# pat (formerly pat.go) - A Sinatra style pattern muxer for Go's net/http library - -## INSTALL - - $ go get github.com/bmizerany/pat - -## USE - - package main - - import ( - "io" - "net/http" - "github.com/bmizerany/pat" - "log" - ) - - // hello world, the web server - func HelloServer(w http.ResponseWriter, req *http.Request) { - io.WriteString(w, "hello, "+req.URL.Query().Get(":name")+"!\n") - } - - func main() { - m := pat.New() - m.Get("/hello/:name", http.HandlerFunc(HelloServer)) - - // Register this pat with the default serve mux so that other packages - // may also be exported. (i.e. /debug/pprof/*) - http.Handle("/", m) - err := http.ListenAndServe(":12345", nil) - if err != nil { - log.Fatal("ListenAndServe: ", err) - } - } - -It's that simple. - -For more information, see: -http://godoc.org/github.com/bmizerany/pat - -## CONTRIBUTORS - -* Keith Rarick (@krarick) - github.com/kr -* Blake Mizerany (@bmizerany) - github.com/bmizerany -* Evan Shaw -* George Rogers - -## LICENSE - -Copyright (C) 2012 by Keith Rarick, Blake Mizerany - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/bmizerany/pat/bench_test.go b/Godeps/_workspace/src/github.com/bmizerany/pat/bench_test.go deleted file mode 100644 index a36f429..0000000 --- a/Godeps/_workspace/src/github.com/bmizerany/pat/bench_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package pat - -import ( - "net/http" - "testing" -) - -func BenchmarkPatternMatching(b *testing.B) { - p := New() - p.Get("/hello/:name", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) - for n := 0; n < b.N; n++ { - b.StopTimer() - r, err := http.NewRequest("GET", "/hello/blake", nil) - if err != nil { - panic(err) - } - b.StartTimer() - p.ServeHTTP(nil, r) - } -} diff --git a/Godeps/_workspace/src/github.com/bmizerany/pat/example/hello.go b/Godeps/_workspace/src/github.com/bmizerany/pat/example/hello.go deleted file mode 100644 index 1a67936..0000000 --- a/Godeps/_workspace/src/github.com/bmizerany/pat/example/hello.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "io" - "log" - "net/http" - - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/bmizerany/pat" -) - -// hello world, the web server -func HelloServer(w http.ResponseWriter, req *http.Request) { - io.WriteString(w, "hello, "+req.URL.Query().Get(":name")+"!\n") -} - -func main() { - m := pat.New() - m.Get("/hello/:name", http.HandlerFunc(HelloServer)) - - // Register this pat with the default serve mux so that other packages - // may also be exported. (i.e. /debug/pprof/*) - http.Handle("/", m) - err := http.ListenAndServe(":12345", nil) - if err != nil { - log.Fatal("ListenAndServe: ", err) - } -} diff --git a/Godeps/_workspace/src/github.com/bmizerany/pat/example/patexample/hello_appengine.go b/Godeps/_workspace/src/github.com/bmizerany/pat/example/patexample/hello_appengine.go deleted file mode 100644 index db72feb..0000000 --- a/Godeps/_workspace/src/github.com/bmizerany/pat/example/patexample/hello_appengine.go +++ /dev/null @@ -1,29 +0,0 @@ -// hello.go ported for appengine -// -// this differs from the standard hello.go example in two ways: appengine -// already provides an http server for you, obviating the need for the -// ListenAndServe call (with associated logging), and the package must not be -// called main (appengine reserves package 'main' for the underlying program). - -package patexample - -import ( - "io" - "net/http" - - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/bmizerany/pat" -) - -// hello world, the web server -func HelloServer(w http.ResponseWriter, req *http.Request) { - io.WriteString(w, "hello, "+req.URL.Query().Get(":name")+"!\n") -} - -func init() { - m := pat.New() - m.Get("/hello/:name", http.HandlerFunc(HelloServer)) - - // Register this pat with the default serve mux so that other packages - // may also be exported. (i.e. /debug/pprof/*) - http.Handle("/", m) -} diff --git a/Godeps/_workspace/src/github.com/bmizerany/pat/mux.go b/Godeps/_workspace/src/github.com/bmizerany/pat/mux.go deleted file mode 100644 index dd4452c..0000000 --- a/Godeps/_workspace/src/github.com/bmizerany/pat/mux.go +++ /dev/null @@ -1,270 +0,0 @@ -// Package pat implements a simple URL pattern muxer -package pat - -import ( - "net/http" - "net/url" - "strings" -) - -// PatternServeMux is an HTTP request multiplexer. It matches the URL of each -// incoming request against a list of registered patterns with their associated -// methods and calls the handler for the pattern that most closely matches the -// URL. -// -// Pattern matching attempts each pattern in the order in which they were -// registered. -// -// Patterns may contain literals or captures. Capture names start with a colon -// and consist of letters A-Z, a-z, _, and 0-9. The rest of the pattern -// matches literally. The portion of the URL matching each name ends with an -// occurrence of the character in the pattern immediately following the name, -// or a /, whichever comes first. It is possible for a name to match the empty -// string. -// -// Example pattern with one capture: -// /hello/:name -// Will match: -// /hello/blake -// /hello/keith -// Will not match: -// /hello/blake/ -// /hello/blake/foo -// /foo -// /foo/bar -// -// Example 2: -// /hello/:name/ -// Will match: -// /hello/blake/ -// /hello/keith/foo -// /hello/blake -// /hello/keith -// Will not match: -// /foo -// /foo/bar -// -// A pattern ending with a slash will get an implicit redirect to it's -// non-slash version. For example: Get("/foo/", handler) will implicitly -// register Get("/foo", handler). You may override it by registering -// Get("/foo", anotherhandler) before the slash version. -// -// Retrieve the capture from the r.URL.Query().Get(":name") in a handler (note -// the colon). If a capture name appears more than once, the additional values -// are appended to the previous values (see -// http://golang.org/pkg/net/url/#Values) -// -// A trivial example server is: -// -// package main -// -// import ( -// "io" -// "net/http" -// "github.com/bmizerany/pat" -// "log" -// ) -// -// // hello world, the web server -// func HelloServer(w http.ResponseWriter, req *http.Request) { -// io.WriteString(w, "hello, "+req.URL.Query().Get(":name")+"!\n") -// } -// -// func main() { -// m := pat.New() -// m.Get("/hello/:name", http.HandlerFunc(HelloServer)) -// -// // Register this pat with the default serve mux so that other packages -// // may also be exported. (i.e. /debug/pprof/*) -// http.Handle("/", m) -// err := http.ListenAndServe(":12345", nil) -// if err != nil { -// log.Fatal("ListenAndServe: ", err) -// } -// } -// -// When "Method Not Allowed": -// -// Pat knows what methods are allowed given a pattern and a URI. For -// convenience, PatternServeMux will add the Allow header for requests that -// match a pattern for a method other than the method requested and set the -// Status to "405 Method Not Allowed". -type PatternServeMux struct { - handlers map[string][]*patHandler -} - -// New returns a new PatternServeMux. -func New() *PatternServeMux { - return &PatternServeMux{make(map[string][]*patHandler)} -} - -// ServeHTTP matches r.URL.Path against its routing table using the rules -// described above. -func (p *PatternServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { - for _, ph := range p.handlers[r.Method] { - if params, ok := ph.try(r.URL.Path); ok { - if len(params) > 0 { - r.URL.RawQuery = url.Values(params).Encode() + "&" + r.URL.RawQuery - } - ph.ServeHTTP(w, r) - return - } - } - - allowed := make([]string, 0, len(p.handlers)) - for meth, handlers := range p.handlers { - if meth == r.Method { - continue - } - - for _, ph := range handlers { - if _, ok := ph.try(r.URL.Path); ok { - allowed = append(allowed, meth) - } - } - } - - if len(allowed) == 0 { - http.NotFound(w, r) - return - } - - w.Header().Add("Allow", strings.Join(allowed, ", ")) - http.Error(w, "Method Not Allowed", 405) -} - -// Head will register a pattern with a handler for HEAD requests. -func (p *PatternServeMux) Head(pat string, h http.Handler) { - p.Add("HEAD", pat, h) -} - -// Get will register a pattern with a handler for GET requests. -// It also registers pat for HEAD requests. If this needs to be overridden, use -// Head before Get with pat. -func (p *PatternServeMux) Get(pat string, h http.Handler) { - p.Add("HEAD", pat, h) - p.Add("GET", pat, h) -} - -// Post will register a pattern with a handler for POST requests. -func (p *PatternServeMux) Post(pat string, h http.Handler) { - p.Add("POST", pat, h) -} - -// Put will register a pattern with a handler for PUT requests. -func (p *PatternServeMux) Put(pat string, h http.Handler) { - p.Add("PUT", pat, h) -} - -// Del will register a pattern with a handler for DELETE requests. -func (p *PatternServeMux) Del(pat string, h http.Handler) { - p.Add("DELETE", pat, h) -} - -// Options will register a pattern with a handler for OPTIONS requests. -func (p *PatternServeMux) Options(pat string, h http.Handler) { - p.Add("OPTIONS", pat, h) -} - -// Add will register a pattern with a handler for meth requests. -func (p *PatternServeMux) Add(meth, pat string, h http.Handler) { - p.handlers[meth] = append(p.handlers[meth], &patHandler{pat, h}) - - n := len(pat) - if n > 0 && pat[n-1] == '/' { - p.Add(meth, pat[:n-1], http.RedirectHandler(pat, http.StatusMovedPermanently)) - } -} - -// Tail returns the trailing string in path after the final slash for a pat ending with a slash. -// -// Examples: -// -// Tail("/hello/:title/", "/hello/mr/mizerany") == "mizerany" -// Tail("/:a/", "/x/y/z") == "y/z" -// -func Tail(pat, path string) string { - var i, j int - for i < len(path) { - switch { - case j >= len(pat): - if pat[len(pat)-1] == '/' { - return path[i:] - } - return "" - case pat[j] == ':': - var nextc byte - _, nextc, j = match(pat, isAlnum, j+1) - _, _, i = match(path, matchPart(nextc), i) - case path[i] == pat[j]: - i++ - j++ - default: - return "" - } - } - return "" -} - -type patHandler struct { - pat string - http.Handler -} - -func (ph *patHandler) try(path string) (url.Values, bool) { - p := make(url.Values) - var i, j int - for i < len(path) { - switch { - case j >= len(ph.pat): - if ph.pat != "/" && len(ph.pat) > 0 && ph.pat[len(ph.pat)-1] == '/' { - return p, true - } - return nil, false - case ph.pat[j] == ':': - var name, val string - var nextc byte - name, nextc, j = match(ph.pat, isAlnum, j+1) - val, _, i = match(path, matchPart(nextc), i) - p.Add(":"+name, val) - case path[i] == ph.pat[j]: - i++ - j++ - default: - return nil, false - } - } - if j != len(ph.pat) { - return nil, false - } - return p, true -} - -func matchPart(b byte) func(byte) bool { - return func(c byte) bool { - return c != b && c != '/' - } -} - -func match(s string, f func(byte) bool, i int) (matched string, next byte, j int) { - j = i - for j < len(s) && f(s[j]) { - j++ - } - if j < len(s) { - next = s[j] - } - return s[i:j], next, j -} - -func isAlpha(ch byte) bool { - return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' -} - -func isDigit(ch byte) bool { - return '0' <= ch && ch <= '9' -} - -func isAlnum(ch byte) bool { - return isAlpha(ch) || isDigit(ch) -} diff --git a/Godeps/_workspace/src/github.com/bmizerany/pat/mux_test.go b/Godeps/_workspace/src/github.com/bmizerany/pat/mux_test.go deleted file mode 100644 index 31efeac..0000000 --- a/Godeps/_workspace/src/github.com/bmizerany/pat/mux_test.go +++ /dev/null @@ -1,241 +0,0 @@ -package pat - -import ( - "net/http" - "net/http/httptest" - "net/url" - "sort" - "strings" - "testing" - - "github.com/bmizerany/assert" -) - -func TestPatMatch(t *testing.T) { - params, ok := (&patHandler{"/", nil}).try("/") - assert.Equal(t, true, ok) - - params, ok = (&patHandler{"/", nil}).try("/wrong_url") - assert.Equal(t, false, ok) - - params, ok = (&patHandler{"/foo/:name", nil}).try("/foo/bar") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":name": {"bar"}}, params) - - params, ok = (&patHandler{"/foo/:name/baz", nil}).try("/foo/bar") - assert.Equal(t, false, ok) - - params, ok = (&patHandler{"/foo/:name/bar/", nil}).try("/foo/keith/bar/baz") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":name": {"keith"}}, params) - - params, ok = (&patHandler{"/foo/:name/bar/", nil}).try("/foo/keith/bar/") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":name": {"keith"}}, params) - - params, ok = (&patHandler{"/foo/:name/bar/", nil}).try("/foo/keith/bar") - assert.Equal(t, false, ok) - - params, ok = (&patHandler{"/foo/:name/baz", nil}).try("/foo/bar/baz") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":name": {"bar"}}, params) - - params, ok = (&patHandler{"/foo/:name/baz/:id", nil}).try("/foo/bar/baz") - assert.Equal(t, false, ok) - - params, ok = (&patHandler{"/foo/:name/baz/:id", nil}).try("/foo/bar/baz/123") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":name": {"bar"}, ":id": {"123"}}, params) - - params, ok = (&patHandler{"/foo/:name/baz/:name", nil}).try("/foo/bar/baz/123") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":name": {"bar", "123"}}, params) - - params, ok = (&patHandler{"/foo/:name.txt", nil}).try("/foo/bar.txt") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":name": {"bar"}}, params) - - params, ok = (&patHandler{"/foo/:name", nil}).try("/foo/:bar") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":name": {":bar"}}, params) - - params, ok = (&patHandler{"/foo/:a:b", nil}).try("/foo/val1:val2") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":a": {"val1"}, ":b": {":val2"}}, params) - - params, ok = (&patHandler{"/foo/:a.", nil}).try("/foo/.") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":a": {""}}, params) - - params, ok = (&patHandler{"/foo/:a:b", nil}).try("/foo/:bar") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":a": {""}, ":b": {":bar"}}, params) - - params, ok = (&patHandler{"/foo/:a:b:c", nil}).try("/foo/:bar") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":a": {""}, ":b": {""}, ":c": {":bar"}}, params) - - params, ok = (&patHandler{"/foo/::name", nil}).try("/foo/val1:val2") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":": {"val1"}, ":name": {":val2"}}, params) - - params, ok = (&patHandler{"/foo/:name.txt", nil}).try("/foo/bar/baz.txt") - assert.Equal(t, false, ok) - - params, ok = (&patHandler{"/foo/x:name", nil}).try("/foo/bar") - assert.Equal(t, false, ok) - - params, ok = (&patHandler{"/foo/x:name", nil}).try("/foo/xbar") - assert.Equal(t, true, ok) - assert.Equal(t, url.Values{":name": {"bar"}}, params) -} - -func TestPatRoutingHit(t *testing.T) { - p := New() - - var ok bool - p.Get("/foo/:name", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ok = true - t.Logf("%#v", r.URL.Query()) - assert.Equal(t, "keith", r.URL.Query().Get(":name")) - })) - - r, err := http.NewRequest("GET", "/foo/keith?a=b", nil) - if err != nil { - t.Fatal(err) - } - - p.ServeHTTP(nil, r) - - assert.T(t, ok) -} - -func TestPatRoutingMethodNotAllowed(t *testing.T) { - p := New() - - var ok bool - p.Post("/foo/:name", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ok = true - })) - - p.Put("/foo/:name", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ok = true - })) - - r, err := http.NewRequest("GET", "/foo/keith", nil) - if err != nil { - t.Fatal(err) - } - - rr := httptest.NewRecorder() - p.ServeHTTP(rr, r) - - assert.T(t, !ok) - assert.Equal(t, http.StatusMethodNotAllowed, rr.Code) - - allowed := strings.Split(rr.Header().Get("Allow"), ", ") - sort.Strings(allowed) - assert.Equal(t, allowed, []string{"POST", "PUT"}) -} - -// Check to make sure we don't pollute the Raw Query when we have no parameters -func TestPatNoParams(t *testing.T) { - p := New() - - var ok bool - p.Get("/foo/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ok = true - t.Logf("%#v", r.URL.RawQuery) - assert.Equal(t, "", r.URL.RawQuery) - })) - - r, err := http.NewRequest("GET", "/foo/", nil) - if err != nil { - t.Fatal(err) - } - - p.ServeHTTP(nil, r) - - assert.T(t, ok) -} - -// Check to make sure we don't pollute the Raw Query when there are parameters but no pattern variables -func TestPatOnlyUserParams(t *testing.T) { - p := New() - - var ok bool - p.Get("/foo/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ok = true - t.Logf("%#v", r.URL.RawQuery) - assert.Equal(t, "a=b", r.URL.RawQuery) - })) - - r, err := http.NewRequest("GET", "/foo/?a=b", nil) - if err != nil { - t.Fatal(err) - } - - p.ServeHTTP(nil, r) - - assert.T(t, ok) -} - -func TestPatImplicitRedirect(t *testing.T) { - p := New() - p.Get("/foo/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) - - r, err := http.NewRequest("GET", "/foo", nil) - if err != nil { - t.Fatal(err) - } - - res := httptest.NewRecorder() - p.ServeHTTP(res, r) - - if res.Code != 301 { - t.Errorf("expected Code 301, was %d", res.Code) - } - - if loc := res.Header().Get("Location"); loc != "/foo/" { - t.Errorf("expected %q, got %q", "/foo/", loc) - } - - p = New() - p.Get("/foo", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) - p.Get("/foo/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) - - r, err = http.NewRequest("GET", "/foo", nil) - if err != nil { - t.Fatal(err) - } - - res = httptest.NewRecorder() - res.Code = 200 - p.ServeHTTP(res, r) - - if res.Code != 200 { - t.Errorf("expected Code 200, was %d", res.Code) - } -} - -func TestTail(t *testing.T) { - for i, test := range []struct { - pat string - path string - expect string - }{ - {"/:a/", "/x/y/z", "y/z"}, - {"/:a/", "/x", ""}, - {"/:a/", "/x/", ""}, - {"/:a", "/x/y/z", ""}, - {"/b/:a", "/x/y/z", ""}, - {"/hello/:title/", "/hello/mr/mizerany", "mizerany"}, - {"/:a/", "/x/y/z", "y/z"}, - } { - tail := Tail(test.pat, test.path) - if tail != test.expect { - t.Errorf("failed test %d: Tail(%q, %q) == %q (!= %q)", - i, test.pat, test.path, tail, test.expect) - } - } -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml b/Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml deleted file mode 100644 index baf46ab..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: go -go: 1.1 - -script: -- go vet ./... -- go test -v ./... diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE b/Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE deleted file mode 100644 index 5515ccf..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (C) 2013 Jeremy Saenz -All Rights Reserved. - -MIT LICENSE - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/README.md b/Godeps/_workspace/src/github.com/codegangsta/cli/README.md deleted file mode 100644 index fe4652c..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/README.md +++ /dev/null @@ -1,287 +0,0 @@ -[![Build Status](https://travis-ci.org/codegangsta/cli.png?branch=master)](https://travis-ci.org/codegangsta/cli) - -# cli.go -cli.go is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way. - -You can view the API docs here: -http://godoc.org/github.com/codegangsta/cli - -## Overview -Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app. - -**This is where cli.go comes into play.** cli.go makes command line programming fun, organized, and expressive! - -## Installation -Make sure you have a working Go environment (go 1.1 is *required*). [See the install instructions](http://golang.org/doc/install.html). - -To install `cli.go`, simply run: -``` -$ go get github.com/codegangsta/cli -``` - -Make sure your `PATH` includes to the `$GOPATH/bin` directory so your commands can be easily used: -``` -export PATH=$PATH:$GOPATH/bin -``` - -## Getting Started -One of the philosophies behind cli.go is that an API should be playful and full of discovery. So a cli.go app can be as little as one line of code in `main()`. - -``` go -package main - -import ( - "os" - "github.com/codegangsta/cli" -) - -func main() { - cli.NewApp().Run(os.Args) -} -``` - -This app will run and show help text, but is not very useful. Let's give an action to execute and some help documentation: - -``` go -package main - -import ( - "os" - "github.com/codegangsta/cli" -) - -func main() { - app := cli.NewApp() - app.Name = "boom" - app.Usage = "make an explosive entrance" - app.Action = func(c *cli.Context) { - println("boom! I say!") - } - - app.Run(os.Args) -} -``` - -Running this already gives you a ton of functionality, plus support for things like subcommands and flags, which are covered below. - -## Example - -Being a programmer can be a lonely job. Thankfully by the power of automation that is not the case! Let's create a greeter app to fend off our demons of loneliness! - -``` go -/* greet.go */ -package main - -import ( - "os" - "github.com/codegangsta/cli" -) - -func main() { - app := cli.NewApp() - app.Name = "greet" - app.Usage = "fight the loneliness!" - app.Action = func(c *cli.Context) { - println("Hello friend!") - } - - app.Run(os.Args) -} -``` - -Install our command to the `$GOPATH/bin` directory: - -``` -$ go install -``` - -Finally run our new command: - -``` -$ greet -Hello friend! -``` - -cli.go also generates some bitchass help text: -``` -$ greet help -NAME: - greet - fight the loneliness! - -USAGE: - greet [global options] command [command options] [arguments...] - -VERSION: - 0.0.0 - -COMMANDS: - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS - --version Shows version information -``` - -### Arguments -You can lookup arguments by calling the `Args` function on `cli.Context`. - -``` go -... -app.Action = func(c *cli.Context) { - println("Hello", c.Args()[0]) -} -... -``` - -### Flags -Setting and querying flags is simple. -``` go -... -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang", - Value: "english", - Usage: "language for the greeting", - }, -} -app.Action = func(c *cli.Context) { - name := "someone" - if len(c.Args()) > 0 { - name = c.Args()[0] - } - if c.String("lang") == "spanish" { - println("Hola", name) - } else { - println("Hello", name) - } -} -... -``` - -#### Alternate Names - -You can set alternate (or short) names for flags by providing a comma-delimited list for the `Name`. e.g. - -``` go -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "language for the greeting", - }, -} -``` - -#### Values from the Environment - -You can also have the default value set from the environment via `EnvVar`. e.g. - -``` go -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "language for the greeting", - EnvVar: "APP_LANG", - }, -} -``` - -That flag can then be set with `--lang spanish` or `-l spanish`. Note that giving two different forms of the same flag in the same command invocation is an error. - -### Subcommands - -Subcommands can be defined for a more git-like command line app. -```go -... -app.Commands = []cli.Command{ - { - Name: "add", - ShortName: "a", - Usage: "add a task to the list", - Action: func(c *cli.Context) { - println("added task: ", c.Args().First()) - }, - }, - { - Name: "complete", - ShortName: "c", - Usage: "complete a task on the list", - Action: func(c *cli.Context) { - println("completed task: ", c.Args().First()) - }, - }, - { - Name: "template", - ShortName: "r", - Usage: "options for task templates", - Subcommands: []cli.Command{ - { - Name: "add", - Usage: "add a new template", - Action: func(c *cli.Context) { - println("new task template: ", c.Args().First()) - }, - }, - { - Name: "remove", - Usage: "remove an existing template", - Action: func(c *cli.Context) { - println("removed task template: ", c.Args().First()) - }, - }, - }, - }, -} -... -``` - -### Bash Completion - -You can enable completion commands by setting the `EnableBashCompletion` -flag on the `App` object. By default, this setting will only auto-complete to -show an app's subcommands, but you can write your own completion methods for -the App or its subcommands. -```go -... -var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"} -app := cli.NewApp() -app.EnableBashCompletion = true -app.Commands = []cli.Command{ - { - Name: "complete", - ShortName: "c", - Usage: "complete a task on the list", - Action: func(c *cli.Context) { - println("completed task: ", c.Args().First()) - }, - BashComplete: func(c *cli.Context) { - // This will complete if no args are passed - if len(c.Args()) > 0 { - return - } - for _, t := range tasks { - fmt.Println(t) - } - }, - } -} -... -``` - -#### To Enable - -Source the `autocomplete/bash_autocomplete` file in your `.bashrc` file while -setting the `PROG` variable to the name of your program: - -`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete` - - -## Contribution Guidelines -Feel free to put up a pull request to fix a bug or maybe add a feature. I will give it a code review and make sure that it does not break backwards compatibility. If I or any other collaborators agree that it is in line with the vision of the project, we will work with you to get the code into a mergeable state and merge it into the master branch. - -If you are have contributed something significant to the project, I will most likely add you as a collaborator. As a collaborator you are given the ability to merge others pull requests. It is very important that new code does not break existing code, so be careful about what code you do choose to merge. If you have any questions feel free to link @codegangsta to the issue in question and we can review it together. - -If you feel like you have contributed to the project but have not yet been added as a collaborator, I probably forgot to add you. Hit @codegangsta up over email and we will get it figured out. - -## About -cli.go is written by none other than the [Code Gangsta](http://codegangsta.io) diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/app.go b/Godeps/_workspace/src/github.com/codegangsta/cli/app.go deleted file mode 100644 index 66e541c..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/app.go +++ /dev/null @@ -1,246 +0,0 @@ -package cli - -import ( - "fmt" - "io/ioutil" - "os" - "time" -) - -// App is the main structure of a cli application. It is recomended that -// and app be created with the cli.NewApp() function -type App struct { - // The name of the program. Defaults to os.Args[0] - Name string - // Description of the program. - Usage string - // Version of the program - Version string - // List of commands to execute - Commands []Command - // List of flags to parse - Flags []Flag - // Boolean to enable bash completion commands - EnableBashCompletion bool - // Boolean to hide built-in help command - HideHelp bool - // An action to execute when the bash-completion flag is set - BashComplete func(context *Context) - // An action to execute before any subcommands are run, but after the context is ready - // If a non-nil error is returned, no subcommands are run - Before func(context *Context) error - // The action to execute when no subcommands are specified - Action func(context *Context) - // Execute this function if the proper command cannot be found - CommandNotFound func(context *Context, command string) - // Compilation date - Compiled time.Time - // Author - Author string - // Author e-mail - Email string -} - -// Tries to find out when this binary was compiled. -// Returns the current time if it fails to find it. -func compileTime() time.Time { - info, err := os.Stat(os.Args[0]) - if err != nil { - return time.Now() - } - return info.ModTime() -} - -// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action. -func NewApp() *App { - return &App{ - Name: os.Args[0], - Usage: "A new cli application", - Version: "0.0.0", - BashComplete: DefaultAppComplete, - Action: helpCommand.Action, - Compiled: compileTime(), - } -} - -// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination -func (a *App) Run(arguments []string) error { - // append help to commands - if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - a.appendFlag(HelpFlag) - } - - //append version/help flags - if a.EnableBashCompletion { - a.appendFlag(BashCompletionFlag) - } - a.appendFlag(VersionFlag) - - // parse flags - set := flagSet(a.Name, a.Flags) - set.SetOutput(ioutil.Discard) - err := set.Parse(arguments[1:]) - nerr := normalizeFlags(a.Flags, set) - if nerr != nil { - fmt.Println(nerr) - context := NewContext(a, set, set) - ShowAppHelp(context) - fmt.Println("") - return nerr - } - context := NewContext(a, set, set) - - if err != nil { - fmt.Printf("Incorrect Usage.\n\n") - ShowAppHelp(context) - fmt.Println("") - return err - } - - if checkCompletions(context) { - return nil - } - - if checkHelp(context) { - return nil - } - - if checkVersion(context) { - return nil - } - - if a.Before != nil { - err := a.Before(context) - if err != nil { - return err - } - } - - args := context.Args() - if args.Present() { - name := args.First() - c := a.Command(name) - if c != nil { - return c.Run(context) - } - } - - // Run default Action - a.Action(context) - return nil -} - -// Another entry point to the cli app, takes care of passing arguments and error handling -func (a *App) RunAndExitOnError() { - if err := a.Run(os.Args); err != nil { - os.Stderr.WriteString(fmt.Sprintln(err)) - os.Exit(1) - } -} - -// Invokes the subcommand given the context, parses ctx.Args() to generate command-specific flags -func (a *App) RunAsSubcommand(ctx *Context) error { - // append help to commands - if len(a.Commands) > 0 { - if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - a.appendFlag(HelpFlag) - } - } - - // append flags - if a.EnableBashCompletion { - a.appendFlag(BashCompletionFlag) - } - - // parse flags - set := flagSet(a.Name, a.Flags) - set.SetOutput(ioutil.Discard) - err := set.Parse(ctx.Args().Tail()) - nerr := normalizeFlags(a.Flags, set) - context := NewContext(a, set, ctx.globalSet) - - if nerr != nil { - fmt.Println(nerr) - if len(a.Commands) > 0 { - ShowSubcommandHelp(context) - } else { - ShowCommandHelp(ctx, context.Args().First()) - } - fmt.Println("") - return nerr - } - - if err != nil { - fmt.Printf("Incorrect Usage.\n\n") - ShowSubcommandHelp(context) - return err - } - - if checkCompletions(context) { - return nil - } - - if len(a.Commands) > 0 { - if checkSubcommandHelp(context) { - return nil - } - } else { - if checkCommandHelp(ctx, context.Args().First()) { - return nil - } - } - - if a.Before != nil { - err := a.Before(context) - if err != nil { - return err - } - } - - args := context.Args() - if args.Present() { - name := args.First() - c := a.Command(name) - if c != nil { - return c.Run(context) - } - } - - // Run default Action - if len(a.Commands) > 0 { - a.Action(context) - } else { - a.Action(ctx) - } - - return nil -} - -// Returns the named command on App. Returns nil if the command does not exist -func (a *App) Command(name string) *Command { - for _, c := range a.Commands { - if c.HasName(name) { - return &c - } - } - - return nil -} - -func (a *App) hasFlag(flag Flag) bool { - for _, f := range a.Flags { - if flag == f { - return true - } - } - - return false -} - -func (a *App) appendFlag(flag Flag) { - if !a.hasFlag(flag) { - a.Flags = append(a.Flags, flag) - } -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go deleted file mode 100644 index ec00776..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go +++ /dev/null @@ -1,423 +0,0 @@ -package cli_test - -import ( - "fmt" - "os" - "testing" - - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/codegangsta/cli" -) - -func ExampleApp() { - // set args for examples sake - os.Args = []string{"greet", "--name", "Jeremy"} - - app := cli.NewApp() - app.Name = "greet" - app.Flags = []cli.Flag{ - cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"}, - } - app.Action = func(c *cli.Context) { - fmt.Printf("Hello %v\n", c.String("name")) - } - app.Run(os.Args) - // Output: - // Hello Jeremy -} - -func ExampleAppSubcommand() { - // set args for examples sake - os.Args = []string{"say", "hi", "english", "--name", "Jeremy"} - app := cli.NewApp() - app.Name = "say" - app.Commands = []cli.Command{ - { - Name: "hello", - ShortName: "hi", - Usage: "use it to see a description", - Description: "This is how we describe hello the function", - Subcommands: []cli.Command{ - { - Name: "english", - ShortName: "en", - Usage: "sends a greeting in english", - Description: "greets someone in english", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "name", - Value: "Bob", - Usage: "Name of the person to greet", - }, - }, - Action: func(c *cli.Context) { - fmt.Println("Hello,", c.String("name")) - }, - }, - }, - }, - } - - app.Run(os.Args) - // Output: - // Hello, Jeremy -} - -func ExampleAppHelp() { - // set args for examples sake - os.Args = []string{"greet", "h", "describeit"} - - app := cli.NewApp() - app.Name = "greet" - app.Flags = []cli.Flag{ - cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"}, - } - app.Commands = []cli.Command{ - { - Name: "describeit", - ShortName: "d", - Usage: "use it to see a description", - Description: "This is how we describe describeit the function", - Action: func(c *cli.Context) { - fmt.Printf("i like to describe things") - }, - }, - } - app.Run(os.Args) - // Output: - // NAME: - // describeit - use it to see a description - // - // USAGE: - // command describeit [arguments...] - // - // DESCRIPTION: - // This is how we describe describeit the function -} - -func ExampleAppBashComplete() { - // set args for examples sake - os.Args = []string{"greet", "--generate-bash-completion"} - - app := cli.NewApp() - app.Name = "greet" - app.EnableBashCompletion = true - app.Commands = []cli.Command{ - { - Name: "describeit", - ShortName: "d", - Usage: "use it to see a description", - Description: "This is how we describe describeit the function", - Action: func(c *cli.Context) { - fmt.Printf("i like to describe things") - }, - }, { - Name: "next", - Usage: "next example", - Description: "more stuff to see when generating bash completion", - Action: func(c *cli.Context) { - fmt.Printf("the next example") - }, - }, - } - - app.Run(os.Args) - // Output: - // describeit - // d - // next - // help - // h -} - -func TestApp_Run(t *testing.T) { - s := "" - - app := cli.NewApp() - app.Action = func(c *cli.Context) { - s = s + c.Args().First() - } - - err := app.Run([]string{"command", "foo"}) - expect(t, err, nil) - err = app.Run([]string{"command", "bar"}) - expect(t, err, nil) - expect(t, s, "foobar") -} - -var commandAppTests = []struct { - name string - expected bool -}{ - {"foobar", true}, - {"batbaz", true}, - {"b", true}, - {"f", true}, - {"bat", false}, - {"nothing", false}, -} - -func TestApp_Command(t *testing.T) { - app := cli.NewApp() - fooCommand := cli.Command{Name: "foobar", ShortName: "f"} - batCommand := cli.Command{Name: "batbaz", ShortName: "b"} - app.Commands = []cli.Command{ - fooCommand, - batCommand, - } - - for _, test := range commandAppTests { - expect(t, app.Command(test.name) != nil, test.expected) - } -} - -func TestApp_CommandWithArgBeforeFlags(t *testing.T) { - var parsedOption, firstArg string - - app := cli.NewApp() - command := cli.Command{ - Name: "cmd", - Flags: []cli.Flag{ - cli.StringFlag{Name: "option", Value: "", Usage: "some option"}, - }, - Action: func(c *cli.Context) { - parsedOption = c.String("option") - firstArg = c.Args().First() - }, - } - app.Commands = []cli.Command{command} - - app.Run([]string{"", "cmd", "my-arg", "--option", "my-option"}) - - expect(t, parsedOption, "my-option") - expect(t, firstArg, "my-arg") -} - -func TestApp_Float64Flag(t *testing.T) { - var meters float64 - - app := cli.NewApp() - app.Flags = []cli.Flag{ - cli.Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"}, - } - app.Action = func(c *cli.Context) { - meters = c.Float64("height") - } - - app.Run([]string{"", "--height", "1.93"}) - expect(t, meters, 1.93) -} - -func TestApp_ParseSliceFlags(t *testing.T) { - var parsedOption, firstArg string - var parsedIntSlice []int - var parsedStringSlice []string - - app := cli.NewApp() - command := cli.Command{ - Name: "cmd", - Flags: []cli.Flag{ - cli.IntSliceFlag{Name: "p", Value: &cli.IntSlice{}, Usage: "set one or more ip addr"}, - cli.StringSliceFlag{Name: "ip", Value: &cli.StringSlice{}, Usage: "set one or more ports to open"}, - }, - Action: func(c *cli.Context) { - parsedIntSlice = c.IntSlice("p") - parsedStringSlice = c.StringSlice("ip") - parsedOption = c.String("option") - firstArg = c.Args().First() - }, - } - app.Commands = []cli.Command{command} - - app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"}) - - IntsEquals := func(a, b []int) bool { - if len(a) != len(b) { - return false - } - for i, v := range a { - if v != b[i] { - return false - } - } - return true - } - - StrsEquals := func(a, b []string) bool { - if len(a) != len(b) { - return false - } - for i, v := range a { - if v != b[i] { - return false - } - } - return true - } - var expectedIntSlice = []int{22, 80} - var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"} - - if !IntsEquals(parsedIntSlice, expectedIntSlice) { - t.Errorf("%v does not match %v", parsedIntSlice, expectedIntSlice) - } - - if !StrsEquals(parsedStringSlice, expectedStringSlice) { - t.Errorf("%v does not match %v", parsedStringSlice, expectedStringSlice) - } -} - -func TestApp_BeforeFunc(t *testing.T) { - beforeRun, subcommandRun := false, false - beforeError := fmt.Errorf("fail") - var err error - - app := cli.NewApp() - - app.Before = func(c *cli.Context) error { - beforeRun = true - s := c.String("opt") - if s == "fail" { - return beforeError - } - - return nil - } - - app.Commands = []cli.Command{ - cli.Command{ - Name: "sub", - Action: func(c *cli.Context) { - subcommandRun = true - }, - }, - } - - app.Flags = []cli.Flag{ - cli.StringFlag{Name: "opt"}, - } - - // run with the Before() func succeeding - err = app.Run([]string{"command", "--opt", "succeed", "sub"}) - - if err != nil { - t.Fatalf("Run error: %s", err) - } - - if beforeRun == false { - t.Errorf("Before() not executed when expected") - } - - if subcommandRun == false { - t.Errorf("Subcommand not executed when expected") - } - - // reset - beforeRun, subcommandRun = false, false - - // run with the Before() func failing - err = app.Run([]string{"command", "--opt", "fail", "sub"}) - - // should be the same error produced by the Before func - if err != beforeError { - t.Errorf("Run error expected, but not received") - } - - if beforeRun == false { - t.Errorf("Before() not executed when expected") - } - - if subcommandRun == true { - t.Errorf("Subcommand executed when NOT expected") - } - -} - -func TestAppHelpPrinter(t *testing.T) { - oldPrinter := cli.HelpPrinter - defer func() { - cli.HelpPrinter = oldPrinter - }() - - var wasCalled = false - cli.HelpPrinter = func(template string, data interface{}) { - wasCalled = true - } - - app := cli.NewApp() - app.Run([]string{"-h"}) - - if wasCalled == false { - t.Errorf("Help printer expected to be called, but was not") - } -} - -func TestAppVersionPrinter(t *testing.T) { - oldPrinter := cli.VersionPrinter - defer func() { - cli.VersionPrinter = oldPrinter - }() - - var wasCalled = false - cli.VersionPrinter = func(c *cli.Context) { - wasCalled = true - } - - app := cli.NewApp() - ctx := cli.NewContext(app, nil, nil) - cli.ShowVersion(ctx) - - if wasCalled == false { - t.Errorf("Version printer expected to be called, but was not") - } -} - -func TestAppCommandNotFound(t *testing.T) { - beforeRun, subcommandRun := false, false - app := cli.NewApp() - - app.CommandNotFound = func(c *cli.Context, command string) { - beforeRun = true - } - - app.Commands = []cli.Command{ - cli.Command{ - Name: "bar", - Action: func(c *cli.Context) { - subcommandRun = true - }, - }, - } - - app.Run([]string{"command", "foo"}) - - expect(t, beforeRun, true) - expect(t, subcommandRun, false) -} - -func TestGlobalFlagsInSubcommands(t *testing.T) { - subcommandRun := false - app := cli.NewApp() - - app.Flags = []cli.Flag{ - cli.BoolFlag{Name: "debug, d", Usage: "Enable debugging"}, - } - - app.Commands = []cli.Command{ - cli.Command{ - Name: "foo", - Subcommands: []cli.Command{ - { - Name: "bar", - Action: func(c *cli.Context) { - if c.GlobalBool("debug") { - subcommandRun = true - } - }, - }, - }, - }, - } - - app.Run([]string{"command", "-d", "foo", "bar"}) - - expect(t, subcommandRun, true) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete b/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete deleted file mode 100644 index 9b55dd9..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/bash - -_cli_bash_autocomplete() { - local cur prev opts base - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion ) - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - } - - complete -F _cli_bash_autocomplete $PROG \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete b/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete deleted file mode 100644 index 5430a18..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete +++ /dev/null @@ -1,5 +0,0 @@ -autoload -U compinit && compinit -autoload -U bashcompinit && bashcompinit - -script_dir=$(dirname $0) -source ${script_dir}/bash_autocomplete diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/cli.go b/Godeps/_workspace/src/github.com/codegangsta/cli/cli.go deleted file mode 100644 index b742545..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/cli.go +++ /dev/null @@ -1,19 +0,0 @@ -// Package cli provides a minimal framework for creating and organizing command line -// Go applications. cli is designed to be easy to understand and write, the most simple -// cli application can be written as follows: -// func main() { -// cli.NewApp().Run(os.Args) -// } -// -// Of course this application does not do much, so let's make this an actual application: -// func main() { -// app := cli.NewApp() -// app.Name = "greet" -// app.Usage = "say a greeting" -// app.Action = func(c *cli.Context) { -// println("Greetings") -// } -// -// app.Run(os.Args) -// } -package cli diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go deleted file mode 100644 index 75322ba..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/cli_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package cli_test - -import ( - "os" - - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/codegangsta/cli" -) - -func Example() { - app := cli.NewApp() - app.Name = "todo" - app.Usage = "task list on the command line" - app.Commands = []cli.Command{ - { - Name: "add", - ShortName: "a", - Usage: "add a task to the list", - Action: func(c *cli.Context) { - println("added task: ", c.Args().First()) - }, - }, - { - Name: "complete", - ShortName: "c", - Usage: "complete a task on the list", - Action: func(c *cli.Context) { - println("completed task: ", c.Args().First()) - }, - }, - } - - app.Run(os.Args) -} - -func ExampleSubcommand() { - app := cli.NewApp() - app.Name = "say" - app.Commands = []cli.Command{ - { - Name: "hello", - ShortName: "hi", - Usage: "use it to see a description", - Description: "This is how we describe hello the function", - Subcommands: []cli.Command{ - { - Name: "english", - ShortName: "en", - Usage: "sends a greeting in english", - Description: "greets someone in english", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "name", - Value: "Bob", - Usage: "Name of the person to greet", - }, - }, - Action: func(c *cli.Context) { - println("Hello, ", c.String("name")) - }, - }, { - Name: "spanish", - ShortName: "sp", - Usage: "sends a greeting in spanish", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "surname", - Value: "Jones", - Usage: "Surname of the person to greet", - }, - }, - Action: func(c *cli.Context) { - println("Hola, ", c.String("surname")) - }, - }, { - Name: "french", - ShortName: "fr", - Usage: "sends a greeting in french", - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "nickname", - Value: "Stevie", - Usage: "Nickname of the person to greet", - }, - }, - Action: func(c *cli.Context) { - println("Bonjour, ", c.String("nickname")) - }, - }, - }, - }, { - Name: "bye", - Usage: "says goodbye", - Action: func(c *cli.Context) { - println("bye") - }, - }, - } - - app.Run(os.Args) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/command.go b/Godeps/_workspace/src/github.com/codegangsta/cli/command.go deleted file mode 100644 index 5622b38..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/command.go +++ /dev/null @@ -1,144 +0,0 @@ -package cli - -import ( - "fmt" - "io/ioutil" - "strings" -) - -// Command is a subcommand for a cli.App. -type Command struct { - // The name of the command - Name string - // short name of the command. Typically one character - ShortName string - // A short description of the usage of this command - Usage string - // A longer explanation of how the command works - Description string - // The function to call when checking for bash command completions - BashComplete func(context *Context) - // An action to execute before any sub-subcommands are run, but after the context is ready - // If a non-nil error is returned, no sub-subcommands are run - Before func(context *Context) error - // The function to call when this command is invoked - Action func(context *Context) - // List of child commands - Subcommands []Command - // List of flags to parse - Flags []Flag - // Treat all flags as normal arguments if true - SkipFlagParsing bool - // Boolean to hide built-in help command - HideHelp bool -} - -// Invokes the command given the context, parses ctx.Args() to generate command-specific flags -func (c Command) Run(ctx *Context) error { - - if len(c.Subcommands) > 0 || c.Before != nil { - return c.startApp(ctx) - } - - if !c.HideHelp { - // append help to flags - c.Flags = append( - c.Flags, - HelpFlag, - ) - } - - if ctx.App.EnableBashCompletion { - c.Flags = append(c.Flags, BashCompletionFlag) - } - - set := flagSet(c.Name, c.Flags) - set.SetOutput(ioutil.Discard) - - firstFlagIndex := -1 - for index, arg := range ctx.Args() { - if strings.HasPrefix(arg, "-") { - firstFlagIndex = index - break - } - } - - var err error - if firstFlagIndex > -1 && !c.SkipFlagParsing { - args := ctx.Args() - regularArgs := args[1:firstFlagIndex] - flagArgs := args[firstFlagIndex:] - err = set.Parse(append(flagArgs, regularArgs...)) - } else { - err = set.Parse(ctx.Args().Tail()) - } - - if err != nil { - fmt.Printf("Incorrect Usage.\n\n") - ShowCommandHelp(ctx, c.Name) - fmt.Println("") - return err - } - - nerr := normalizeFlags(c.Flags, set) - if nerr != nil { - fmt.Println(nerr) - fmt.Println("") - ShowCommandHelp(ctx, c.Name) - fmt.Println("") - return nerr - } - context := NewContext(ctx.App, set, ctx.globalSet) - - if checkCommandCompletions(context, c.Name) { - return nil - } - - if checkCommandHelp(context, c.Name) { - return nil - } - context.Command = c - c.Action(context) - return nil -} - -// Returns true if Command.Name or Command.ShortName matches given name -func (c Command) HasName(name string) bool { - return c.Name == name || c.ShortName == name -} - -func (c Command) startApp(ctx *Context) error { - app := NewApp() - - // set the name and usage - app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name) - if c.Description != "" { - app.Usage = c.Description - } else { - app.Usage = c.Usage - } - - // set CommandNotFound - app.CommandNotFound = ctx.App.CommandNotFound - - // set the flags and commands - app.Commands = c.Subcommands - app.Flags = c.Flags - app.HideHelp = c.HideHelp - - // bash completion - app.EnableBashCompletion = ctx.App.EnableBashCompletion - if c.BashComplete != nil { - app.BashComplete = c.BashComplete - } - - // set the actions - app.Before = c.Before - if c.Action != nil { - app.Action = c.Action - } else { - app.Action = helpSubcommand.Action - } - - return app.RunAsSubcommand(ctx) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go deleted file mode 100644 index 70bc390..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package cli_test - -import ( - "flag" - "testing" - - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/codegangsta/cli" -) - -func TestCommandDoNotIgnoreFlags(t *testing.T) { - app := cli.NewApp() - set := flag.NewFlagSet("test", 0) - test := []string{"blah", "blah", "-break"} - set.Parse(test) - - c := cli.NewContext(app, set, set) - - command := cli.Command{ - Name: "test-cmd", - ShortName: "tc", - Usage: "this is for testing", - Description: "testing", - Action: func(_ *cli.Context) {}, - } - err := command.Run(c) - - expect(t, err.Error(), "flag provided but not defined: -break") -} - -func TestCommandIgnoreFlags(t *testing.T) { - app := cli.NewApp() - set := flag.NewFlagSet("test", 0) - test := []string{"blah", "blah"} - set.Parse(test) - - c := cli.NewContext(app, set, set) - - command := cli.Command{ - Name: "test-cmd", - ShortName: "tc", - Usage: "this is for testing", - Description: "testing", - Action: func(_ *cli.Context) {}, - SkipFlagParsing: true, - } - err := command.Run(c) - - expect(t, err, nil) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/context.go b/Godeps/_workspace/src/github.com/codegangsta/cli/context.go deleted file mode 100644 index 8b44148..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/context.go +++ /dev/null @@ -1,315 +0,0 @@ -package cli - -import ( - "errors" - "flag" - "strconv" - "strings" - "time" -) - -// Context is a type that is passed through to -// each Handler action in a cli application. Context -// can be used to retrieve context-specific Args and -// parsed command-line options. -type Context struct { - App *App - Command Command - flagSet *flag.FlagSet - globalSet *flag.FlagSet - setFlags map[string]bool -} - -// Creates a new context. For use in when invoking an App or Command action. -func NewContext(app *App, set *flag.FlagSet, globalSet *flag.FlagSet) *Context { - return &Context{App: app, flagSet: set, globalSet: globalSet} -} - -// Looks up the value of a local int flag, returns 0 if no int flag exists -func (c *Context) Int(name string) int { - return lookupInt(name, c.flagSet) -} - -// Looks up the value of a local time.Duration flag, returns 0 if no time.Duration flag exists -func (c *Context) Duration(name string) time.Duration { - return lookupDuration(name, c.flagSet) -} - -// Looks up the value of a local float64 flag, returns 0 if no float64 flag exists -func (c *Context) Float64(name string) float64 { - return lookupFloat64(name, c.flagSet) -} - -// Looks up the value of a local bool flag, returns false if no bool flag exists -func (c *Context) Bool(name string) bool { - return lookupBool(name, c.flagSet) -} - -// Looks up the value of a local boolT flag, returns false if no bool flag exists -func (c *Context) BoolT(name string) bool { - return lookupBoolT(name, c.flagSet) -} - -// Looks up the value of a local string flag, returns "" if no string flag exists -func (c *Context) String(name string) string { - return lookupString(name, c.flagSet) -} - -// Looks up the value of a local string slice flag, returns nil if no string slice flag exists -func (c *Context) StringSlice(name string) []string { - return lookupStringSlice(name, c.flagSet) -} - -// Looks up the value of a local int slice flag, returns nil if no int slice flag exists -func (c *Context) IntSlice(name string) []int { - return lookupIntSlice(name, c.flagSet) -} - -// Looks up the value of a local generic flag, returns nil if no generic flag exists -func (c *Context) Generic(name string) interface{} { - return lookupGeneric(name, c.flagSet) -} - -// Looks up the value of a global int flag, returns 0 if no int flag exists -func (c *Context) GlobalInt(name string) int { - return lookupInt(name, c.globalSet) -} - -// Looks up the value of a global time.Duration flag, returns 0 if no time.Duration flag exists -func (c *Context) GlobalDuration(name string) time.Duration { - return lookupDuration(name, c.globalSet) -} - -// Looks up the value of a global bool flag, returns false if no bool flag exists -func (c *Context) GlobalBool(name string) bool { - return lookupBool(name, c.globalSet) -} - -// Looks up the value of a global string flag, returns "" if no string flag exists -func (c *Context) GlobalString(name string) string { - return lookupString(name, c.globalSet) -} - -// Looks up the value of a global string slice flag, returns nil if no string slice flag exists -func (c *Context) GlobalStringSlice(name string) []string { - return lookupStringSlice(name, c.globalSet) -} - -// Looks up the value of a global int slice flag, returns nil if no int slice flag exists -func (c *Context) GlobalIntSlice(name string) []int { - return lookupIntSlice(name, c.globalSet) -} - -// Looks up the value of a global generic flag, returns nil if no generic flag exists -func (c *Context) GlobalGeneric(name string) interface{} { - return lookupGeneric(name, c.globalSet) -} - -// Determines if the flag was actually set exists -func (c *Context) IsSet(name string) bool { - if c.setFlags == nil { - c.setFlags = make(map[string]bool) - c.flagSet.Visit(func(f *flag.Flag) { - c.setFlags[f.Name] = true - }) - } - return c.setFlags[name] == true -} - -// Returns a slice of flag names used in this context. -func (c *Context) FlagNames() (names []string) { - for _, flag := range c.Command.Flags { - name := strings.Split(flag.getName(), ",")[0] - if name == "help" { - continue - } - names = append(names, name) - } - return -} - -type Args []string - -// Returns the command line arguments associated with the context. -func (c *Context) Args() Args { - args := Args(c.flagSet.Args()) - return args -} - -// Returns the nth argument, or else a blank string -func (a Args) Get(n int) string { - if len(a) > n { - return a[n] - } - return "" -} - -// Returns the first argument, or else a blank string -func (a Args) First() string { - return a.Get(0) -} - -// Return the rest of the arguments (not the first one) -// or else an empty string slice -func (a Args) Tail() []string { - if len(a) >= 2 { - return []string(a)[1:] - } - return []string{} -} - -// Checks if there are any arguments present -func (a Args) Present() bool { - return len(a) != 0 -} - -// Swaps arguments at the given indexes -func (a Args) Swap(from, to int) error { - if from >= len(a) || to >= len(a) { - return errors.New("index out of range") - } - a[from], a[to] = a[to], a[from] - return nil -} - -func lookupInt(name string, set *flag.FlagSet) int { - f := set.Lookup(name) - if f != nil { - val, err := strconv.Atoi(f.Value.String()) - if err != nil { - return 0 - } - return val - } - - return 0 -} - -func lookupDuration(name string, set *flag.FlagSet) time.Duration { - f := set.Lookup(name) - if f != nil { - val, err := time.ParseDuration(f.Value.String()) - if err == nil { - return val - } - } - - return 0 -} - -func lookupFloat64(name string, set *flag.FlagSet) float64 { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseFloat(f.Value.String(), 64) - if err != nil { - return 0 - } - return val - } - - return 0 -} - -func lookupString(name string, set *flag.FlagSet) string { - f := set.Lookup(name) - if f != nil { - return f.Value.String() - } - - return "" -} - -func lookupStringSlice(name string, set *flag.FlagSet) []string { - f := set.Lookup(name) - if f != nil { - return (f.Value.(*StringSlice)).Value() - - } - - return nil -} - -func lookupIntSlice(name string, set *flag.FlagSet) []int { - f := set.Lookup(name) - if f != nil { - return (f.Value.(*IntSlice)).Value() - - } - - return nil -} - -func lookupGeneric(name string, set *flag.FlagSet) interface{} { - f := set.Lookup(name) - if f != nil { - return f.Value - } - return nil -} - -func lookupBool(name string, set *flag.FlagSet) bool { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseBool(f.Value.String()) - if err != nil { - return false - } - return val - } - - return false -} - -func lookupBoolT(name string, set *flag.FlagSet) bool { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseBool(f.Value.String()) - if err != nil { - return true - } - return val - } - - return false -} - -func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { - switch ff.Value.(type) { - case *StringSlice: - default: - set.Set(name, ff.Value.String()) - } -} - -func normalizeFlags(flags []Flag, set *flag.FlagSet) error { - visited := make(map[string]bool) - set.Visit(func(f *flag.Flag) { - visited[f.Name] = true - }) - for _, f := range flags { - parts := strings.Split(f.getName(), ",") - if len(parts) == 1 { - continue - } - var ff *flag.Flag - for _, name := range parts { - name = strings.Trim(name, " ") - if visited[name] { - if ff != nil { - return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name) - } - ff = set.Lookup(name) - } - } - if ff == nil { - continue - } - for _, name := range parts { - name = strings.Trim(name, " ") - if !visited[name] { - copyFlag(name, ff, set) - } - } - } - return nil -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go deleted file mode 100644 index 7a01d60..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package cli_test - -import ( - "flag" - "testing" - "time" - - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/codegangsta/cli" -) - -func TestNewContext(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Int("myflag", 12, "doc") - globalSet := flag.NewFlagSet("test", 0) - globalSet.Int("myflag", 42, "doc") - command := cli.Command{Name: "mycommand"} - c := cli.NewContext(nil, set, globalSet) - c.Command = command - expect(t, c.Int("myflag"), 12) - expect(t, c.GlobalInt("myflag"), 42) - expect(t, c.Command.Name, "mycommand") -} - -func TestContext_Int(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Int("myflag", 12, "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.Int("myflag"), 12) -} - -func TestContext_Duration(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Duration("myflag", time.Duration(12*time.Second), "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.Duration("myflag"), time.Duration(12*time.Second)) -} - -func TestContext_String(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.String("myflag", "hello world", "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.String("myflag"), "hello world") -} - -func TestContext_Bool(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", false, "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.Bool("myflag"), false) -} - -func TestContext_BoolT(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", true, "doc") - c := cli.NewContext(nil, set, set) - expect(t, c.BoolT("myflag"), true) -} - -func TestContext_Args(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", false, "doc") - c := cli.NewContext(nil, set, set) - set.Parse([]string{"--myflag", "bat", "baz"}) - expect(t, len(c.Args()), 2) - expect(t, c.Bool("myflag"), true) -} - -func TestContext_IsSet(t *testing.T) { - set := flag.NewFlagSet("test", 0) - set.Bool("myflag", false, "doc") - set.String("otherflag", "hello world", "doc") - c := cli.NewContext(nil, set, set) - set.Parse([]string{"--myflag", "bat", "baz"}) - expect(t, c.IsSet("myflag"), true) - expect(t, c.IsSet("otherflag"), false) - expect(t, c.IsSet("bogusflag"), false) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/flag.go b/Godeps/_workspace/src/github.com/codegangsta/cli/flag.go deleted file mode 100644 index b30bca3..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/flag.go +++ /dev/null @@ -1,410 +0,0 @@ -package cli - -import ( - "flag" - "fmt" - "os" - "strconv" - "strings" - "time" -) - -// This flag enables bash-completion for all commands and subcommands -var BashCompletionFlag = BoolFlag{ - Name: "generate-bash-completion", -} - -// This flag prints the version for the application -var VersionFlag = BoolFlag{ - Name: "version, v", - Usage: "print the version", -} - -// This flag prints the help for all commands and subcommands -var HelpFlag = BoolFlag{ - Name: "help, h", - Usage: "show help", -} - -// Flag is a common interface related to parsing flags in cli. -// For more advanced flag parsing techniques, it is recomended that -// this interface be implemented. -type Flag interface { - fmt.Stringer - // Apply Flag settings to the given flag set - Apply(*flag.FlagSet) - getName() string -} - -func flagSet(name string, flags []Flag) *flag.FlagSet { - set := flag.NewFlagSet(name, flag.ContinueOnError) - - for _, f := range flags { - f.Apply(set) - } - return set -} - -func eachName(longName string, fn func(string)) { - parts := strings.Split(longName, ",") - for _, name := range parts { - name = strings.Trim(name, " ") - fn(name) - } -} - -// Generic is a generic parseable type identified by a specific flag -type Generic interface { - Set(value string) error - String() string -} - -// GenericFlag is the flag type for types implementing Generic -type GenericFlag struct { - Name string - Value Generic - Usage string - EnvVar string -} - -func (f GenericFlag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s%s %v\t`%v` %s", prefixFor(f.Name), f.Name, f.Value, "-"+f.Name+" option -"+f.Name+" option", f.Usage)) -} - -func (f GenericFlag) Apply(set *flag.FlagSet) { - val := f.Value - if f.EnvVar != "" { - if envVal := os.Getenv(f.EnvVar); envVal != "" { - val.Set(envVal) - } - } - - eachName(f.Name, func(name string) { - set.Var(f.Value, name, f.Usage) - }) -} - -func (f GenericFlag) getName() string { - return f.Name -} - -type StringSlice []string - -func (f *StringSlice) Set(value string) error { - *f = append(*f, value) - return nil -} - -func (f *StringSlice) String() string { - return fmt.Sprintf("%s", *f) -} - -func (f *StringSlice) Value() []string { - return *f -} - -type StringSliceFlag struct { - Name string - Value *StringSlice - Usage string - EnvVar string -} - -func (f StringSliceFlag) String() string { - firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ") - pref := prefixFor(firstName) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)) -} - -func (f StringSliceFlag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - if envVal := os.Getenv(f.EnvVar); envVal != "" { - newVal := &StringSlice{} - for _, s := range strings.Split(envVal, ",") { - newVal.Set(s) - } - f.Value = newVal - } - } - - eachName(f.Name, func(name string) { - set.Var(f.Value, name, f.Usage) - }) -} - -func (f StringSliceFlag) getName() string { - return f.Name -} - -type IntSlice []int - -func (f *IntSlice) Set(value string) error { - - tmp, err := strconv.Atoi(value) - if err != nil { - return err - } else { - *f = append(*f, tmp) - } - return nil -} - -func (f *IntSlice) String() string { - return fmt.Sprintf("%d", *f) -} - -func (f *IntSlice) Value() []int { - return *f -} - -type IntSliceFlag struct { - Name string - Value *IntSlice - Usage string - EnvVar string -} - -func (f IntSliceFlag) String() string { - firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ") - pref := prefixFor(firstName) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)) -} - -func (f IntSliceFlag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - if envVal := os.Getenv(f.EnvVar); envVal != "" { - newVal := &IntSlice{} - for _, s := range strings.Split(envVal, ",") { - err := newVal.Set(s) - if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - } - } - f.Value = newVal - } - } - - eachName(f.Name, func(name string) { - set.Var(f.Value, name, f.Usage) - }) -} - -func (f IntSliceFlag) getName() string { - return f.Name -} - -type BoolFlag struct { - Name string - Usage string - EnvVar string -} - -func (f BoolFlag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)) -} - -func (f BoolFlag) Apply(set *flag.FlagSet) { - val := false - if f.EnvVar != "" { - if envVal := os.Getenv(f.EnvVar); envVal != "" { - envValBool, err := strconv.ParseBool(envVal) - if err == nil { - val = envValBool - } - } - } - - eachName(f.Name, func(name string) { - set.Bool(name, val, f.Usage) - }) -} - -func (f BoolFlag) getName() string { - return f.Name -} - -type BoolTFlag struct { - Name string - Usage string - EnvVar string -} - -func (f BoolTFlag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)) -} - -func (f BoolTFlag) Apply(set *flag.FlagSet) { - val := true - if f.EnvVar != "" { - if envVal := os.Getenv(f.EnvVar); envVal != "" { - envValBool, err := strconv.ParseBool(envVal) - if err == nil { - val = envValBool - } - } - } - - eachName(f.Name, func(name string) { - set.Bool(name, val, f.Usage) - }) -} - -func (f BoolTFlag) getName() string { - return f.Name -} - -type StringFlag struct { - Name string - Value string - Usage string - EnvVar string -} - -func (f StringFlag) String() string { - var fmtString string - fmtString = "%s %v\t%v" - - if len(f.Value) > 0 { - fmtString = "%s '%v'\t%v" - } else { - fmtString = "%s %v\t%v" - } - - return withEnvHint(f.EnvVar, fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage)) -} - -func (f StringFlag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - if envVal := os.Getenv(f.EnvVar); envVal != "" { - f.Value = envVal - } - } - - eachName(f.Name, func(name string) { - set.String(name, f.Value, f.Usage) - }) -} - -func (f StringFlag) getName() string { - return f.Name -} - -type IntFlag struct { - Name string - Value int - Usage string - EnvVar string -} - -func (f IntFlag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage)) -} - -func (f IntFlag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - if envVal := os.Getenv(f.EnvVar); envVal != "" { - envValInt, err := strconv.ParseUint(envVal, 10, 64) - if err == nil { - f.Value = int(envValInt) - } - } - } - - eachName(f.Name, func(name string) { - set.Int(name, f.Value, f.Usage) - }) -} - -func (f IntFlag) getName() string { - return f.Name -} - -type DurationFlag struct { - Name string - Value time.Duration - Usage string - EnvVar string -} - -func (f DurationFlag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage)) -} - -func (f DurationFlag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - if envVal := os.Getenv(f.EnvVar); envVal != "" { - envValDuration, err := time.ParseDuration(envVal) - if err == nil { - f.Value = envValDuration - } - } - } - - eachName(f.Name, func(name string) { - set.Duration(name, f.Value, f.Usage) - }) -} - -func (f DurationFlag) getName() string { - return f.Name -} - -type Float64Flag struct { - Name string - Value float64 - Usage string - EnvVar string -} - -func (f Float64Flag) String() string { - return withEnvHint(f.EnvVar, fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage)) -} - -func (f Float64Flag) Apply(set *flag.FlagSet) { - if f.EnvVar != "" { - if envVal := os.Getenv(f.EnvVar); envVal != "" { - envValFloat, err := strconv.ParseFloat(envVal, 10) - if err == nil { - f.Value = float64(envValFloat) - } - } - } - - eachName(f.Name, func(name string) { - set.Float64(name, f.Value, f.Usage) - }) -} - -func (f Float64Flag) getName() string { - return f.Name -} - -func prefixFor(name string) (prefix string) { - if len(name) == 1 { - prefix = "-" - } else { - prefix = "--" - } - - return -} - -func prefixedNames(fullName string) (prefixed string) { - parts := strings.Split(fullName, ",") - for i, name := range parts { - name = strings.Trim(name, " ") - prefixed += prefixFor(name) + name - if i < len(parts)-1 { - prefixed += ", " - } - } - return -} - -func withEnvHint(envVar, str string) string { - envText := "" - if envVar != "" { - envText = fmt.Sprintf(" [$%s]", envVar) - } - return str + envText -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go deleted file mode 100644 index f96c648..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go +++ /dev/null @@ -1,587 +0,0 @@ -package cli_test - -import ( - "fmt" - "os" - "reflect" - "strings" - "testing" - - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/codegangsta/cli" -) - -var boolFlagTests = []struct { - name string - expected string -}{ - {"help", "--help\t"}, - {"h", "-h\t"}, -} - -func TestBoolFlagHelpOutput(t *testing.T) { - - for _, test := range boolFlagTests { - flag := cli.BoolFlag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -var stringFlagTests = []struct { - name string - value string - expected string -}{ - {"help", "", "--help \t"}, - {"h", "", "-h \t"}, - {"h", "", "-h \t"}, - {"test", "Something", "--test 'Something'\t"}, -} - -func TestStringFlagHelpOutput(t *testing.T) { - - for _, test := range stringFlagTests { - flag := cli.StringFlag{Name: test.name, Value: test.value} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -func TestStringFlagWithEnvVarHelpOutput(t *testing.T) { - - os.Setenv("APP_FOO", "derp") - for _, test := range stringFlagTests { - flag := cli.StringFlag{Name: test.name, Value: test.value, EnvVar: "APP_FOO"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_FOO]") { - t.Errorf("%s does not end with [$APP_FOO]", output) - } - } -} - -var stringSliceFlagTests = []struct { - name string - value *cli.StringSlice - expected string -}{ - {"help", func() *cli.StringSlice { - s := &cli.StringSlice{} - s.Set("") - return s - }(), "--help '--help option --help option'\t"}, - {"h", func() *cli.StringSlice { - s := &cli.StringSlice{} - s.Set("") - return s - }(), "-h '-h option -h option'\t"}, - {"h", func() *cli.StringSlice { - s := &cli.StringSlice{} - s.Set("") - return s - }(), "-h '-h option -h option'\t"}, - {"test", func() *cli.StringSlice { - s := &cli.StringSlice{} - s.Set("Something") - return s - }(), "--test '--test option --test option'\t"}, -} - -func TestStringSliceFlagHelpOutput(t *testing.T) { - - for _, test := range stringSliceFlagTests { - flag := cli.StringSliceFlag{Name: test.name, Value: test.value} - output := flag.String() - - if output != test.expected { - t.Errorf("%q does not match %q", output, test.expected) - } - } -} - -func TestStringSliceFlagWithEnvVarHelpOutput(t *testing.T) { - - os.Setenv("APP_QWWX", "11,4") - for _, test := range stringSliceFlagTests { - flag := cli.StringSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_QWWX"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_QWWX]") { - t.Errorf("%q does not end with [$APP_QWWX]", output) - } - } -} - -var intFlagTests = []struct { - name string - expected string -}{ - {"help", "--help '0'\t"}, - {"h", "-h '0'\t"}, -} - -func TestIntFlagHelpOutput(t *testing.T) { - - for _, test := range intFlagTests { - flag := cli.IntFlag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -func TestIntFlagWithEnvVarHelpOutput(t *testing.T) { - - os.Setenv("APP_BAR", "2") - for _, test := range intFlagTests { - flag := cli.IntFlag{Name: test.name, EnvVar: "APP_BAR"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_BAR]") { - t.Errorf("%s does not end with [$APP_BAR]", output) - } - } -} - -var durationFlagTests = []struct { - name string - expected string -}{ - {"help", "--help '0'\t"}, - {"h", "-h '0'\t"}, -} - -func TestDurationFlagHelpOutput(t *testing.T) { - - for _, test := range durationFlagTests { - flag := cli.DurationFlag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -func TestDurationFlagWithEnvVarHelpOutput(t *testing.T) { - - os.Setenv("APP_BAR", "2h3m6s") - for _, test := range durationFlagTests { - flag := cli.DurationFlag{Name: test.name, EnvVar: "APP_BAR"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_BAR]") { - t.Errorf("%s does not end with [$APP_BAR]", output) - } - } -} - -var intSliceFlagTests = []struct { - name string - value *cli.IntSlice - expected string -}{ - {"help", &cli.IntSlice{}, "--help '--help option --help option'\t"}, - {"h", &cli.IntSlice{}, "-h '-h option -h option'\t"}, - {"h", &cli.IntSlice{}, "-h '-h option -h option'\t"}, - {"test", func() *cli.IntSlice { - i := &cli.IntSlice{} - i.Set("9") - return i - }(), "--test '--test option --test option'\t"}, -} - -func TestIntSliceFlagHelpOutput(t *testing.T) { - - for _, test := range intSliceFlagTests { - flag := cli.IntSliceFlag{Name: test.name, Value: test.value} - output := flag.String() - - if output != test.expected { - t.Errorf("%q does not match %q", output, test.expected) - } - } -} - -func TestIntSliceFlagWithEnvVarHelpOutput(t *testing.T) { - - os.Setenv("APP_SMURF", "42,3") - for _, test := range intSliceFlagTests { - flag := cli.IntSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_SMURF"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_SMURF]") { - t.Errorf("%q does not end with [$APP_SMURF]", output) - } - } -} - -var float64FlagTests = []struct { - name string - expected string -}{ - {"help", "--help '0'\t"}, - {"h", "-h '0'\t"}, -} - -func TestFloat64FlagHelpOutput(t *testing.T) { - - for _, test := range float64FlagTests { - flag := cli.Float64Flag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) - } - } -} - -func TestFloat64FlagWithEnvVarHelpOutput(t *testing.T) { - - os.Setenv("APP_BAZ", "99.4") - for _, test := range float64FlagTests { - flag := cli.Float64Flag{Name: test.name, EnvVar: "APP_BAZ"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_BAZ]") { - t.Errorf("%s does not end with [$APP_BAZ]", output) - } - } -} - -var genericFlagTests = []struct { - name string - value cli.Generic - expected string -}{ - {"help", &Parser{}, "--help \t`-help option -help option` "}, - {"h", &Parser{}, "-h \t`-h option -h option` "}, - {"test", &Parser{}, "--test \t`-test option -test option` "}, -} - -func TestGenericFlagHelpOutput(t *testing.T) { - - for _, test := range genericFlagTests { - flag := cli.GenericFlag{Name: test.name} - output := flag.String() - - if output != test.expected { - t.Errorf("%q does not match %q", output, test.expected) - } - } -} - -func TestGenericFlagWithEnvVarHelpOutput(t *testing.T) { - - os.Setenv("APP_ZAP", "3") - for _, test := range genericFlagTests { - flag := cli.GenericFlag{Name: test.name, EnvVar: "APP_ZAP"} - output := flag.String() - - if !strings.HasSuffix(output, " [$APP_ZAP]") { - t.Errorf("%s does not end with [$APP_ZAP]", output) - } - } -} - -func TestParseMultiString(t *testing.T) { - (&cli.App{ - Flags: []cli.Flag{ - cli.StringFlag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.String("serve") != "10" { - t.Errorf("main name not set") - } - if ctx.String("s") != "10" { - t.Errorf("short name not set") - } - }, - }).Run([]string{"run", "-s", "10"}) -} - -func TestParseMultiStringFromEnv(t *testing.T) { - os.Setenv("APP_COUNT", "20") - (&cli.App{ - Flags: []cli.Flag{ - cli.StringFlag{Name: "count, c", EnvVar: "APP_COUNT"}, - }, - Action: func(ctx *cli.Context) { - if ctx.String("count") != "20" { - t.Errorf("main name not set") - } - if ctx.String("c") != "20" { - t.Errorf("short name not set") - } - }, - }).Run([]string{"run"}) -} - -func TestParseMultiStringSlice(t *testing.T) { - (&cli.App{ - Flags: []cli.Flag{ - cli.StringSliceFlag{Name: "serve, s", Value: &cli.StringSlice{}}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) { - t.Errorf("main name not set") - } - if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) { - t.Errorf("short name not set") - } - }, - }).Run([]string{"run", "-s", "10", "-s", "20"}) -} - -func TestParseMultiStringSliceFromEnv(t *testing.T) { - os.Setenv("APP_INTERVALS", "20,30,40") - - (&cli.App{ - Flags: []cli.Flag{ - cli.StringSliceFlag{Name: "intervals, i", Value: &cli.StringSlice{}, EnvVar: "APP_INTERVALS"}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) { - t.Errorf("main name not set from env") - } - if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) { - t.Errorf("short name not set from env") - } - }, - }).Run([]string{"run"}) -} - -func TestParseMultiInt(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.IntFlag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Int("serve") != 10 { - t.Errorf("main name not set") - } - if ctx.Int("s") != 10 { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "-s", "10"}) -} - -func TestParseMultiIntFromEnv(t *testing.T) { - os.Setenv("APP_TIMEOUT_SECONDS", "10") - a := cli.App{ - Flags: []cli.Flag{ - cli.IntFlag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Int("timeout") != 10 { - t.Errorf("main name not set") - } - if ctx.Int("t") != 10 { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run"}) -} - -func TestParseMultiIntSlice(t *testing.T) { - (&cli.App{ - Flags: []cli.Flag{ - cli.IntSliceFlag{Name: "serve, s", Value: &cli.IntSlice{}}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.IntSlice("serve"), []int{10, 20}) { - t.Errorf("main name not set") - } - if !reflect.DeepEqual(ctx.IntSlice("s"), []int{10, 20}) { - t.Errorf("short name not set") - } - }, - }).Run([]string{"run", "-s", "10", "-s", "20"}) -} - -func TestParseMultiIntSliceFromEnv(t *testing.T) { - os.Setenv("APP_INTERVALS", "20,30,40") - - (&cli.App{ - Flags: []cli.Flag{ - cli.IntSliceFlag{Name: "intervals, i", Value: &cli.IntSlice{}, EnvVar: "APP_INTERVALS"}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) { - t.Errorf("main name not set from env") - } - if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) { - t.Errorf("short name not set from env") - } - }, - }).Run([]string{"run"}) -} - -func TestParseMultiFloat64(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.Float64Flag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Float64("serve") != 10.2 { - t.Errorf("main name not set") - } - if ctx.Float64("s") != 10.2 { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "-s", "10.2"}) -} - -func TestParseMultiFloat64FromEnv(t *testing.T) { - os.Setenv("APP_TIMEOUT_SECONDS", "15.5") - a := cli.App{ - Flags: []cli.Flag{ - cli.Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Float64("timeout") != 15.5 { - t.Errorf("main name not set") - } - if ctx.Float64("t") != 15.5 { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run"}) -} - -func TestParseMultiBool(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.BoolFlag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Bool("serve") != true { - t.Errorf("main name not set") - } - if ctx.Bool("s") != true { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "--serve"}) -} - -func TestParseMultiBoolFromEnv(t *testing.T) { - os.Setenv("APP_DEBUG", "1") - a := cli.App{ - Flags: []cli.Flag{ - cli.BoolFlag{Name: "debug, d", EnvVar: "APP_DEBUG"}, - }, - Action: func(ctx *cli.Context) { - if ctx.Bool("debug") != true { - t.Errorf("main name not set from env") - } - if ctx.Bool("d") != true { - t.Errorf("short name not set from env") - } - }, - } - a.Run([]string{"run"}) -} - -func TestParseMultiBoolT(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.BoolTFlag{Name: "serve, s"}, - }, - Action: func(ctx *cli.Context) { - if ctx.BoolT("serve") != true { - t.Errorf("main name not set") - } - if ctx.BoolT("s") != true { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "--serve"}) -} - -func TestParseMultiBoolTFromEnv(t *testing.T) { - os.Setenv("APP_DEBUG", "0") - a := cli.App{ - Flags: []cli.Flag{ - cli.BoolTFlag{Name: "debug, d", EnvVar: "APP_DEBUG"}, - }, - Action: func(ctx *cli.Context) { - if ctx.BoolT("debug") != false { - t.Errorf("main name not set from env") - } - if ctx.BoolT("d") != false { - t.Errorf("short name not set from env") - } - }, - } - a.Run([]string{"run"}) -} - -type Parser [2]string - -func (p *Parser) Set(value string) error { - parts := strings.Split(value, ",") - if len(parts) != 2 { - return fmt.Errorf("invalid format") - } - - (*p)[0] = parts[0] - (*p)[1] = parts[1] - - return nil -} - -func (p *Parser) String() string { - return fmt.Sprintf("%s,%s", p[0], p[1]) -} - -func TestParseGeneric(t *testing.T) { - a := cli.App{ - Flags: []cli.Flag{ - cli.GenericFlag{Name: "serve, s", Value: &Parser{}}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) { - t.Errorf("main name not set") - } - if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) { - t.Errorf("short name not set") - } - }, - } - a.Run([]string{"run", "-s", "10,20"}) -} - -func TestParseGenericFromEnv(t *testing.T) { - os.Setenv("APP_SERVE", "20,30") - a := cli.App{ - Flags: []cli.Flag{ - cli.GenericFlag{Name: "serve, s", Value: &Parser{}, EnvVar: "APP_SERVE"}, - }, - Action: func(ctx *cli.Context) { - if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"20", "30"}) { - t.Errorf("main name not set from env") - } - if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"20", "30"}) { - t.Errorf("short name not set from env") - } - }, - } - a.Run([]string{"run"}) -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/help.go b/Godeps/_workspace/src/github.com/codegangsta/cli/help.go deleted file mode 100644 index 5020cb6..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/help.go +++ /dev/null @@ -1,224 +0,0 @@ -package cli - -import ( - "fmt" - "os" - "text/tabwriter" - "text/template" -) - -// The text template for the Default help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var AppHelpTemplate = `NAME: - {{.Name}} - {{.Usage}} - -USAGE: - {{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...] - -VERSION: - {{.Version}}{{if or .Author .Email}} - -AUTHOR:{{if .Author}} - {{.Author}}{{if .Email}} - <{{.Email}}>{{end}}{{else}} - {{.Email}}{{end}}{{end}} - -COMMANDS: - {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} - {{end}}{{if .Flags}} -GLOBAL OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{end}} -` - -// The text template for the command help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var CommandHelpTemplate = `NAME: - {{.Name}} - {{.Usage}} - -USAGE: - command {{.Name}}{{if .Flags}} [command options]{{end}} [arguments...]{{if .Description}} - -DESCRIPTION: - {{.Description}}{{end}}{{if .Flags}} - -OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{ end }} -` - -// The text template for the subcommand help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var SubcommandHelpTemplate = `NAME: - {{.Name}} - {{.Usage}} - -USAGE: - {{.Name}} command{{if .Flags}} [command options]{{end}} [arguments...] - -COMMANDS: - {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} - {{end}}{{if .Flags}} -OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{end}} -` - -var helpCommand = Command{ - Name: "help", - ShortName: "h", - Usage: "Shows a list of commands or help for one command", - Action: func(c *Context) { - args := c.Args() - if args.Present() { - ShowCommandHelp(c, args.First()) - } else { - ShowAppHelp(c) - } - }, -} - -var helpSubcommand = Command{ - Name: "help", - ShortName: "h", - Usage: "Shows a list of commands or help for one command", - Action: func(c *Context) { - args := c.Args() - if args.Present() { - ShowCommandHelp(c, args.First()) - } else { - ShowSubcommandHelp(c) - } - }, -} - -// Prints help for the App -var HelpPrinter = printHelp - -// Prints version for the App -var VersionPrinter = printVersion - -func ShowAppHelp(c *Context) { - HelpPrinter(AppHelpTemplate, c.App) -} - -// Prints the list of subcommands as the default app completion method -func DefaultAppComplete(c *Context) { - for _, command := range c.App.Commands { - fmt.Println(command.Name) - if command.ShortName != "" { - fmt.Println(command.ShortName) - } - } -} - -// Prints help for the given command -func ShowCommandHelp(c *Context, command string) { - for _, c := range c.App.Commands { - if c.HasName(command) { - HelpPrinter(CommandHelpTemplate, c) - return - } - } - - if c.App.CommandNotFound != nil { - c.App.CommandNotFound(c, command) - } else { - fmt.Printf("No help topic for '%v'\n", command) - } -} - -// Prints help for the given subcommand -func ShowSubcommandHelp(c *Context) { - HelpPrinter(SubcommandHelpTemplate, c.App) -} - -// Prints the version number of the App -func ShowVersion(c *Context) { - VersionPrinter(c) -} - -func printVersion(c *Context) { - fmt.Printf("%v version %v\n", c.App.Name, c.App.Version) -} - -// Prints the lists of commands within a given context -func ShowCompletions(c *Context) { - a := c.App - if a != nil && a.BashComplete != nil { - a.BashComplete(c) - } -} - -// Prints the custom completions for a given command -func ShowCommandCompletions(ctx *Context, command string) { - c := ctx.App.Command(command) - if c != nil && c.BashComplete != nil { - c.BashComplete(ctx) - } -} - -func printHelp(templ string, data interface{}) { - w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0) - t := template.Must(template.New("help").Parse(templ)) - err := t.Execute(w, data) - if err != nil { - panic(err) - } - w.Flush() -} - -func checkVersion(c *Context) bool { - if c.GlobalBool("version") { - ShowVersion(c) - return true - } - - return false -} - -func checkHelp(c *Context) bool { - if c.GlobalBool("h") || c.GlobalBool("help") { - ShowAppHelp(c) - return true - } - - return false -} - -func checkCommandHelp(c *Context, name string) bool { - if c.Bool("h") || c.Bool("help") { - ShowCommandHelp(c, name) - return true - } - - return false -} - -func checkSubcommandHelp(c *Context) bool { - if c.GlobalBool("h") || c.GlobalBool("help") { - ShowSubcommandHelp(c) - return true - } - - return false -} - -func checkCompletions(c *Context) bool { - if c.GlobalBool(BashCompletionFlag.Name) && c.App.EnableBashCompletion { - ShowCompletions(c) - return true - } - - return false -} - -func checkCommandCompletions(c *Context, name string) bool { - if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion { - ShowCommandCompletions(c, name) - return true - } - - return false -} diff --git a/Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go b/Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go deleted file mode 100644 index cdc4feb..0000000 --- a/Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package cli_test - -import ( - "reflect" - "testing" -) - -/* Test Helpers */ -func expect(t *testing.T, a interface{}, b interface{}) { - if a != b { - t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) - } -} - -func refute(t *testing.T, a interface{}, b interface{}) { - if a == b { - t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) - } -} diff --git a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/.gitignore b/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/.gitignore deleted file mode 100644 index 0026861..0000000 --- a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe diff --git a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/README.md b/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/README.md deleted file mode 100644 index 371d9b6..0000000 --- a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/README.md +++ /dev/null @@ -1,17 +0,0 @@ -go-colortext package [![GoSearch](http://go-search.org/badge?id=github.com%2Fdaviddengcn%2Fgo-colortext)](http://go-search.org/view?id=github.com%2Fdaviddengcn%2Fgo-colortext) -==================== - -This is a package to change the color of the text and background in the console, working both under Windows and other systems. - -Under Windows, the console APIs are used. Otherwise, ANSI texts are output. - -Docs: http://godoc.org/github.com/daviddengcn/go-colortext ([packages that import ct](http://go-search.org/view?id=github.com%2fdaviddengcn%2fgo-colortext)) - -Usage: -```go -ChangeColor(Red, true, White, false) -fmt.Println(...) -ChangeColor(Green, false, None, false) -fmt.Println(...) -ResetColor() -``` diff --git a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct.go b/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct.go deleted file mode 100644 index a3d7657..0000000 --- a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -ct package provides functions to change the color of console text. - -Under windows platform, the Console api is used. Under other systems, ANSI text mode is used. -*/ -package ct - -// Color is the type of color to be set. -type Color int - -const ( - // No change of color - None = Color(iota) - Black - Red - Green - Yellow - Blue - Magenta - Cyan - White -) - -/* -ResetColor resets the foreground and background to original colors -*/ -func ResetColor() { - resetColor() -} - -// ChangeColor sets the foreground and background colors. If the value of the color is None, -// the corresponding color keeps unchanged. -// If fgBright or bgBright is set true, corresponding color use bright color. bgBright may be -// ignored in some OS environment. -func ChangeColor(fg Color, fgBright bool, bg Color, bgBright bool) { - changeColor(fg, fgBright, bg, bgBright) -} diff --git a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_ansi.go b/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_ansi.go deleted file mode 100644 index 6b0c5bc..0000000 --- a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_ansi.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build !windows - -package ct - -import ( - "fmt" -) - -func resetColor() { - fmt.Print("\x1b[0m") -} - -func changeColor(fg Color, fgBright bool, bg Color, bgBright bool) { - if fg == None && bg == None { - return - } // if - - s := "" - if fg != None { - s = fmt.Sprintf("%s%d", s, 30+(int)(fg-Black)) - if fgBright { - s += ";1" - } // if - } // if - - if bg != None { - if s != "" { - s += ";" - } // if - s = fmt.Sprintf("%s%d", s, 40+(int)(bg-Black)) - } // if - - s = "\x1b[0;" + s + "m" - fmt.Print(s) -} diff --git a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_test.go b/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_test.go deleted file mode 100644 index b2db738..0000000 --- a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package ct - -import ( - "fmt" - "testing" -) - -func TestChangeColor(t *testing.T) { - defer ResetColor() - fmt.Println("Normal text...") - text := "This is an demo of using ChangeColor to output colorful texts" - i := 1 - for _, c := range text { - ChangeColor(Color(i/2%8)+Black, i%2 == 1, Color((i+2)/2%8)+Black, false) - fmt.Print(string(c)) - i++ - } // for c - fmt.Println() - ChangeColor(Red, true, White, false) - fmt.Println("Before reset.") - ChangeColor(Red, false, White, true) - fmt.Println("Before reset.") - ResetColor() - fmt.Println("After reset.") - fmt.Println("After reset.") -} diff --git a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_win.go b/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_win.go deleted file mode 100644 index 6b41644..0000000 --- a/Godeps/_workspace/src/github.com/daviddengcn/go-colortext/ct_win.go +++ /dev/null @@ -1,139 +0,0 @@ -// +build windows - -package ct - -import ( - "syscall" - "unsafe" -) - -var fg_colors = []uint16{ - 0, - 0, - foreground_red, - foreground_green, - foreground_red | foreground_green, - foreground_blue, - foreground_red | foreground_blue, - foreground_green | foreground_blue, - foreground_red | foreground_green | foreground_blue} - -var bg_colors = []uint16{ - 0, - 0, - background_red, - background_green, - background_red | background_green, - background_blue, - background_red | background_blue, - background_green | background_blue, - background_red | background_green | background_blue} - -const ( - foreground_blue = uint16(0x0001) - foreground_green = uint16(0x0002) - foreground_red = uint16(0x0004) - foreground_intensity = uint16(0x0008) - background_blue = uint16(0x0010) - background_green = uint16(0x0020) - background_red = uint16(0x0040) - background_intensity = uint16(0x0080) - - foreground_mask = foreground_blue | foreground_green | foreground_red | foreground_intensity - background_mask = background_blue | background_green | background_red | background_intensity -) - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - - procGetStdHandle = kernel32.NewProc("GetStdHandle") - procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - - hStdout uintptr - initScreenInfo *console_screen_buffer_info -) - -func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool { - ret, _, _ := procSetConsoleTextAttribute.Call( - hConsoleOutput, - uintptr(wAttributes)) - return ret != 0 -} - -type coord struct { - X, Y int16 -} - -type small_rect struct { - Left, Top, Right, Bottom int16 -} - -type console_screen_buffer_info struct { - DwSize coord - DwCursorPosition coord - WAttributes uint16 - SrWindow small_rect - DwMaximumWindowSize coord -} - -func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *console_screen_buffer_info { - var csbi console_screen_buffer_info - ret, _, _ := procGetConsoleScreenBufferInfo.Call( - hConsoleOutput, - uintptr(unsafe.Pointer(&csbi))) - if ret == 0 { - return nil - } - return &csbi -} - -const ( - std_output_handle = uint32(-11 & 0xFFFFFFFF) -) - -func init() { - kernel32 := syscall.NewLazyDLL("kernel32.dll") - - procGetStdHandle = kernel32.NewProc("GetStdHandle") - - hStdout, _, _ = procGetStdHandle.Call(uintptr(std_output_handle)) - - initScreenInfo = getConsoleScreenBufferInfo(hStdout) - - syscall.LoadDLL("") -} - -func resetColor() { - if initScreenInfo == nil { // No console info - Ex: stdout redirection - return - } - setConsoleTextAttribute(hStdout, initScreenInfo.WAttributes) -} - -func changeColor(fg Color, fgBright bool, bg Color, bgBright bool) { - attr := uint16(0) - if fg == None || bg == None { - cbufinfo := getConsoleScreenBufferInfo(hStdout) - if cbufinfo == nil { // No console info - Ex: stdout redirection - return - } - attr = getConsoleScreenBufferInfo(hStdout).WAttributes - } // if - - if fg != None { - attr = attr & ^foreground_mask | fg_colors[fg] - if fgBright { - attr |= foreground_intensity - } // if - } // if - - if bg != None { - attr = attr & ^background_mask | bg_colors[bg] - if bgBright { - attr |= background_intensity - } // if - } // if - - setConsoleTextAttribute(hStdout, attr) -} diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/.gitignore b/Godeps/_workspace/src/github.com/howeyc/fsnotify/.gitignore deleted file mode 100644 index e4706a9..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Setup a Global .gitignore for OS and editor generated files: -# https://help.github.com/articles/ignoring-files -# git config --global core.excludesfile ~/.gitignore_global - -.vagrant diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/AUTHORS b/Godeps/_workspace/src/github.com/howeyc/fsnotify/AUTHORS deleted file mode 100644 index e52b72f..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/AUTHORS +++ /dev/null @@ -1,28 +0,0 @@ -# Names should be added to this file as -# Name or Organization -# The email address is not required for organizations. - -# You can update this list using the following command: -# -# $ git shortlog -se | awk '{print $2 " " $3 " " $4}' - -# Please keep the list sorted. - -Adrien Bustany -Caleb Spare -Case Nelson -Chris Howey -Christoffer Buchholz -Dave Cheney -Francisco Souza -John C Barstow -Kelvin Fo -Nathan Youngman -Paul Hammond -Pursuit92 -Rob Figueiredo -Travis Cline -Tudor Golubenco -bronze1man -debrando -henrikedwards diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/CHANGELOG.md b/Godeps/_workspace/src/github.com/howeyc/fsnotify/CHANGELOG.md deleted file mode 100644 index 761686a..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/CHANGELOG.md +++ /dev/null @@ -1,160 +0,0 @@ -# Changelog - -## v0.9.0 / 2014-01-17 - -* IsAttrib() for events that only concern a file's metadata [#79][] (thanks @abustany) -* [Fix] kqueue: fix deadlock [#77][] (thanks @cespare) -* [NOTICE] Development has moved to `code.google.com/p/go.exp/fsnotify` in preparation for inclusion in the Go standard library. - -## v0.8.12 / 2013-11-13 - -* [API] Remove FD_SET and friends from Linux adapter - -## v0.8.11 / 2013-11-02 - -* [Doc] Add Changelog [#72][] (thanks @nathany) -* [Doc] Spotlight and double modify events on OS X [#62][] (reported by @paulhammond) - -## v0.8.10 / 2013-10-19 - -* [Fix] kqueue: remove file watches when parent directory is removed [#71][] (reported by @mdwhatcott) -* [Fix] kqueue: race between Close and readEvents [#70][] (reported by @bernerdschaefer) -* [Doc] specify OS-specific limits in README (thanks @debrando) - -## v0.8.9 / 2013-09-08 - -* [Doc] Contributing (thanks @nathany) -* [Doc] update package path in example code [#63][] (thanks @paulhammond) -* [Doc] GoCI badge in README (Linux only) [#60][] -* [Doc] Cross-platform testing with Vagrant [#59][] (thanks @nathany) - -## v0.8.8 / 2013-06-17 - -* [Fix] Windows: handle `ERROR_MORE_DATA` on Windows [#49][] (thanks @jbowtie) - -## v0.8.7 / 2013-06-03 - -* [API] Make syscall flags internal -* [Fix] inotify: ignore event changes -* [Fix] race in symlink test [#45][] (reported by @srid) -* [Fix] tests on Windows -* lower case error messages - -## v0.8.6 / 2013-05-23 - -* kqueue: Use EVT_ONLY flag on Darwin -* [Doc] Update README with full example - -## v0.8.5 / 2013-05-09 - -* [Fix] inotify: allow monitoring of "broken" symlinks (thanks @tsg) - -## v0.8.4 / 2013-04-07 - -* [Fix] kqueue: watch all file events [#40][] (thanks @ChrisBuchholz) - -## v0.8.3 / 2013-03-13 - -* [Fix] inoitfy/kqueue memory leak [#36][] (reported by @nbkolchin) -* [Fix] kqueue: use fsnFlags for watching a directory [#33][] (reported by @nbkolchin) - -## v0.8.2 / 2013-02-07 - -* [Doc] add Authors -* [Fix] fix data races for map access [#29][] (thanks @fsouza) - -## v0.8.1 / 2013-01-09 - -* [Fix] Windows path separators -* [Doc] BSD License - -## v0.8.0 / 2012-11-09 - -* kqueue: directory watching improvements (thanks @vmirage) -* inotify: add `IN_MOVED_TO` [#25][] (requested by @cpisto) -* [Fix] kqueue: deleting watched directory [#24][] (reported by @jakerr) - -## v0.7.4 / 2012-10-09 - -* [Fix] inotify: fixes from https://codereview.appspot.com/5418045/ (ugorji) -* [Fix] kqueue: preserve watch flags when watching for delete [#21][] (reported by @robfig) -* [Fix] kqueue: watch the directory even if it isn't a new watch (thanks @robfig) -* [Fix] kqueue: modify after recreation of file - -## v0.7.3 / 2012-09-27 - -* [Fix] kqueue: watch with an existing folder inside the watched folder (thanks @vmirage) -* [Fix] kqueue: no longer get duplicate CREATE events - -## v0.7.2 / 2012-09-01 - -* kqueue: events for created directories - -## v0.7.1 / 2012-07-14 - -* [Fix] for renaming files - -## v0.7.0 / 2012-07-02 - -* [Feature] FSNotify flags -* [Fix] inotify: Added file name back to event path - -## v0.6.0 / 2012-06-06 - -* kqueue: watch files after directory created (thanks @tmc) - -## v0.5.1 / 2012-05-22 - -* [Fix] inotify: remove all watches before Close() - -## v0.5.0 / 2012-05-03 - -* [API] kqueue: return errors during watch instead of sending over channel -* kqueue: match symlink behavior on Linux -* inotify: add `DELETE_SELF` (requested by @taralx) -* [Fix] kqueue: handle EINTR (reported by @robfig) -* [Doc] Godoc example [#1][] (thanks @davecheney) - -## v0.4.0 / 2012-03-30 - -* Go 1 released: build with go tool -* [Feature] Windows support using winfsnotify -* Windows does not have attribute change notifications -* Roll attribute notifications into IsModify - -## v0.3.0 / 2012-02-19 - -* kqueue: add files when watch directory - -## v0.2.0 / 2011-12-30 - -* update to latest Go weekly code - -## v0.1.0 / 2011-10-19 - -* kqueue: add watch on file creation to match inotify -* kqueue: create file event -* inotify: ignore `IN_IGNORED` events -* event String() -* linux: common FileEvent functions -* initial commit - -[#79]: https://github.com/howeyc/fsnotify/pull/79 -[#77]: https://github.com/howeyc/fsnotify/pull/77 -[#72]: https://github.com/howeyc/fsnotify/issues/72 -[#71]: https://github.com/howeyc/fsnotify/issues/71 -[#70]: https://github.com/howeyc/fsnotify/issues/70 -[#63]: https://github.com/howeyc/fsnotify/issues/63 -[#62]: https://github.com/howeyc/fsnotify/issues/62 -[#60]: https://github.com/howeyc/fsnotify/issues/60 -[#59]: https://github.com/howeyc/fsnotify/issues/59 -[#49]: https://github.com/howeyc/fsnotify/issues/49 -[#45]: https://github.com/howeyc/fsnotify/issues/45 -[#40]: https://github.com/howeyc/fsnotify/issues/40 -[#36]: https://github.com/howeyc/fsnotify/issues/36 -[#33]: https://github.com/howeyc/fsnotify/issues/33 -[#29]: https://github.com/howeyc/fsnotify/issues/29 -[#25]: https://github.com/howeyc/fsnotify/issues/25 -[#24]: https://github.com/howeyc/fsnotify/issues/24 -[#21]: https://github.com/howeyc/fsnotify/issues/21 -[#1]: https://github.com/howeyc/fsnotify/issues/1 diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/CONTRIBUTING.md b/Godeps/_workspace/src/github.com/howeyc/fsnotify/CONTRIBUTING.md deleted file mode 100644 index b2025d7..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/CONTRIBUTING.md +++ /dev/null @@ -1,7 +0,0 @@ -# Contributing - -## Moving Notice - -There is a fork being actively developed with a new API in preparation for the Go Standard Library: -[github.com/go-fsnotify/fsnotify](https://github.com/go-fsnotify/fsnotify) - diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/LICENSE b/Godeps/_workspace/src/github.com/howeyc/fsnotify/LICENSE deleted file mode 100644 index f21e540..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. -Copyright (c) 2012 fsnotify Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/README.md b/Godeps/_workspace/src/github.com/howeyc/fsnotify/README.md deleted file mode 100644 index 4c7498d..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# File system notifications for Go - -[![GoDoc](https://godoc.org/github.com/howeyc/fsnotify?status.png)](http://godoc.org/github.com/howeyc/fsnotify) - -Cross platform: Windows, Linux, BSD and OS X. - -## Moving Notice - -There is a fork being actively developed with a new API in preparation for the Go Standard Library: -[github.com/go-fsnotify/fsnotify](https://github.com/go-fsnotify/fsnotify) - -## Example: - -```go -package main - -import ( - "log" - - "github.com/howeyc/fsnotify" -) - -func main() { - watcher, err := fsnotify.NewWatcher() - if err != nil { - log.Fatal(err) - } - - done := make(chan bool) - - // Process events - go func() { - for { - select { - case ev := <-watcher.Event: - log.Println("event:", ev) - case err := <-watcher.Error: - log.Println("error:", err) - } - } - }() - - err = watcher.Watch("testDir") - if err != nil { - log.Fatal(err) - } - - <-done - - /* ... do stuff ... */ - watcher.Close() -} -``` - -For each event: -* Name -* IsCreate() -* IsDelete() -* IsModify() -* IsRename() - -## FAQ - -**When a file is moved to another directory is it still being watched?** - -No (it shouldn't be, unless you are watching where it was moved to). - -**When I watch a directory, are all subdirectories watched as well?** - -No, you must add watches for any directory you want to watch (a recursive watcher is in the works [#56][]). - -**Do I have to watch the Error and Event channels in a separate goroutine?** - -As of now, yes. Looking into making this single-thread friendly (see [#7][]) - -**Why am I receiving multiple events for the same file on OS X?** - -Spotlight indexing on OS X can result in multiple events (see [#62][]). A temporary workaround is to add your folder(s) to the *Spotlight Privacy settings* until we have a native FSEvents implementation (see [#54][]). - -**How many files can be watched at once?** - -There are OS-specific limits as to how many watches can be created: -* Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, -reaching this limit results in a "no space left on device" error. -* BSD / OSX: sysctl variables "kern.maxfiles" and "kern.maxfilesperproc", reaching these limits results in a "too many open files" error. - - -[#62]: https://github.com/howeyc/fsnotify/issues/62 -[#56]: https://github.com/howeyc/fsnotify/issues/56 -[#54]: https://github.com/howeyc/fsnotify/issues/54 -[#7]: https://github.com/howeyc/fsnotify/issues/7 - diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/example_test.go b/Godeps/_workspace/src/github.com/howeyc/fsnotify/example_test.go deleted file mode 100644 index 6e29e0b..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/example_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package fsnotify_test - -import ( - "log" - - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/howeyc/fsnotify" -) - -func ExampleNewWatcher() { - watcher, err := fsnotify.NewWatcher() - if err != nil { - log.Fatal(err) - } - - go func() { - for { - select { - case ev := <-watcher.Event: - log.Println("event:", ev) - case err := <-watcher.Error: - log.Println("error:", err) - } - } - }() - - err = watcher.Watch("/tmp/foo") - if err != nil { - log.Fatal(err) - } -} diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify.go b/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify.go deleted file mode 100644 index 9a48d84..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify.go +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package fsnotify implements file system notification. -package fsnotify - -import "fmt" - -const ( - FSN_CREATE = 1 - FSN_MODIFY = 2 - FSN_DELETE = 4 - FSN_RENAME = 8 - - FSN_ALL = FSN_MODIFY | FSN_DELETE | FSN_RENAME | FSN_CREATE -) - -// Purge events from interal chan to external chan if passes filter -func (w *Watcher) purgeEvents() { - for ev := range w.internalEvent { - sendEvent := false - w.fsnmut.Lock() - fsnFlags := w.fsnFlags[ev.Name] - w.fsnmut.Unlock() - - if (fsnFlags&FSN_CREATE == FSN_CREATE) && ev.IsCreate() { - sendEvent = true - } - - if (fsnFlags&FSN_MODIFY == FSN_MODIFY) && ev.IsModify() { - sendEvent = true - } - - if (fsnFlags&FSN_DELETE == FSN_DELETE) && ev.IsDelete() { - sendEvent = true - } - - if (fsnFlags&FSN_RENAME == FSN_RENAME) && ev.IsRename() { - sendEvent = true - } - - if sendEvent { - w.Event <- ev - } - - // If there's no file, then no more events for user - // BSD must keep watch for internal use (watches DELETEs to keep track - // what files exist for create events) - if ev.IsDelete() { - w.fsnmut.Lock() - delete(w.fsnFlags, ev.Name) - w.fsnmut.Unlock() - } - } - - close(w.Event) -} - -// Watch a given file path -func (w *Watcher) Watch(path string) error { - return w.WatchFlags(path, FSN_ALL) -} - -// Watch a given file path for a particular set of notifications (FSN_MODIFY etc.) -func (w *Watcher) WatchFlags(path string, flags uint32) error { - w.fsnmut.Lock() - w.fsnFlags[path] = flags - w.fsnmut.Unlock() - return w.watch(path) -} - -// Remove a watch on a file -func (w *Watcher) RemoveWatch(path string) error { - w.fsnmut.Lock() - delete(w.fsnFlags, path) - w.fsnmut.Unlock() - return w.removeWatch(path) -} - -// String formats the event e in the form -// "filename: DELETE|MODIFY|..." -func (e *FileEvent) String() string { - var events string = "" - - if e.IsCreate() { - events += "|" + "CREATE" - } - - if e.IsDelete() { - events += "|" + "DELETE" - } - - if e.IsModify() { - events += "|" + "MODIFY" - } - - if e.IsRename() { - events += "|" + "RENAME" - } - - if e.IsAttrib() { - events += "|" + "ATTRIB" - } - - if len(events) > 0 { - events = events[1:] - } - - return fmt.Sprintf("%q: %s", e.Name, events) -} diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_bsd.go b/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_bsd.go deleted file mode 100644 index e6ffd7e..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_bsd.go +++ /dev/null @@ -1,496 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build freebsd openbsd netbsd darwin - -package fsnotify - -import ( - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "sync" - "syscall" -) - -const ( - // Flags (from ) - sys_NOTE_DELETE = 0x0001 /* vnode was removed */ - sys_NOTE_WRITE = 0x0002 /* data contents changed */ - sys_NOTE_EXTEND = 0x0004 /* size increased */ - sys_NOTE_ATTRIB = 0x0008 /* attributes changed */ - sys_NOTE_LINK = 0x0010 /* link count changed */ - sys_NOTE_RENAME = 0x0020 /* vnode was renamed */ - sys_NOTE_REVOKE = 0x0040 /* vnode access was revoked */ - - // Watch all events - sys_NOTE_ALLEVENTS = sys_NOTE_DELETE | sys_NOTE_WRITE | sys_NOTE_ATTRIB | sys_NOTE_RENAME - - // Block for 100 ms on each call to kevent - keventWaitTime = 100e6 -) - -type FileEvent struct { - mask uint32 // Mask of events - Name string // File name (optional) - create bool // set by fsnotify package if found new file -} - -// IsCreate reports whether the FileEvent was triggered by a creation -func (e *FileEvent) IsCreate() bool { return e.create } - -// IsDelete reports whether the FileEvent was triggered by a delete -func (e *FileEvent) IsDelete() bool { return (e.mask & sys_NOTE_DELETE) == sys_NOTE_DELETE } - -// IsModify reports whether the FileEvent was triggered by a file modification -func (e *FileEvent) IsModify() bool { - return ((e.mask&sys_NOTE_WRITE) == sys_NOTE_WRITE || (e.mask&sys_NOTE_ATTRIB) == sys_NOTE_ATTRIB) -} - -// IsRename reports whether the FileEvent was triggered by a change name -func (e *FileEvent) IsRename() bool { return (e.mask & sys_NOTE_RENAME) == sys_NOTE_RENAME } - -// IsAttrib reports whether the FileEvent was triggered by a change in the file metadata. -func (e *FileEvent) IsAttrib() bool { - return (e.mask & sys_NOTE_ATTRIB) == sys_NOTE_ATTRIB -} - -type Watcher struct { - mu sync.Mutex // Mutex for the Watcher itself. - kq int // File descriptor (as returned by the kqueue() syscall) - watches map[string]int // Map of watched file descriptors (key: path) - wmut sync.Mutex // Protects access to watches. - fsnFlags map[string]uint32 // Map of watched files to flags used for filter - fsnmut sync.Mutex // Protects access to fsnFlags. - enFlags map[string]uint32 // Map of watched files to evfilt note flags used in kqueue - enmut sync.Mutex // Protects access to enFlags. - paths map[int]string // Map of watched paths (key: watch descriptor) - finfo map[int]os.FileInfo // Map of file information (isDir, isReg; key: watch descriptor) - pmut sync.Mutex // Protects access to paths and finfo. - fileExists map[string]bool // Keep track of if we know this file exists (to stop duplicate create events) - femut sync.Mutex // Protects access to fileExists. - externalWatches map[string]bool // Map of watches added by user of the library. - ewmut sync.Mutex // Protects access to externalWatches. - Error chan error // Errors are sent on this channel - internalEvent chan *FileEvent // Events are queued on this channel - Event chan *FileEvent // Events are returned on this channel - done chan bool // Channel for sending a "quit message" to the reader goroutine - isClosed bool // Set to true when Close() is first called -} - -// NewWatcher creates and returns a new kevent instance using kqueue(2) -func NewWatcher() (*Watcher, error) { - fd, errno := syscall.Kqueue() - if fd == -1 { - return nil, os.NewSyscallError("kqueue", errno) - } - w := &Watcher{ - kq: fd, - watches: make(map[string]int), - fsnFlags: make(map[string]uint32), - enFlags: make(map[string]uint32), - paths: make(map[int]string), - finfo: make(map[int]os.FileInfo), - fileExists: make(map[string]bool), - externalWatches: make(map[string]bool), - internalEvent: make(chan *FileEvent), - Event: make(chan *FileEvent), - Error: make(chan error), - done: make(chan bool, 1), - } - - go w.readEvents() - go w.purgeEvents() - return w, nil -} - -// Close closes a kevent watcher instance -// It sends a message to the reader goroutine to quit and removes all watches -// associated with the kevent instance -func (w *Watcher) Close() error { - w.mu.Lock() - if w.isClosed { - w.mu.Unlock() - return nil - } - w.isClosed = true - w.mu.Unlock() - - // Send "quit" message to the reader goroutine - w.done <- true - w.wmut.Lock() - ws := w.watches - w.wmut.Unlock() - for path := range ws { - w.removeWatch(path) - } - - return nil -} - -// AddWatch adds path to the watched file set. -// The flags are interpreted as described in kevent(2). -func (w *Watcher) addWatch(path string, flags uint32) error { - w.mu.Lock() - if w.isClosed { - w.mu.Unlock() - return errors.New("kevent instance already closed") - } - w.mu.Unlock() - - watchDir := false - - w.wmut.Lock() - watchfd, found := w.watches[path] - w.wmut.Unlock() - if !found { - fi, errstat := os.Lstat(path) - if errstat != nil { - return errstat - } - - // don't watch socket - if fi.Mode()&os.ModeSocket == os.ModeSocket { - return nil - } - - // Follow Symlinks - // Unfortunately, Linux can add bogus symlinks to watch list without - // issue, and Windows can't do symlinks period (AFAIK). To maintain - // consistency, we will act like everything is fine. There will simply - // be no file events for broken symlinks. - // Hence the returns of nil on errors. - if fi.Mode()&os.ModeSymlink == os.ModeSymlink { - path, err := filepath.EvalSymlinks(path) - if err != nil { - return nil - } - - fi, errstat = os.Lstat(path) - if errstat != nil { - return nil - } - } - - fd, errno := syscall.Open(path, open_FLAGS, 0700) - if fd == -1 { - return errno - } - watchfd = fd - - w.wmut.Lock() - w.watches[path] = watchfd - w.wmut.Unlock() - - w.pmut.Lock() - w.paths[watchfd] = path - w.finfo[watchfd] = fi - w.pmut.Unlock() - } - // Watch the directory if it has not been watched before. - w.pmut.Lock() - w.enmut.Lock() - if w.finfo[watchfd].IsDir() && - (flags&sys_NOTE_WRITE) == sys_NOTE_WRITE && - (!found || (w.enFlags[path]&sys_NOTE_WRITE) != sys_NOTE_WRITE) { - watchDir = true - } - w.enmut.Unlock() - w.pmut.Unlock() - - w.enmut.Lock() - w.enFlags[path] = flags - w.enmut.Unlock() - - var kbuf [1]syscall.Kevent_t - watchEntry := &kbuf[0] - watchEntry.Fflags = flags - syscall.SetKevent(watchEntry, watchfd, syscall.EVFILT_VNODE, syscall.EV_ADD|syscall.EV_CLEAR) - entryFlags := watchEntry.Flags - success, errno := syscall.Kevent(w.kq, kbuf[:], nil, nil) - if success == -1 { - return errno - } else if (entryFlags & syscall.EV_ERROR) == syscall.EV_ERROR { - return errors.New("kevent add error") - } - - if watchDir { - errdir := w.watchDirectoryFiles(path) - if errdir != nil { - return errdir - } - } - return nil -} - -// Watch adds path to the watched file set, watching all events. -func (w *Watcher) watch(path string) error { - w.ewmut.Lock() - w.externalWatches[path] = true - w.ewmut.Unlock() - return w.addWatch(path, sys_NOTE_ALLEVENTS) -} - -// RemoveWatch removes path from the watched file set. -func (w *Watcher) removeWatch(path string) error { - w.wmut.Lock() - watchfd, ok := w.watches[path] - w.wmut.Unlock() - if !ok { - return errors.New(fmt.Sprintf("can't remove non-existent kevent watch for: %s", path)) - } - var kbuf [1]syscall.Kevent_t - watchEntry := &kbuf[0] - syscall.SetKevent(watchEntry, watchfd, syscall.EVFILT_VNODE, syscall.EV_DELETE) - entryFlags := watchEntry.Flags - success, errno := syscall.Kevent(w.kq, kbuf[:], nil, nil) - if success == -1 { - return os.NewSyscallError("kevent_rm_watch", errno) - } else if (entryFlags & syscall.EV_ERROR) == syscall.EV_ERROR { - return errors.New("kevent rm error") - } - syscall.Close(watchfd) - w.wmut.Lock() - delete(w.watches, path) - w.wmut.Unlock() - w.enmut.Lock() - delete(w.enFlags, path) - w.enmut.Unlock() - w.pmut.Lock() - delete(w.paths, watchfd) - fInfo := w.finfo[watchfd] - delete(w.finfo, watchfd) - w.pmut.Unlock() - - // Find all watched paths that are in this directory that are not external. - if fInfo.IsDir() { - var pathsToRemove []string - w.pmut.Lock() - for _, wpath := range w.paths { - wdir, _ := filepath.Split(wpath) - if filepath.Clean(wdir) == filepath.Clean(path) { - w.ewmut.Lock() - if !w.externalWatches[wpath] { - pathsToRemove = append(pathsToRemove, wpath) - } - w.ewmut.Unlock() - } - } - w.pmut.Unlock() - for _, p := range pathsToRemove { - // Since these are internal, not much sense in propagating error - // to the user, as that will just confuse them with an error about - // a path they did not explicitly watch themselves. - w.removeWatch(p) - } - } - - return nil -} - -// readEvents reads from the kqueue file descriptor, converts the -// received events into Event objects and sends them via the Event channel -func (w *Watcher) readEvents() { - var ( - eventbuf [10]syscall.Kevent_t // Event buffer - events []syscall.Kevent_t // Received events - twait *syscall.Timespec // Time to block waiting for events - n int // Number of events returned from kevent - errno error // Syscall errno - ) - events = eventbuf[0:0] - twait = new(syscall.Timespec) - *twait = syscall.NsecToTimespec(keventWaitTime) - - for { - // See if there is a message on the "done" channel - var done bool - select { - case done = <-w.done: - default: - } - - // If "done" message is received - if done { - errno := syscall.Close(w.kq) - if errno != nil { - w.Error <- os.NewSyscallError("close", errno) - } - close(w.internalEvent) - close(w.Error) - return - } - - // Get new events - if len(events) == 0 { - n, errno = syscall.Kevent(w.kq, nil, eventbuf[:], twait) - - // EINTR is okay, basically the syscall was interrupted before - // timeout expired. - if errno != nil && errno != syscall.EINTR { - w.Error <- os.NewSyscallError("kevent", errno) - continue - } - - // Received some events - if n > 0 { - events = eventbuf[0:n] - } - } - - // Flush the events we received to the events channel - for len(events) > 0 { - fileEvent := new(FileEvent) - watchEvent := &events[0] - fileEvent.mask = uint32(watchEvent.Fflags) - w.pmut.Lock() - fileEvent.Name = w.paths[int(watchEvent.Ident)] - fileInfo := w.finfo[int(watchEvent.Ident)] - w.pmut.Unlock() - if fileInfo != nil && fileInfo.IsDir() && !fileEvent.IsDelete() { - // Double check to make sure the directory exist. This can happen when - // we do a rm -fr on a recursively watched folders and we receive a - // modification event first but the folder has been deleted and later - // receive the delete event - if _, err := os.Lstat(fileEvent.Name); os.IsNotExist(err) { - // mark is as delete event - fileEvent.mask |= sys_NOTE_DELETE - } - } - - if fileInfo != nil && fileInfo.IsDir() && fileEvent.IsModify() && !fileEvent.IsDelete() { - w.sendDirectoryChangeEvents(fileEvent.Name) - } else { - // Send the event on the events channel - w.internalEvent <- fileEvent - } - - // Move to next event - events = events[1:] - - if fileEvent.IsRename() { - w.removeWatch(fileEvent.Name) - w.femut.Lock() - delete(w.fileExists, fileEvent.Name) - w.femut.Unlock() - } - if fileEvent.IsDelete() { - w.removeWatch(fileEvent.Name) - w.femut.Lock() - delete(w.fileExists, fileEvent.Name) - w.femut.Unlock() - - // Look for a file that may have overwritten this - // (ie mv f1 f2 will delete f2 then create f2) - fileDir, _ := filepath.Split(fileEvent.Name) - fileDir = filepath.Clean(fileDir) - w.wmut.Lock() - _, found := w.watches[fileDir] - w.wmut.Unlock() - if found { - // make sure the directory exist before we watch for changes. When we - // do a recursive watch and perform rm -fr, the parent directory might - // have gone missing, ignore the missing directory and let the - // upcoming delete event remove the watch form the parent folder - if _, err := os.Lstat(fileDir); !os.IsNotExist(err) { - w.sendDirectoryChangeEvents(fileDir) - } - } - } - } - } -} - -func (w *Watcher) watchDirectoryFiles(dirPath string) error { - // Get all files - files, err := ioutil.ReadDir(dirPath) - if err != nil { - return err - } - - // Search for new files - for _, fileInfo := range files { - filePath := filepath.Join(dirPath, fileInfo.Name()) - - // Inherit fsnFlags from parent directory - w.fsnmut.Lock() - if flags, found := w.fsnFlags[dirPath]; found { - w.fsnFlags[filePath] = flags - } else { - w.fsnFlags[filePath] = FSN_ALL - } - w.fsnmut.Unlock() - - if fileInfo.IsDir() == false { - // Watch file to mimic linux fsnotify - e := w.addWatch(filePath, sys_NOTE_ALLEVENTS) - if e != nil { - return e - } - } else { - // If the user is currently watching directory - // we want to preserve the flags used - w.enmut.Lock() - currFlags, found := w.enFlags[filePath] - w.enmut.Unlock() - var newFlags uint32 = sys_NOTE_DELETE - if found { - newFlags |= currFlags - } - - // Linux gives deletes if not explicitly watching - e := w.addWatch(filePath, newFlags) - if e != nil { - return e - } - } - w.femut.Lock() - w.fileExists[filePath] = true - w.femut.Unlock() - } - - return nil -} - -// sendDirectoryEvents searches the directory for newly created files -// and sends them over the event channel. This functionality is to have -// the BSD version of fsnotify match linux fsnotify which provides a -// create event for files created in a watched directory. -func (w *Watcher) sendDirectoryChangeEvents(dirPath string) { - // Get all files - files, err := ioutil.ReadDir(dirPath) - if err != nil { - w.Error <- err - } - - // Search for new files - for _, fileInfo := range files { - filePath := filepath.Join(dirPath, fileInfo.Name()) - w.femut.Lock() - _, doesExist := w.fileExists[filePath] - w.femut.Unlock() - if !doesExist { - // Inherit fsnFlags from parent directory - w.fsnmut.Lock() - if flags, found := w.fsnFlags[dirPath]; found { - w.fsnFlags[filePath] = flags - } else { - w.fsnFlags[filePath] = FSN_ALL - } - w.fsnmut.Unlock() - - // Send create event - fileEvent := new(FileEvent) - fileEvent.Name = filePath - fileEvent.create = true - w.internalEvent <- fileEvent - } - w.femut.Lock() - w.fileExists[filePath] = true - w.femut.Unlock() - } - w.watchDirectoryFiles(dirPath) -} diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_linux.go b/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_linux.go deleted file mode 100644 index 80ade87..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_linux.go +++ /dev/null @@ -1,304 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build linux - -package fsnotify - -import ( - "errors" - "fmt" - "os" - "strings" - "sync" - "syscall" - "unsafe" -) - -const ( - // Options for inotify_init() are not exported - // sys_IN_CLOEXEC uint32 = syscall.IN_CLOEXEC - // sys_IN_NONBLOCK uint32 = syscall.IN_NONBLOCK - - // Options for AddWatch - sys_IN_DONT_FOLLOW uint32 = syscall.IN_DONT_FOLLOW - sys_IN_ONESHOT uint32 = syscall.IN_ONESHOT - sys_IN_ONLYDIR uint32 = syscall.IN_ONLYDIR - - // The "sys_IN_MASK_ADD" option is not exported, as AddWatch - // adds it automatically, if there is already a watch for the given path - // sys_IN_MASK_ADD uint32 = syscall.IN_MASK_ADD - - // Events - sys_IN_ACCESS uint32 = syscall.IN_ACCESS - sys_IN_ALL_EVENTS uint32 = syscall.IN_ALL_EVENTS - sys_IN_ATTRIB uint32 = syscall.IN_ATTRIB - sys_IN_CLOSE uint32 = syscall.IN_CLOSE - sys_IN_CLOSE_NOWRITE uint32 = syscall.IN_CLOSE_NOWRITE - sys_IN_CLOSE_WRITE uint32 = syscall.IN_CLOSE_WRITE - sys_IN_CREATE uint32 = syscall.IN_CREATE - sys_IN_DELETE uint32 = syscall.IN_DELETE - sys_IN_DELETE_SELF uint32 = syscall.IN_DELETE_SELF - sys_IN_MODIFY uint32 = syscall.IN_MODIFY - sys_IN_MOVE uint32 = syscall.IN_MOVE - sys_IN_MOVED_FROM uint32 = syscall.IN_MOVED_FROM - sys_IN_MOVED_TO uint32 = syscall.IN_MOVED_TO - sys_IN_MOVE_SELF uint32 = syscall.IN_MOVE_SELF - sys_IN_OPEN uint32 = syscall.IN_OPEN - - sys_AGNOSTIC_EVENTS = sys_IN_MOVED_TO | sys_IN_MOVED_FROM | sys_IN_CREATE | sys_IN_ATTRIB | sys_IN_MODIFY | sys_IN_MOVE_SELF | sys_IN_DELETE | sys_IN_DELETE_SELF - - // Special events - sys_IN_ISDIR uint32 = syscall.IN_ISDIR - sys_IN_IGNORED uint32 = syscall.IN_IGNORED - sys_IN_Q_OVERFLOW uint32 = syscall.IN_Q_OVERFLOW - sys_IN_UNMOUNT uint32 = syscall.IN_UNMOUNT -) - -type FileEvent struct { - mask uint32 // Mask of events - cookie uint32 // Unique cookie associating related events (for rename(2)) - Name string // File name (optional) -} - -// IsCreate reports whether the FileEvent was triggered by a creation -func (e *FileEvent) IsCreate() bool { - return (e.mask&sys_IN_CREATE) == sys_IN_CREATE || (e.mask&sys_IN_MOVED_TO) == sys_IN_MOVED_TO -} - -// IsDelete reports whether the FileEvent was triggered by a delete -func (e *FileEvent) IsDelete() bool { - return (e.mask&sys_IN_DELETE_SELF) == sys_IN_DELETE_SELF || (e.mask&sys_IN_DELETE) == sys_IN_DELETE -} - -// IsModify reports whether the FileEvent was triggered by a file modification or attribute change -func (e *FileEvent) IsModify() bool { - return ((e.mask&sys_IN_MODIFY) == sys_IN_MODIFY || (e.mask&sys_IN_ATTRIB) == sys_IN_ATTRIB) -} - -// IsRename reports whether the FileEvent was triggered by a change name -func (e *FileEvent) IsRename() bool { - return ((e.mask&sys_IN_MOVE_SELF) == sys_IN_MOVE_SELF || (e.mask&sys_IN_MOVED_FROM) == sys_IN_MOVED_FROM) -} - -// IsAttrib reports whether the FileEvent was triggered by a change in the file metadata. -func (e *FileEvent) IsAttrib() bool { - return (e.mask & sys_IN_ATTRIB) == sys_IN_ATTRIB -} - -type watch struct { - wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall) - flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags) -} - -type Watcher struct { - mu sync.Mutex // Map access - fd int // File descriptor (as returned by the inotify_init() syscall) - watches map[string]*watch // Map of inotify watches (key: path) - fsnFlags map[string]uint32 // Map of watched files to flags used for filter - fsnmut sync.Mutex // Protects access to fsnFlags. - paths map[int]string // Map of watched paths (key: watch descriptor) - Error chan error // Errors are sent on this channel - internalEvent chan *FileEvent // Events are queued on this channel - Event chan *FileEvent // Events are returned on this channel - done chan bool // Channel for sending a "quit message" to the reader goroutine - isClosed bool // Set to true when Close() is first called -} - -// NewWatcher creates and returns a new inotify instance using inotify_init(2) -func NewWatcher() (*Watcher, error) { - fd, errno := syscall.InotifyInit() - if fd == -1 { - return nil, os.NewSyscallError("inotify_init", errno) - } - w := &Watcher{ - fd: fd, - watches: make(map[string]*watch), - fsnFlags: make(map[string]uint32), - paths: make(map[int]string), - internalEvent: make(chan *FileEvent), - Event: make(chan *FileEvent), - Error: make(chan error), - done: make(chan bool, 1), - } - - go w.readEvents() - go w.purgeEvents() - return w, nil -} - -// Close closes an inotify watcher instance -// It sends a message to the reader goroutine to quit and removes all watches -// associated with the inotify instance -func (w *Watcher) Close() error { - if w.isClosed { - return nil - } - w.isClosed = true - - // Remove all watches - for path := range w.watches { - w.RemoveWatch(path) - } - - // Send "quit" message to the reader goroutine - w.done <- true - - return nil -} - -// AddWatch adds path to the watched file set. -// The flags are interpreted as described in inotify_add_watch(2). -func (w *Watcher) addWatch(path string, flags uint32) error { - if w.isClosed { - return errors.New("inotify instance already closed") - } - - w.mu.Lock() - watchEntry, found := w.watches[path] - w.mu.Unlock() - if found { - watchEntry.flags |= flags - flags |= syscall.IN_MASK_ADD - } - wd, errno := syscall.InotifyAddWatch(w.fd, path, flags) - if wd == -1 { - return errno - } - - w.mu.Lock() - w.watches[path] = &watch{wd: uint32(wd), flags: flags} - w.paths[wd] = path - w.mu.Unlock() - - return nil -} - -// Watch adds path to the watched file set, watching all events. -func (w *Watcher) watch(path string) error { - return w.addWatch(path, sys_AGNOSTIC_EVENTS) -} - -// RemoveWatch removes path from the watched file set. -func (w *Watcher) removeWatch(path string) error { - w.mu.Lock() - defer w.mu.Unlock() - watch, ok := w.watches[path] - if !ok { - return errors.New(fmt.Sprintf("can't remove non-existent inotify watch for: %s", path)) - } - success, errno := syscall.InotifyRmWatch(w.fd, watch.wd) - if success == -1 { - return os.NewSyscallError("inotify_rm_watch", errno) - } - delete(w.watches, path) - return nil -} - -// readEvents reads from the inotify file descriptor, converts the -// received events into Event objects and sends them via the Event channel -func (w *Watcher) readEvents() { - var ( - buf [syscall.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events - n int // Number of bytes read with read() - errno error // Syscall errno - ) - - for { - // See if there is a message on the "done" channel - select { - case <-w.done: - syscall.Close(w.fd) - close(w.internalEvent) - close(w.Error) - return - default: - } - - n, errno = syscall.Read(w.fd, buf[:]) - - // If EOF is received - if n == 0 { - syscall.Close(w.fd) - close(w.internalEvent) - close(w.Error) - return - } - - if n < 0 { - w.Error <- os.NewSyscallError("read", errno) - continue - } - if n < syscall.SizeofInotifyEvent { - w.Error <- errors.New("inotify: short read in readEvents()") - continue - } - - var offset uint32 = 0 - // We don't know how many events we just read into the buffer - // While the offset points to at least one whole event... - for offset <= uint32(n-syscall.SizeofInotifyEvent) { - // Point "raw" to the event in the buffer - raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset])) - event := new(FileEvent) - event.mask = uint32(raw.Mask) - event.cookie = uint32(raw.Cookie) - nameLen := uint32(raw.Len) - // If the event happened to the watched directory or the watched file, the kernel - // doesn't append the filename to the event, but we would like to always fill the - // the "Name" field with a valid filename. We retrieve the path of the watch from - // the "paths" map. - w.mu.Lock() - event.Name = w.paths[int(raw.Wd)] - w.mu.Unlock() - watchedName := event.Name - if nameLen > 0 { - // Point "bytes" at the first byte of the filename - bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent])) - // The filename is padded with NUL bytes. TrimRight() gets rid of those. - event.Name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000") - } - - // Send the events that are not ignored on the events channel - if !event.ignoreLinux() { - // Setup FSNotify flags (inherit from directory watch) - w.fsnmut.Lock() - if _, fsnFound := w.fsnFlags[event.Name]; !fsnFound { - if fsnFlags, watchFound := w.fsnFlags[watchedName]; watchFound { - w.fsnFlags[event.Name] = fsnFlags - } else { - w.fsnFlags[event.Name] = FSN_ALL - } - } - w.fsnmut.Unlock() - - w.internalEvent <- event - } - - // Move to the next event in the buffer - offset += syscall.SizeofInotifyEvent + nameLen - } - } -} - -// Certain types of events can be "ignored" and not sent over the Event -// channel. Such as events marked ignore by the kernel, or MODIFY events -// against files that do not exist. -func (e *FileEvent) ignoreLinux() bool { - // Ignore anything the inotify API says to ignore - if e.mask&sys_IN_IGNORED == sys_IN_IGNORED { - return true - } - - // If the event is not a DELETE or RENAME, the file must exist. - // Otherwise the event is ignored. - // *Note*: this was put in place because it was seen that a MODIFY - // event was sent after the DELETE. This ignores that MODIFY and - // assumes a DELETE will come or has come if the file doesn't exist. - if !(e.IsDelete() || e.IsRename()) { - _, statErr := os.Lstat(e.Name) - return os.IsNotExist(statErr) - } - return false -} diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_open_bsd.go b/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_open_bsd.go deleted file mode 100644 index 37ea998..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_open_bsd.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build freebsd openbsd netbsd - -package fsnotify - -import "syscall" - -const open_FLAGS = syscall.O_NONBLOCK | syscall.O_RDONLY diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_open_darwin.go b/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_open_darwin.go deleted file mode 100644 index d450318..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_open_darwin.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin - -package fsnotify - -import "syscall" - -const open_FLAGS = syscall.O_EVTONLY diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_symlink_test.go b/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_symlink_test.go deleted file mode 100644 index 39061f8..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_symlink_test.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build freebsd openbsd netbsd darwin linux - -package fsnotify - -import ( - "os" - "path/filepath" - "testing" - "time" -) - -func TestFsnotifyFakeSymlink(t *testing.T) { - watcher := newWatcher(t) - - // Create directory to watch - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - var errorsReceived counter - // Receive errors on the error channel on a separate goroutine - go func() { - for errors := range watcher.Error { - t.Logf("Received error: %s", errors) - errorsReceived.increment() - } - }() - - // Count the CREATE events received - var createEventsReceived, otherEventsReceived counter - go func() { - for ev := range watcher.Event { - t.Logf("event received: %s", ev) - if ev.IsCreate() { - createEventsReceived.increment() - } else { - otherEventsReceived.increment() - } - } - }() - - addWatch(t, watcher, testDir) - - if err := os.Symlink(filepath.Join(testDir, "zzz"), filepath.Join(testDir, "zzznew")); err != nil { - t.Fatalf("Failed to create bogus symlink: %s", err) - } - t.Logf("Created bogus symlink") - - // We expect this event to be received almost immediately, but let's wait 500 ms to be sure - time.Sleep(500 * time.Millisecond) - - // Should not be error, just no events for broken links (watching nothing) - if errorsReceived.value() > 0 { - t.Fatal("fsnotify errors have been received.") - } - if otherEventsReceived.value() > 0 { - t.Fatal("fsnotify other events received on the broken link") - } - - // Except for 1 create event (for the link itself) - if createEventsReceived.value() == 0 { - t.Fatal("fsnotify create events were not received after 500 ms") - } - if createEventsReceived.value() > 1 { - t.Fatal("fsnotify more create events received than expected") - } - - // Try closing the fsnotify instance - t.Log("calling Close()") - watcher.Close() -} diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_test.go b/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_test.go deleted file mode 100644 index 3f5a648..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_test.go +++ /dev/null @@ -1,1010 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package fsnotify - -import ( - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "runtime" - "sync/atomic" - "testing" - "time" -) - -// An atomic counter -type counter struct { - val int32 -} - -func (c *counter) increment() { - atomic.AddInt32(&c.val, 1) -} - -func (c *counter) value() int32 { - return atomic.LoadInt32(&c.val) -} - -func (c *counter) reset() { - atomic.StoreInt32(&c.val, 0) -} - -// tempMkdir makes a temporary directory -func tempMkdir(t *testing.T) string { - dir, err := ioutil.TempDir("", "fsnotify") - if err != nil { - t.Fatalf("failed to create test directory: %s", err) - } - return dir -} - -// newWatcher initializes an fsnotify Watcher instance. -func newWatcher(t *testing.T) *Watcher { - watcher, err := NewWatcher() - if err != nil { - t.Fatalf("NewWatcher() failed: %s", err) - } - return watcher -} - -// addWatch adds a watch for a directory -func addWatch(t *testing.T, watcher *Watcher, dir string) { - if err := watcher.Watch(dir); err != nil { - t.Fatalf("watcher.Watch(%q) failed: %s", dir, err) - } -} - -func TestFsnotifyMultipleOperations(t *testing.T) { - watcher := newWatcher(t) - - // Receive errors on the error channel on a separate goroutine - go func() { - for err := range watcher.Error { - t.Fatalf("error received: %s", err) - } - }() - - // Create directory to watch - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - // Create directory that's not watched - testDirToMoveFiles := tempMkdir(t) - defer os.RemoveAll(testDirToMoveFiles) - - testFile := filepath.Join(testDir, "TestFsnotifySeq.testfile") - testFileRenamed := filepath.Join(testDirToMoveFiles, "TestFsnotifySeqRename.testfile") - - addWatch(t, watcher, testDir) - - // Receive events on the event channel on a separate goroutine - eventstream := watcher.Event - var createReceived, modifyReceived, deleteReceived, renameReceived counter - done := make(chan bool) - go func() { - for event := range eventstream { - // Only count relevant events - if event.Name == filepath.Clean(testDir) || event.Name == filepath.Clean(testFile) { - t.Logf("event received: %s", event) - if event.IsDelete() { - deleteReceived.increment() - } - if event.IsModify() { - modifyReceived.increment() - } - if event.IsCreate() { - createReceived.increment() - } - if event.IsRename() { - renameReceived.increment() - } - } else { - t.Logf("unexpected event received: %s", event) - } - } - done <- true - }() - - // Create a file - // This should add at least one event to the fsnotify event queue - var f *os.File - f, err := os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - - time.Sleep(time.Millisecond) - f.WriteString("data") - f.Sync() - f.Close() - - time.Sleep(50 * time.Millisecond) // give system time to sync write change before delete - - if err := testRename(testFile, testFileRenamed); err != nil { - t.Fatalf("rename failed: %s", err) - } - - // Modify the file outside of the watched dir - f, err = os.Open(testFileRenamed) - if err != nil { - t.Fatalf("open test renamed file failed: %s", err) - } - f.WriteString("data") - f.Sync() - f.Close() - - time.Sleep(50 * time.Millisecond) // give system time to sync write change before delete - - // Recreate the file that was moved - f, err = os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Close() - time.Sleep(50 * time.Millisecond) // give system time to sync write change before delete - - // We expect this event to be received almost immediately, but let's wait 500 ms to be sure - time.Sleep(500 * time.Millisecond) - cReceived := createReceived.value() - if cReceived != 2 { - t.Fatalf("incorrect number of create events received after 500 ms (%d vs %d)", cReceived, 2) - } - mReceived := modifyReceived.value() - if mReceived != 1 { - t.Fatalf("incorrect number of modify events received after 500 ms (%d vs %d)", mReceived, 1) - } - dReceived := deleteReceived.value() - rReceived := renameReceived.value() - if dReceived+rReceived != 1 { - t.Fatalf("incorrect number of rename+delete events received after 500 ms (%d vs %d)", rReceived+dReceived, 1) - } - - // Try closing the fsnotify instance - t.Log("calling Close()") - watcher.Close() - t.Log("waiting for the event channel to become closed...") - select { - case <-done: - t.Log("event channel closed") - case <-time.After(2 * time.Second): - t.Fatal("event stream was not closed after 2 seconds") - } -} - -func TestFsnotifyMultipleCreates(t *testing.T) { - watcher := newWatcher(t) - - // Receive errors on the error channel on a separate goroutine - go func() { - for err := range watcher.Error { - t.Fatalf("error received: %s", err) - } - }() - - // Create directory to watch - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - testFile := filepath.Join(testDir, "TestFsnotifySeq.testfile") - - addWatch(t, watcher, testDir) - - // Receive events on the event channel on a separate goroutine - eventstream := watcher.Event - var createReceived, modifyReceived, deleteReceived counter - done := make(chan bool) - go func() { - for event := range eventstream { - // Only count relevant events - if event.Name == filepath.Clean(testDir) || event.Name == filepath.Clean(testFile) { - t.Logf("event received: %s", event) - if event.IsDelete() { - deleteReceived.increment() - } - if event.IsCreate() { - createReceived.increment() - } - if event.IsModify() { - modifyReceived.increment() - } - } else { - t.Logf("unexpected event received: %s", event) - } - } - done <- true - }() - - // Create a file - // This should add at least one event to the fsnotify event queue - var f *os.File - f, err := os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - - time.Sleep(time.Millisecond) - f.WriteString("data") - f.Sync() - f.Close() - - time.Sleep(50 * time.Millisecond) // give system time to sync write change before delete - - os.Remove(testFile) - - time.Sleep(50 * time.Millisecond) // give system time to sync write change before delete - - // Recreate the file - f, err = os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Close() - time.Sleep(50 * time.Millisecond) // give system time to sync write change before delete - - // Modify - f, err = os.OpenFile(testFile, os.O_WRONLY, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - - time.Sleep(time.Millisecond) - f.WriteString("data") - f.Sync() - f.Close() - - time.Sleep(50 * time.Millisecond) // give system time to sync write change before delete - - // Modify - f, err = os.OpenFile(testFile, os.O_WRONLY, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - - time.Sleep(time.Millisecond) - f.WriteString("data") - f.Sync() - f.Close() - - time.Sleep(50 * time.Millisecond) // give system time to sync write change before delete - - // We expect this event to be received almost immediately, but let's wait 500 ms to be sure - time.Sleep(500 * time.Millisecond) - cReceived := createReceived.value() - if cReceived != 2 { - t.Fatalf("incorrect number of create events received after 500 ms (%d vs %d)", cReceived, 2) - } - mReceived := modifyReceived.value() - if mReceived < 3 { - t.Fatalf("incorrect number of modify events received after 500 ms (%d vs atleast %d)", mReceived, 3) - } - dReceived := deleteReceived.value() - if dReceived != 1 { - t.Fatalf("incorrect number of rename+delete events received after 500 ms (%d vs %d)", dReceived, 1) - } - - // Try closing the fsnotify instance - t.Log("calling Close()") - watcher.Close() - t.Log("waiting for the event channel to become closed...") - select { - case <-done: - t.Log("event channel closed") - case <-time.After(2 * time.Second): - t.Fatal("event stream was not closed after 2 seconds") - } -} - -func TestFsnotifyDirOnly(t *testing.T) { - watcher := newWatcher(t) - - // Create directory to watch - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - // Create a file before watching directory - // This should NOT add any events to the fsnotify event queue - testFileAlreadyExists := filepath.Join(testDir, "TestFsnotifyEventsExisting.testfile") - { - var f *os.File - f, err := os.OpenFile(testFileAlreadyExists, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - f.Close() - } - - addWatch(t, watcher, testDir) - - // Receive errors on the error channel on a separate goroutine - go func() { - for err := range watcher.Error { - t.Fatalf("error received: %s", err) - } - }() - - testFile := filepath.Join(testDir, "TestFsnotifyDirOnly.testfile") - - // Receive events on the event channel on a separate goroutine - eventstream := watcher.Event - var createReceived, modifyReceived, deleteReceived counter - done := make(chan bool) - go func() { - for event := range eventstream { - // Only count relevant events - if event.Name == filepath.Clean(testDir) || event.Name == filepath.Clean(testFile) || event.Name == filepath.Clean(testFileAlreadyExists) { - t.Logf("event received: %s", event) - if event.IsDelete() { - deleteReceived.increment() - } - if event.IsModify() { - modifyReceived.increment() - } - if event.IsCreate() { - createReceived.increment() - } - } else { - t.Logf("unexpected event received: %s", event) - } - } - done <- true - }() - - // Create a file - // This should add at least one event to the fsnotify event queue - var f *os.File - f, err := os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - - time.Sleep(time.Millisecond) - f.WriteString("data") - f.Sync() - f.Close() - - time.Sleep(50 * time.Millisecond) // give system time to sync write change before delete - - os.Remove(testFile) - os.Remove(testFileAlreadyExists) - - // We expect this event to be received almost immediately, but let's wait 500 ms to be sure - time.Sleep(500 * time.Millisecond) - cReceived := createReceived.value() - if cReceived != 1 { - t.Fatalf("incorrect number of create events received after 500 ms (%d vs %d)", cReceived, 1) - } - mReceived := modifyReceived.value() - if mReceived != 1 { - t.Fatalf("incorrect number of modify events received after 500 ms (%d vs %d)", mReceived, 1) - } - dReceived := deleteReceived.value() - if dReceived != 2 { - t.Fatalf("incorrect number of delete events received after 500 ms (%d vs %d)", dReceived, 2) - } - - // Try closing the fsnotify instance - t.Log("calling Close()") - watcher.Close() - t.Log("waiting for the event channel to become closed...") - select { - case <-done: - t.Log("event channel closed") - case <-time.After(2 * time.Second): - t.Fatal("event stream was not closed after 2 seconds") - } -} - -func TestFsnotifyDeleteWatchedDir(t *testing.T) { - watcher := newWatcher(t) - defer watcher.Close() - - // Create directory to watch - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - // Create a file before watching directory - testFileAlreadyExists := filepath.Join(testDir, "TestFsnotifyEventsExisting.testfile") - { - var f *os.File - f, err := os.OpenFile(testFileAlreadyExists, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - f.Close() - } - - addWatch(t, watcher, testDir) - - // Add a watch for testFile - addWatch(t, watcher, testFileAlreadyExists) - - // Receive errors on the error channel on a separate goroutine - go func() { - for err := range watcher.Error { - t.Fatalf("error received: %s", err) - } - }() - - // Receive events on the event channel on a separate goroutine - eventstream := watcher.Event - var deleteReceived counter - go func() { - for event := range eventstream { - // Only count relevant events - if event.Name == filepath.Clean(testDir) || event.Name == filepath.Clean(testFileAlreadyExists) { - t.Logf("event received: %s", event) - if event.IsDelete() { - deleteReceived.increment() - } - } else { - t.Logf("unexpected event received: %s", event) - } - } - }() - - os.RemoveAll(testDir) - - // We expect this event to be received almost immediately, but let's wait 500 ms to be sure - time.Sleep(500 * time.Millisecond) - dReceived := deleteReceived.value() - if dReceived < 2 { - t.Fatalf("did not receive at least %d delete events, received %d after 500 ms", 2, dReceived) - } -} - -func TestFsnotifySubDir(t *testing.T) { - watcher := newWatcher(t) - - // Create directory to watch - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - testFile1 := filepath.Join(testDir, "TestFsnotifyFile1.testfile") - testSubDir := filepath.Join(testDir, "sub") - testSubDirFile := filepath.Join(testDir, "sub/TestFsnotifyFile1.testfile") - - // Receive errors on the error channel on a separate goroutine - go func() { - for err := range watcher.Error { - t.Fatalf("error received: %s", err) - } - }() - - // Receive events on the event channel on a separate goroutine - eventstream := watcher.Event - var createReceived, deleteReceived counter - done := make(chan bool) - go func() { - for event := range eventstream { - // Only count relevant events - if event.Name == filepath.Clean(testDir) || event.Name == filepath.Clean(testSubDir) || event.Name == filepath.Clean(testFile1) { - t.Logf("event received: %s", event) - if event.IsCreate() { - createReceived.increment() - } - if event.IsDelete() { - deleteReceived.increment() - } - } else { - t.Logf("unexpected event received: %s", event) - } - } - done <- true - }() - - addWatch(t, watcher, testDir) - - // Create sub-directory - if err := os.Mkdir(testSubDir, 0777); err != nil { - t.Fatalf("failed to create test sub-directory: %s", err) - } - - // Create a file - var f *os.File - f, err := os.OpenFile(testFile1, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - f.Close() - - // Create a file (Should not see this! we are not watching subdir) - var fs *os.File - fs, err = os.OpenFile(testSubDirFile, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - fs.Sync() - fs.Close() - - time.Sleep(200 * time.Millisecond) - - // Make sure receive deletes for both file and sub-directory - os.RemoveAll(testSubDir) - os.Remove(testFile1) - - // We expect this event to be received almost immediately, but let's wait 500 ms to be sure - time.Sleep(500 * time.Millisecond) - cReceived := createReceived.value() - if cReceived != 2 { - t.Fatalf("incorrect number of create events received after 500 ms (%d vs %d)", cReceived, 2) - } - dReceived := deleteReceived.value() - if dReceived != 2 { - t.Fatalf("incorrect number of delete events received after 500 ms (%d vs %d)", dReceived, 2) - } - - // Try closing the fsnotify instance - t.Log("calling Close()") - watcher.Close() - t.Log("waiting for the event channel to become closed...") - select { - case <-done: - t.Log("event channel closed") - case <-time.After(2 * time.Second): - t.Fatal("event stream was not closed after 2 seconds") - } -} - -func TestFsnotifyRename(t *testing.T) { - watcher := newWatcher(t) - - // Create directory to watch - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - addWatch(t, watcher, testDir) - - // Receive errors on the error channel on a separate goroutine - go func() { - for err := range watcher.Error { - t.Fatalf("error received: %s", err) - } - }() - - testFile := filepath.Join(testDir, "TestFsnotifyEvents.testfile") - testFileRenamed := filepath.Join(testDir, "TestFsnotifyEvents.testfileRenamed") - - // Receive events on the event channel on a separate goroutine - eventstream := watcher.Event - var renameReceived counter - done := make(chan bool) - go func() { - for event := range eventstream { - // Only count relevant events - if event.Name == filepath.Clean(testDir) || event.Name == filepath.Clean(testFile) || event.Name == filepath.Clean(testFileRenamed) { - if event.IsRename() { - renameReceived.increment() - } - t.Logf("event received: %s", event) - } else { - t.Logf("unexpected event received: %s", event) - } - } - done <- true - }() - - // Create a file - // This should add at least one event to the fsnotify event queue - var f *os.File - f, err := os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - - f.WriteString("data") - f.Sync() - f.Close() - - // Add a watch for testFile - addWatch(t, watcher, testFile) - - if err := testRename(testFile, testFileRenamed); err != nil { - t.Fatalf("rename failed: %s", err) - } - - // We expect this event to be received almost immediately, but let's wait 500 ms to be sure - time.Sleep(500 * time.Millisecond) - if renameReceived.value() == 0 { - t.Fatal("fsnotify rename events have not been received after 500 ms") - } - - // Try closing the fsnotify instance - t.Log("calling Close()") - watcher.Close() - t.Log("waiting for the event channel to become closed...") - select { - case <-done: - t.Log("event channel closed") - case <-time.After(2 * time.Second): - t.Fatal("event stream was not closed after 2 seconds") - } - - os.Remove(testFileRenamed) -} - -func TestFsnotifyRenameToCreate(t *testing.T) { - watcher := newWatcher(t) - - // Create directory to watch - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - // Create directory to get file - testDirFrom := tempMkdir(t) - defer os.RemoveAll(testDirFrom) - - addWatch(t, watcher, testDir) - - // Receive errors on the error channel on a separate goroutine - go func() { - for err := range watcher.Error { - t.Fatalf("error received: %s", err) - } - }() - - testFile := filepath.Join(testDirFrom, "TestFsnotifyEvents.testfile") - testFileRenamed := filepath.Join(testDir, "TestFsnotifyEvents.testfileRenamed") - - // Receive events on the event channel on a separate goroutine - eventstream := watcher.Event - var createReceived counter - done := make(chan bool) - go func() { - for event := range eventstream { - // Only count relevant events - if event.Name == filepath.Clean(testDir) || event.Name == filepath.Clean(testFile) || event.Name == filepath.Clean(testFileRenamed) { - if event.IsCreate() { - createReceived.increment() - } - t.Logf("event received: %s", event) - } else { - t.Logf("unexpected event received: %s", event) - } - } - done <- true - }() - - // Create a file - // This should add at least one event to the fsnotify event queue - var f *os.File - f, err := os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - f.Close() - - if err := testRename(testFile, testFileRenamed); err != nil { - t.Fatalf("rename failed: %s", err) - } - - // We expect this event to be received almost immediately, but let's wait 500 ms to be sure - time.Sleep(500 * time.Millisecond) - if createReceived.value() == 0 { - t.Fatal("fsnotify create events have not been received after 500 ms") - } - - // Try closing the fsnotify instance - t.Log("calling Close()") - watcher.Close() - t.Log("waiting for the event channel to become closed...") - select { - case <-done: - t.Log("event channel closed") - case <-time.After(2 * time.Second): - t.Fatal("event stream was not closed after 2 seconds") - } - - os.Remove(testFileRenamed) -} - -func TestFsnotifyRenameToOverwrite(t *testing.T) { - switch runtime.GOOS { - case "plan9", "windows": - t.Skipf("skipping test on %q (os.Rename over existing file does not create event).", runtime.GOOS) - } - - watcher := newWatcher(t) - - // Create directory to watch - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - // Create directory to get file - testDirFrom := tempMkdir(t) - defer os.RemoveAll(testDirFrom) - - testFile := filepath.Join(testDirFrom, "TestFsnotifyEvents.testfile") - testFileRenamed := filepath.Join(testDir, "TestFsnotifyEvents.testfileRenamed") - - // Create a file - var fr *os.File - fr, err := os.OpenFile(testFileRenamed, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - fr.Sync() - fr.Close() - - addWatch(t, watcher, testDir) - - // Receive errors on the error channel on a separate goroutine - go func() { - for err := range watcher.Error { - t.Fatalf("error received: %s", err) - } - }() - - // Receive events on the event channel on a separate goroutine - eventstream := watcher.Event - var eventReceived counter - done := make(chan bool) - go func() { - for event := range eventstream { - // Only count relevant events - if event.Name == filepath.Clean(testFileRenamed) { - eventReceived.increment() - t.Logf("event received: %s", event) - } else { - t.Logf("unexpected event received: %s", event) - } - } - done <- true - }() - - // Create a file - // This should add at least one event to the fsnotify event queue - var f *os.File - f, err = os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - f.Close() - - if err := testRename(testFile, testFileRenamed); err != nil { - t.Fatalf("rename failed: %s", err) - } - - // We expect this event to be received almost immediately, but let's wait 500 ms to be sure - time.Sleep(500 * time.Millisecond) - if eventReceived.value() == 0 { - t.Fatal("fsnotify events have not been received after 500 ms") - } - - // Try closing the fsnotify instance - t.Log("calling Close()") - watcher.Close() - t.Log("waiting for the event channel to become closed...") - select { - case <-done: - t.Log("event channel closed") - case <-time.After(2 * time.Second): - t.Fatal("event stream was not closed after 2 seconds") - } - - os.Remove(testFileRenamed) -} - -func TestRemovalOfWatch(t *testing.T) { - // Create directory to watch - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - // Create a file before watching directory - testFileAlreadyExists := filepath.Join(testDir, "TestFsnotifyEventsExisting.testfile") - { - var f *os.File - f, err := os.OpenFile(testFileAlreadyExists, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - f.Close() - } - - watcher := newWatcher(t) - defer watcher.Close() - - addWatch(t, watcher, testDir) - if err := watcher.RemoveWatch(testDir); err != nil { - t.Fatalf("Could not remove the watch: %v\n", err) - } - - go func() { - select { - case ev := <-watcher.Event: - t.Fatalf("We received event: %v\n", ev) - case <-time.After(500 * time.Millisecond): - t.Log("No event received, as expected.") - } - }() - - time.Sleep(200 * time.Millisecond) - // Modify the file outside of the watched dir - f, err := os.Open(testFileAlreadyExists) - if err != nil { - t.Fatalf("Open test file failed: %s", err) - } - f.WriteString("data") - f.Sync() - f.Close() - if err := os.Chmod(testFileAlreadyExists, 0700); err != nil { - t.Fatalf("chmod failed: %s", err) - } - time.Sleep(400 * time.Millisecond) -} - -func TestFsnotifyAttrib(t *testing.T) { - if runtime.GOOS == "windows" { - t.Skip("attributes don't work on Windows.") - } - - watcher := newWatcher(t) - - // Create directory to watch - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - // Receive errors on the error channel on a separate goroutine - go func() { - for err := range watcher.Error { - t.Fatalf("error received: %s", err) - } - }() - - testFile := filepath.Join(testDir, "TestFsnotifyAttrib.testfile") - - // Receive events on the event channel on a separate goroutine - eventstream := watcher.Event - // The modifyReceived counter counts IsModify events that are not IsAttrib, - // and the attribReceived counts IsAttrib events (which are also IsModify as - // a consequence). - var modifyReceived counter - var attribReceived counter - done := make(chan bool) - go func() { - for event := range eventstream { - // Only count relevant events - if event.Name == filepath.Clean(testDir) || event.Name == filepath.Clean(testFile) { - if event.IsModify() { - modifyReceived.increment() - } - if event.IsAttrib() { - attribReceived.increment() - } - t.Logf("event received: %s", event) - } else { - t.Logf("unexpected event received: %s", event) - } - } - done <- true - }() - - // Create a file - // This should add at least one event to the fsnotify event queue - var f *os.File - f, err := os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - t.Fatalf("creating test file failed: %s", err) - } - f.Sync() - - f.WriteString("data") - f.Sync() - f.Close() - - // Add a watch for testFile - addWatch(t, watcher, testFile) - - if err := os.Chmod(testFile, 0700); err != nil { - t.Fatalf("chmod failed: %s", err) - } - - // We expect this event to be received almost immediately, but let's wait 500 ms to be sure - // Creating/writing a file changes also the mtime, so IsAttrib should be set to true here - time.Sleep(500 * time.Millisecond) - if modifyReceived.value() == 0 { - t.Fatal("fsnotify modify events have not received after 500 ms") - } - if attribReceived.value() == 0 { - t.Fatal("fsnotify attribute events have not received after 500 ms") - } - - // Modifying the contents of the file does not set the attrib flag (although eg. the mtime - // might have been modified). - modifyReceived.reset() - attribReceived.reset() - - f, err = os.OpenFile(testFile, os.O_WRONLY, 0) - if err != nil { - t.Fatalf("reopening test file failed: %s", err) - } - - f.WriteString("more data") - f.Sync() - f.Close() - - time.Sleep(500 * time.Millisecond) - - if modifyReceived.value() != 1 { - t.Fatal("didn't receive a modify event after changing test file contents") - } - - if attribReceived.value() != 0 { - t.Fatal("did receive an unexpected attrib event after changing test file contents") - } - - modifyReceived.reset() - attribReceived.reset() - - // Doing a chmod on the file should trigger an event with the "attrib" flag set (the contents - // of the file are not changed though) - if err := os.Chmod(testFile, 0600); err != nil { - t.Fatalf("chmod failed: %s", err) - } - - time.Sleep(500 * time.Millisecond) - - if attribReceived.value() != 1 { - t.Fatal("didn't receive an attribute change after 500ms") - } - - // Try closing the fsnotify instance - t.Log("calling Close()") - watcher.Close() - t.Log("waiting for the event channel to become closed...") - select { - case <-done: - t.Log("event channel closed") - case <-time.After(1e9): - t.Fatal("event stream was not closed after 1 second") - } - - os.Remove(testFile) -} - -func TestFsnotifyClose(t *testing.T) { - watcher := newWatcher(t) - watcher.Close() - - var done int32 - go func() { - watcher.Close() - atomic.StoreInt32(&done, 1) - }() - - time.Sleep(50e6) // 50 ms - if atomic.LoadInt32(&done) == 0 { - t.Fatal("double Close() test failed: second Close() call didn't return") - } - - testDir := tempMkdir(t) - defer os.RemoveAll(testDir) - - if err := watcher.Watch(testDir); err == nil { - t.Fatal("expected error on Watch() after Close(), got nil") - } -} - -func testRename(file1, file2 string) error { - switch runtime.GOOS { - case "windows", "plan9": - return os.Rename(file1, file2) - default: - cmd := exec.Command("mv", file1, file2) - return cmd.Run() - } -} diff --git a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_windows.go b/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_windows.go deleted file mode 100644 index d88ae63..0000000 --- a/Godeps/_workspace/src/github.com/howeyc/fsnotify/fsnotify_windows.go +++ /dev/null @@ -1,598 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build windows - -package fsnotify - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "runtime" - "sync" - "syscall" - "unsafe" -) - -const ( - // Options for AddWatch - sys_FS_ONESHOT = 0x80000000 - sys_FS_ONLYDIR = 0x1000000 - - // Events - sys_FS_ACCESS = 0x1 - sys_FS_ALL_EVENTS = 0xfff - sys_FS_ATTRIB = 0x4 - sys_FS_CLOSE = 0x18 - sys_FS_CREATE = 0x100 - sys_FS_DELETE = 0x200 - sys_FS_DELETE_SELF = 0x400 - sys_FS_MODIFY = 0x2 - sys_FS_MOVE = 0xc0 - sys_FS_MOVED_FROM = 0x40 - sys_FS_MOVED_TO = 0x80 - sys_FS_MOVE_SELF = 0x800 - - // Special events - sys_FS_IGNORED = 0x8000 - sys_FS_Q_OVERFLOW = 0x4000 -) - -const ( - // TODO(nj): Use syscall.ERROR_MORE_DATA from ztypes_windows in Go 1.3+ - sys_ERROR_MORE_DATA syscall.Errno = 234 -) - -// Event is the type of the notification messages -// received on the watcher's Event channel. -type FileEvent struct { - mask uint32 // Mask of events - cookie uint32 // Unique cookie associating related events (for rename) - Name string // File name (optional) -} - -// IsCreate reports whether the FileEvent was triggered by a creation -func (e *FileEvent) IsCreate() bool { return (e.mask & sys_FS_CREATE) == sys_FS_CREATE } - -// IsDelete reports whether the FileEvent was triggered by a delete -func (e *FileEvent) IsDelete() bool { - return ((e.mask&sys_FS_DELETE) == sys_FS_DELETE || (e.mask&sys_FS_DELETE_SELF) == sys_FS_DELETE_SELF) -} - -// IsModify reports whether the FileEvent was triggered by a file modification or attribute change -func (e *FileEvent) IsModify() bool { - return ((e.mask&sys_FS_MODIFY) == sys_FS_MODIFY || (e.mask&sys_FS_ATTRIB) == sys_FS_ATTRIB) -} - -// IsRename reports whether the FileEvent was triggered by a change name -func (e *FileEvent) IsRename() bool { - return ((e.mask&sys_FS_MOVE) == sys_FS_MOVE || (e.mask&sys_FS_MOVE_SELF) == sys_FS_MOVE_SELF || (e.mask&sys_FS_MOVED_FROM) == sys_FS_MOVED_FROM || (e.mask&sys_FS_MOVED_TO) == sys_FS_MOVED_TO) -} - -// IsAttrib reports whether the FileEvent was triggered by a change in the file metadata. -func (e *FileEvent) IsAttrib() bool { - return (e.mask & sys_FS_ATTRIB) == sys_FS_ATTRIB -} - -const ( - opAddWatch = iota - opRemoveWatch -) - -const ( - provisional uint64 = 1 << (32 + iota) -) - -type input struct { - op int - path string - flags uint32 - reply chan error -} - -type inode struct { - handle syscall.Handle - volume uint32 - index uint64 -} - -type watch struct { - ov syscall.Overlapped - ino *inode // i-number - path string // Directory path - mask uint64 // Directory itself is being watched with these notify flags - names map[string]uint64 // Map of names being watched and their notify flags - rename string // Remembers the old name while renaming a file - buf [4096]byte -} - -type indexMap map[uint64]*watch -type watchMap map[uint32]indexMap - -// A Watcher waits for and receives event notifications -// for a specific set of files and directories. -type Watcher struct { - mu sync.Mutex // Map access - port syscall.Handle // Handle to completion port - watches watchMap // Map of watches (key: i-number) - fsnFlags map[string]uint32 // Map of watched files to flags used for filter - fsnmut sync.Mutex // Protects access to fsnFlags. - input chan *input // Inputs to the reader are sent on this channel - internalEvent chan *FileEvent // Events are queued on this channel - Event chan *FileEvent // Events are returned on this channel - Error chan error // Errors are sent on this channel - isClosed bool // Set to true when Close() is first called - quit chan chan<- error - cookie uint32 -} - -// NewWatcher creates and returns a Watcher. -func NewWatcher() (*Watcher, error) { - port, e := syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 0) - if e != nil { - return nil, os.NewSyscallError("CreateIoCompletionPort", e) - } - w := &Watcher{ - port: port, - watches: make(watchMap), - fsnFlags: make(map[string]uint32), - input: make(chan *input, 1), - Event: make(chan *FileEvent, 50), - internalEvent: make(chan *FileEvent), - Error: make(chan error), - quit: make(chan chan<- error, 1), - } - go w.readEvents() - go w.purgeEvents() - return w, nil -} - -// Close closes a Watcher. -// It sends a message to the reader goroutine to quit and removes all watches -// associated with the watcher. -func (w *Watcher) Close() error { - if w.isClosed { - return nil - } - w.isClosed = true - - // Send "quit" message to the reader goroutine - ch := make(chan error) - w.quit <- ch - if err := w.wakeupReader(); err != nil { - return err - } - return <-ch -} - -// AddWatch adds path to the watched file set. -func (w *Watcher) AddWatch(path string, flags uint32) error { - if w.isClosed { - return errors.New("watcher already closed") - } - in := &input{ - op: opAddWatch, - path: filepath.Clean(path), - flags: flags, - reply: make(chan error), - } - w.input <- in - if err := w.wakeupReader(); err != nil { - return err - } - return <-in.reply -} - -// Watch adds path to the watched file set, watching all events. -func (w *Watcher) watch(path string) error { - return w.AddWatch(path, sys_FS_ALL_EVENTS) -} - -// RemoveWatch removes path from the watched file set. -func (w *Watcher) removeWatch(path string) error { - in := &input{ - op: opRemoveWatch, - path: filepath.Clean(path), - reply: make(chan error), - } - w.input <- in - if err := w.wakeupReader(); err != nil { - return err - } - return <-in.reply -} - -func (w *Watcher) wakeupReader() error { - e := syscall.PostQueuedCompletionStatus(w.port, 0, 0, nil) - if e != nil { - return os.NewSyscallError("PostQueuedCompletionStatus", e) - } - return nil -} - -func getDir(pathname string) (dir string, err error) { - attr, e := syscall.GetFileAttributes(syscall.StringToUTF16Ptr(pathname)) - if e != nil { - return "", os.NewSyscallError("GetFileAttributes", e) - } - if attr&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 { - dir = pathname - } else { - dir, _ = filepath.Split(pathname) - dir = filepath.Clean(dir) - } - return -} - -func getIno(path string) (ino *inode, err error) { - h, e := syscall.CreateFile(syscall.StringToUTF16Ptr(path), - syscall.FILE_LIST_DIRECTORY, - syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, - nil, syscall.OPEN_EXISTING, - syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, 0) - if e != nil { - return nil, os.NewSyscallError("CreateFile", e) - } - var fi syscall.ByHandleFileInformation - if e = syscall.GetFileInformationByHandle(h, &fi); e != nil { - syscall.CloseHandle(h) - return nil, os.NewSyscallError("GetFileInformationByHandle", e) - } - ino = &inode{ - handle: h, - volume: fi.VolumeSerialNumber, - index: uint64(fi.FileIndexHigh)<<32 | uint64(fi.FileIndexLow), - } - return ino, nil -} - -// Must run within the I/O thread. -func (m watchMap) get(ino *inode) *watch { - if i := m[ino.volume]; i != nil { - return i[ino.index] - } - return nil -} - -// Must run within the I/O thread. -func (m watchMap) set(ino *inode, watch *watch) { - i := m[ino.volume] - if i == nil { - i = make(indexMap) - m[ino.volume] = i - } - i[ino.index] = watch -} - -// Must run within the I/O thread. -func (w *Watcher) addWatch(pathname string, flags uint64) error { - dir, err := getDir(pathname) - if err != nil { - return err - } - if flags&sys_FS_ONLYDIR != 0 && pathname != dir { - return nil - } - ino, err := getIno(dir) - if err != nil { - return err - } - w.mu.Lock() - watchEntry := w.watches.get(ino) - w.mu.Unlock() - if watchEntry == nil { - if _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != nil { - syscall.CloseHandle(ino.handle) - return os.NewSyscallError("CreateIoCompletionPort", e) - } - watchEntry = &watch{ - ino: ino, - path: dir, - names: make(map[string]uint64), - } - w.mu.Lock() - w.watches.set(ino, watchEntry) - w.mu.Unlock() - flags |= provisional - } else { - syscall.CloseHandle(ino.handle) - } - if pathname == dir { - watchEntry.mask |= flags - } else { - watchEntry.names[filepath.Base(pathname)] |= flags - } - if err = w.startRead(watchEntry); err != nil { - return err - } - if pathname == dir { - watchEntry.mask &= ^provisional - } else { - watchEntry.names[filepath.Base(pathname)] &= ^provisional - } - return nil -} - -// Must run within the I/O thread. -func (w *Watcher) remWatch(pathname string) error { - dir, err := getDir(pathname) - if err != nil { - return err - } - ino, err := getIno(dir) - if err != nil { - return err - } - w.mu.Lock() - watch := w.watches.get(ino) - w.mu.Unlock() - if watch == nil { - return fmt.Errorf("can't remove non-existent watch for: %s", pathname) - } - if pathname == dir { - w.sendEvent(watch.path, watch.mask&sys_FS_IGNORED) - watch.mask = 0 - } else { - name := filepath.Base(pathname) - w.sendEvent(watch.path+"\\"+name, watch.names[name]&sys_FS_IGNORED) - delete(watch.names, name) - } - return w.startRead(watch) -} - -// Must run within the I/O thread. -func (w *Watcher) deleteWatch(watch *watch) { - for name, mask := range watch.names { - if mask&provisional == 0 { - w.sendEvent(watch.path+"\\"+name, mask&sys_FS_IGNORED) - } - delete(watch.names, name) - } - if watch.mask != 0 { - if watch.mask&provisional == 0 { - w.sendEvent(watch.path, watch.mask&sys_FS_IGNORED) - } - watch.mask = 0 - } -} - -// Must run within the I/O thread. -func (w *Watcher) startRead(watch *watch) error { - if e := syscall.CancelIo(watch.ino.handle); e != nil { - w.Error <- os.NewSyscallError("CancelIo", e) - w.deleteWatch(watch) - } - mask := toWindowsFlags(watch.mask) - for _, m := range watch.names { - mask |= toWindowsFlags(m) - } - if mask == 0 { - if e := syscall.CloseHandle(watch.ino.handle); e != nil { - w.Error <- os.NewSyscallError("CloseHandle", e) - } - w.mu.Lock() - delete(w.watches[watch.ino.volume], watch.ino.index) - w.mu.Unlock() - return nil - } - e := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0], - uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0) - if e != nil { - err := os.NewSyscallError("ReadDirectoryChanges", e) - if e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 { - // Watched directory was probably removed - if w.sendEvent(watch.path, watch.mask&sys_FS_DELETE_SELF) { - if watch.mask&sys_FS_ONESHOT != 0 { - watch.mask = 0 - } - } - err = nil - } - w.deleteWatch(watch) - w.startRead(watch) - return err - } - return nil -} - -// readEvents reads from the I/O completion port, converts the -// received events into Event objects and sends them via the Event channel. -// Entry point to the I/O thread. -func (w *Watcher) readEvents() { - var ( - n, key uint32 - ov *syscall.Overlapped - ) - runtime.LockOSThread() - - for { - e := syscall.GetQueuedCompletionStatus(w.port, &n, &key, &ov, syscall.INFINITE) - watch := (*watch)(unsafe.Pointer(ov)) - - if watch == nil { - select { - case ch := <-w.quit: - w.mu.Lock() - var indexes []indexMap - for _, index := range w.watches { - indexes = append(indexes, index) - } - w.mu.Unlock() - for _, index := range indexes { - for _, watch := range index { - w.deleteWatch(watch) - w.startRead(watch) - } - } - var err error - if e := syscall.CloseHandle(w.port); e != nil { - err = os.NewSyscallError("CloseHandle", e) - } - close(w.internalEvent) - close(w.Error) - ch <- err - return - case in := <-w.input: - switch in.op { - case opAddWatch: - in.reply <- w.addWatch(in.path, uint64(in.flags)) - case opRemoveWatch: - in.reply <- w.remWatch(in.path) - } - default: - } - continue - } - - switch e { - case sys_ERROR_MORE_DATA: - if watch == nil { - w.Error <- errors.New("ERROR_MORE_DATA has unexpectedly null lpOverlapped buffer") - } else { - // The i/o succeeded but the buffer is full. - // In theory we should be building up a full packet. - // In practice we can get away with just carrying on. - n = uint32(unsafe.Sizeof(watch.buf)) - } - case syscall.ERROR_ACCESS_DENIED: - // Watched directory was probably removed - w.sendEvent(watch.path, watch.mask&sys_FS_DELETE_SELF) - w.deleteWatch(watch) - w.startRead(watch) - continue - case syscall.ERROR_OPERATION_ABORTED: - // CancelIo was called on this handle - continue - default: - w.Error <- os.NewSyscallError("GetQueuedCompletionPort", e) - continue - case nil: - } - - var offset uint32 - for { - if n == 0 { - w.internalEvent <- &FileEvent{mask: sys_FS_Q_OVERFLOW} - w.Error <- errors.New("short read in readEvents()") - break - } - - // Point "raw" to the event in the buffer - raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset])) - buf := (*[syscall.MAX_PATH]uint16)(unsafe.Pointer(&raw.FileName)) - name := syscall.UTF16ToString(buf[:raw.FileNameLength/2]) - fullname := watch.path + "\\" + name - - var mask uint64 - switch raw.Action { - case syscall.FILE_ACTION_REMOVED: - mask = sys_FS_DELETE_SELF - case syscall.FILE_ACTION_MODIFIED: - mask = sys_FS_MODIFY - case syscall.FILE_ACTION_RENAMED_OLD_NAME: - watch.rename = name - case syscall.FILE_ACTION_RENAMED_NEW_NAME: - if watch.names[watch.rename] != 0 { - watch.names[name] |= watch.names[watch.rename] - delete(watch.names, watch.rename) - mask = sys_FS_MOVE_SELF - } - } - - sendNameEvent := func() { - if w.sendEvent(fullname, watch.names[name]&mask) { - if watch.names[name]&sys_FS_ONESHOT != 0 { - delete(watch.names, name) - } - } - } - if raw.Action != syscall.FILE_ACTION_RENAMED_NEW_NAME { - sendNameEvent() - } - if raw.Action == syscall.FILE_ACTION_REMOVED { - w.sendEvent(fullname, watch.names[name]&sys_FS_IGNORED) - delete(watch.names, name) - } - if w.sendEvent(fullname, watch.mask&toFSnotifyFlags(raw.Action)) { - if watch.mask&sys_FS_ONESHOT != 0 { - watch.mask = 0 - } - } - if raw.Action == syscall.FILE_ACTION_RENAMED_NEW_NAME { - fullname = watch.path + "\\" + watch.rename - sendNameEvent() - } - - // Move to the next event in the buffer - if raw.NextEntryOffset == 0 { - break - } - offset += raw.NextEntryOffset - - // Error! - if offset >= n { - w.Error <- errors.New("Windows system assumed buffer larger than it is, events have likely been missed.") - break - } - } - - if err := w.startRead(watch); err != nil { - w.Error <- err - } - } -} - -func (w *Watcher) sendEvent(name string, mask uint64) bool { - if mask == 0 { - return false - } - event := &FileEvent{mask: uint32(mask), Name: name} - if mask&sys_FS_MOVE != 0 { - if mask&sys_FS_MOVED_FROM != 0 { - w.cookie++ - } - event.cookie = w.cookie - } - select { - case ch := <-w.quit: - w.quit <- ch - case w.Event <- event: - } - return true -} - -func toWindowsFlags(mask uint64) uint32 { - var m uint32 - if mask&sys_FS_ACCESS != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_LAST_ACCESS - } - if mask&sys_FS_MODIFY != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_LAST_WRITE - } - if mask&sys_FS_ATTRIB != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_ATTRIBUTES - } - if mask&(sys_FS_MOVE|sys_FS_CREATE|sys_FS_DELETE) != 0 { - m |= syscall.FILE_NOTIFY_CHANGE_FILE_NAME | syscall.FILE_NOTIFY_CHANGE_DIR_NAME - } - return m -} - -func toFSnotifyFlags(action uint32) uint64 { - switch action { - case syscall.FILE_ACTION_ADDED: - return sys_FS_CREATE - case syscall.FILE_ACTION_REMOVED: - return sys_FS_DELETE - case syscall.FILE_ACTION_MODIFIED: - return sys_FS_MODIFY - case syscall.FILE_ACTION_RENAMED_OLD_NAME: - return sys_FS_MOVED_FROM - case syscall.FILE_ACTION_RENAMED_NEW_NAME: - return sys_FS_MOVED_TO - } - return 0 -} diff --git a/Godeps/_workspace/src/github.com/oleksandr/fbp/LICENSE b/Godeps/_workspace/src/github.com/oleksandr/fbp/LICENSE deleted file mode 100644 index 0c82131..0000000 --- a/Godeps/_workspace/src/github.com/oleksandr/fbp/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Oleksandr Lobunets - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/oleksandr/fbp/README.md b/Godeps/_workspace/src/github.com/oleksandr/fbp/README.md deleted file mode 100644 index 448d933..0000000 --- a/Godeps/_workspace/src/github.com/oleksandr/fbp/README.md +++ /dev/null @@ -1,55 +0,0 @@ -NoFlo's FBP DSL parser for Go -=== - -A Go parser for .FBP DSL language from NoFlo - -Dependencies ---- - -This is optional. If you want to update the parser's code based on the grammer.peg you need to install the following dependency: - - go get github.com/pointlander/peg - -This will download and compile _peg_ binary, which you can use later to generate the parser. - -The following command will generate the parser: - - peg -switch -inline grammar.peg - -Installation ---- - -Use regular _go install_ or _go get_ command to download and install the _fbp_ library: - - go get github.com/oleksandr/fbp - -The library already includes the generated parser. - -Basic usage ---- - - import "github.com/oleksandr/fbp" - - var graph string = ` - '5s' -> INTERVAL Ticker(core/ticker) OUT -> IN Forward(core/passthru) - Forward OUT -> IN Log(core/console)` - - parser := &fbp.Fbp{Buffer: graph} - parser.Init() - err := parser.Parse() - if err != nil { - t.Log(err.Error()) - t.Fail() - } - parser.Execute() - if err = parser.Validate(); err != nil { - t.Log(err.Error()) - t.Fail() - } - - // At this point you have parser.Processes, parser.Connections, - // parser.Inports and parser.Outports data structures... - - - - diff --git a/Godeps/_workspace/src/github.com/oleksandr/fbp/grammar.peg b/Godeps/_workspace/src/github.com/oleksandr/fbp/grammar.peg deleted file mode 100644 index 15a2a45..0000000 --- a/Godeps/_workspace/src/github.com/oleksandr/fbp/grammar.peg +++ /dev/null @@ -1,86 +0,0 @@ -package fbp - -type Fbp Peg { - BaseFbp -} - -start <- line* _ !. - -line <- - _ "EXPORT=" [A-Za-z.0-9_]+ ":" [A-Z0-9_]+ _ LineTerminator? - / _ "INPORT=" <[A-Za-z0-9_]+ "." [A-Z0-9_\[\]]+ ":" [A-Z0-9_]+> _ LineTerminator? { p.createInport(buffer[begin:end]) } - / _ "OUTPORT=" <[A-Za-z0-9_]+ "." [A-Z0-9_\[\]]+ ":" [A-Z0-9_]+> _ LineTerminator? { p.createOutport(buffer[begin:end]) } - / comment [\n\r]? - / _ [\n\r] - / _ connection _ LineTerminator? - -LineTerminator <- _ ","? comment? [\n\r]? - -comment <- _ "#" anychar* - -connection <- - ( - ( - bridge - _ "->" _ - connection - ) - / bridge - ) - -bridge <- - ( - port _ { p.inPort = p.port; p.inPortIndex = p.index } - node _ - port { p.outPort = p.port; p.outPortIndex = p.index } - ) { p.createMiddlet() } - / iip - / leftlet { p.createLeftlet() } - / rightlet { p.createRightlet() } - -leftlet <- - (node _ portWithIndex) - / - (node _ port) - -iip <- "'" "'" { p.iip = buffer[begin:end] } - -rightlet <- - (portWithIndex _ node) - / - (port _ node) - -node <- - ( - <[a-zA-Z0-9_]+> { p.nodeProcessName = buffer[begin:end] } - component? - ) { p.createNode() } - -component <- - "(" - <[a-zA-Z/\-0-9_]*> { p.nodeComponentName = buffer[begin:end] } - compMeta? - ")" - -compMeta <- ":" <[a-zA-Z/=_,0-9]+> { p.nodeMeta = buffer[begin:end] } - -port <- <[A-Z.0-9_]+> __ { p.port = buffer[begin:end] } - -portWithIndex <- - ( - <[A-Z.0-9_]+> { p.port = buffer[begin:end] } - "[" - <[0-9]+> { p.index = buffer[begin:end] } - "]" - __ - ) - -anychar <- [^\n\r] - -iipchar <- - [\\]['] - / [^'] - -_ <- [ \t]* - -__ <- [ \t]+ diff --git a/Godeps/_workspace/src/github.com/oleksandr/fbp/grammar.peg.go b/Godeps/_workspace/src/github.com/oleksandr/fbp/grammar.peg.go deleted file mode 100644 index 5de7fc5..0000000 --- a/Godeps/_workspace/src/github.com/oleksandr/fbp/grammar.peg.go +++ /dev/null @@ -1,2844 +0,0 @@ -package fbp - -import ( - "fmt" - "math" - "sort" - "strconv" -) - -const end_symbol rune = 4 - -/* The rule types inferred from the grammar are below. */ -type pegRule uint8 - -const ( - ruleUnknown pegRule = iota - rulestart - ruleline - ruleLineTerminator - rulecomment - ruleconnection - rulebridge - ruleleftlet - ruleiip - rulerightlet - rulenode - rulecomponent - rulecompMeta - ruleport - ruleportWithIndex - ruleanychar - ruleiipchar - rule_ - rule__ - rulePegText - ruleAction0 - ruleAction1 - ruleAction2 - ruleAction3 - ruleAction4 - ruleAction5 - ruleAction6 - ruleAction7 - ruleAction8 - ruleAction9 - ruleAction10 - ruleAction11 - ruleAction12 - ruleAction13 - ruleAction14 - - rulePre_ - rule_In_ - rule_Suf -) - -var rul3s = [...]string{ - "Unknown", - "start", - "line", - "LineTerminator", - "comment", - "connection", - "bridge", - "leftlet", - "iip", - "rightlet", - "node", - "component", - "compMeta", - "port", - "portWithIndex", - "anychar", - "iipchar", - "_", - "__", - "PegText", - "Action0", - "Action1", - "Action2", - "Action3", - "Action4", - "Action5", - "Action6", - "Action7", - "Action8", - "Action9", - "Action10", - "Action11", - "Action12", - "Action13", - "Action14", - - "Pre_", - "_In_", - "_Suf", -} - -type tokenTree interface { - Print() - PrintSyntax() - PrintSyntaxTree(buffer string) - Add(rule pegRule, begin, end, next, depth int) - Expand(index int) tokenTree - Tokens() <-chan token32 - AST() *node32 - Error() []token32 - trim(length int) -} - -type node32 struct { - token32 - up, next *node32 -} - -func (node *node32) print(depth int, buffer string) { - for node != nil { - for c := 0; c < depth; c++ { - fmt.Printf(" ") - } - fmt.Printf("\x1B[34m%v\x1B[m %v\n", rul3s[node.pegRule], strconv.Quote(buffer[node.begin:node.end])) - if node.up != nil { - node.up.print(depth+1, buffer) - } - node = node.next - } -} - -func (ast *node32) Print(buffer string) { - ast.print(0, buffer) -} - -type element struct { - node *node32 - down *element -} - -/* ${@} bit structure for abstract syntax tree */ -type token16 struct { - pegRule - begin, end, next int16 -} - -func (t *token16) isZero() bool { - return t.pegRule == ruleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 -} - -func (t *token16) isParentOf(u token16) bool { - return t.begin <= u.begin && t.end >= u.end && t.next > u.next -} - -func (t *token16) getToken32() token32 { - return token32{pegRule: t.pegRule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} -} - -func (t *token16) String() string { - return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", rul3s[t.pegRule], t.begin, t.end, t.next) -} - -type tokens16 struct { - tree []token16 - ordered [][]token16 -} - -func (t *tokens16) trim(length int) { - t.tree = t.tree[0:length] -} - -func (t *tokens16) Print() { - for _, token := range t.tree { - fmt.Println(token.String()) - } -} - -func (t *tokens16) Order() [][]token16 { - if t.ordered != nil { - return t.ordered - } - - depths := make([]int16, 1, math.MaxInt16) - for i, token := range t.tree { - if token.pegRule == ruleUnknown { - t.tree = t.tree[:i] - break - } - depth := int(token.next) - if length := len(depths); depth >= length { - depths = depths[:depth+1] - } - depths[depth]++ - } - depths = append(depths, 0) - - ordered, pool := make([][]token16, len(depths)), make([]token16, len(t.tree)+len(depths)) - for i, depth := range depths { - depth++ - ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 - } - - for i, token := range t.tree { - depth := token.next - token.next = int16(i) - ordered[depth][depths[depth]] = token - depths[depth]++ - } - t.ordered = ordered - return ordered -} - -type state16 struct { - token16 - depths []int16 - leaf bool -} - -func (t *tokens16) AST() *node32 { - tokens := t.Tokens() - stack := &element{node: &node32{token32: <-tokens}} - for token := range tokens { - if token.begin == token.end { - continue - } - node := &node32{token32: token} - for stack != nil && stack.node.begin >= token.begin && stack.node.end <= token.end { - stack.node.next = node.up - node.up = stack.node - stack = stack.down - } - stack = &element{node: node, down: stack} - } - return stack.node -} - -func (t *tokens16) PreOrder() (<-chan state16, [][]token16) { - s, ordered := make(chan state16, 6), t.Order() - go func() { - var states [8]state16 - for i, _ := range states { - states[i].depths = make([]int16, len(ordered)) - } - depths, state, depth := make([]int16, len(ordered)), 0, 1 - write := func(t token16, leaf bool) { - S := states[state] - state, S.pegRule, S.begin, S.end, S.next, S.leaf = (state+1)%8, t.pegRule, t.begin, t.end, int16(depth), leaf - copy(S.depths, depths) - s <- S - } - - states[state].token16 = ordered[0][0] - depths[0]++ - state++ - a, b := ordered[depth-1][depths[depth-1]-1], ordered[depth][depths[depth]] - depthFirstSearch: - for { - for { - if i := depths[depth]; i > 0 { - if c, j := ordered[depth][i-1], depths[depth-1]; a.isParentOf(c) && - (j < 2 || !ordered[depth-1][j-2].isParentOf(c)) { - if c.end != b.begin { - write(token16{pegRule: rule_In_, begin: c.end, end: b.begin}, true) - } - break - } - } - - if a.begin < b.begin { - write(token16{pegRule: rulePre_, begin: a.begin, end: b.begin}, true) - } - break - } - - next := depth + 1 - if c := ordered[next][depths[next]]; c.pegRule != ruleUnknown && b.isParentOf(c) { - write(b, false) - depths[depth]++ - depth, a, b = next, b, c - continue - } - - write(b, true) - depths[depth]++ - c, parent := ordered[depth][depths[depth]], true - for { - if c.pegRule != ruleUnknown && a.isParentOf(c) { - b = c - continue depthFirstSearch - } else if parent && b.end != a.end { - write(token16{pegRule: rule_Suf, begin: b.end, end: a.end}, true) - } - - depth-- - if depth > 0 { - a, b, c = ordered[depth-1][depths[depth-1]-1], a, ordered[depth][depths[depth]] - parent = a.isParentOf(b) - continue - } - - break depthFirstSearch - } - } - - close(s) - }() - return s, ordered -} - -func (t *tokens16) PrintSyntax() { - tokens, ordered := t.PreOrder() - max := -1 - for token := range tokens { - if !token.leaf { - fmt.Printf("%v", token.begin) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[36m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) - } - fmt.Printf(" \x1B[36m%v\x1B[m\n", rul3s[token.pegRule]) - } else if token.begin == token.end { - fmt.Printf("%v", token.begin) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[31m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) - } - fmt.Printf(" \x1B[31m%v\x1B[m\n", rul3s[token.pegRule]) - } else { - for c, end := token.begin, token.end; c < end; c++ { - if i := int(c); max+1 < i { - for j := max; j < i; j++ { - fmt.Printf("skip %v %v\n", j, token.String()) - } - max = i - } else if i := int(c); i <= max { - for j := i; j <= max; j++ { - fmt.Printf("dupe %v %v\n", j, token.String()) - } - } else { - max = int(c) - } - fmt.Printf("%v", c) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[34m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) - } - fmt.Printf(" \x1B[34m%v\x1B[m\n", rul3s[token.pegRule]) - } - fmt.Printf("\n") - } - } -} - -func (t *tokens16) PrintSyntaxTree(buffer string) { - tokens, _ := t.PreOrder() - for token := range tokens { - for c := 0; c < int(token.next); c++ { - fmt.Printf(" ") - } - fmt.Printf("\x1B[34m%v\x1B[m %v\n", rul3s[token.pegRule], strconv.Quote(buffer[token.begin:token.end])) - } -} - -func (t *tokens16) Add(rule pegRule, begin, end, depth, index int) { - t.tree[index] = token16{pegRule: rule, begin: int16(begin), end: int16(end), next: int16(depth)} -} - -func (t *tokens16) Tokens() <-chan token32 { - s := make(chan token32, 16) - go func() { - for _, v := range t.tree { - s <- v.getToken32() - } - close(s) - }() - return s -} - -func (t *tokens16) Error() []token32 { - ordered := t.Order() - length := len(ordered) - tokens, length := make([]token32, length), length-1 - for i, _ := range tokens { - o := ordered[length-i] - if len(o) > 1 { - tokens[i] = o[len(o)-2].getToken32() - } - } - return tokens -} - -/* ${@} bit structure for abstract syntax tree */ -type token32 struct { - pegRule - begin, end, next int32 -} - -func (t *token32) isZero() bool { - return t.pegRule == ruleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 -} - -func (t *token32) isParentOf(u token32) bool { - return t.begin <= u.begin && t.end >= u.end && t.next > u.next -} - -func (t *token32) getToken32() token32 { - return token32{pegRule: t.pegRule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} -} - -func (t *token32) String() string { - return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", rul3s[t.pegRule], t.begin, t.end, t.next) -} - -type tokens32 struct { - tree []token32 - ordered [][]token32 -} - -func (t *tokens32) trim(length int) { - t.tree = t.tree[0:length] -} - -func (t *tokens32) Print() { - for _, token := range t.tree { - fmt.Println(token.String()) - } -} - -func (t *tokens32) Order() [][]token32 { - if t.ordered != nil { - return t.ordered - } - - depths := make([]int32, 1, math.MaxInt16) - for i, token := range t.tree { - if token.pegRule == ruleUnknown { - t.tree = t.tree[:i] - break - } - depth := int(token.next) - if length := len(depths); depth >= length { - depths = depths[:depth+1] - } - depths[depth]++ - } - depths = append(depths, 0) - - ordered, pool := make([][]token32, len(depths)), make([]token32, len(t.tree)+len(depths)) - for i, depth := range depths { - depth++ - ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 - } - - for i, token := range t.tree { - depth := token.next - token.next = int32(i) - ordered[depth][depths[depth]] = token - depths[depth]++ - } - t.ordered = ordered - return ordered -} - -type state32 struct { - token32 - depths []int32 - leaf bool -} - -func (t *tokens32) AST() *node32 { - tokens := t.Tokens() - stack := &element{node: &node32{token32: <-tokens}} - for token := range tokens { - if token.begin == token.end { - continue - } - node := &node32{token32: token} - for stack != nil && stack.node.begin >= token.begin && stack.node.end <= token.end { - stack.node.next = node.up - node.up = stack.node - stack = stack.down - } - stack = &element{node: node, down: stack} - } - return stack.node -} - -func (t *tokens32) PreOrder() (<-chan state32, [][]token32) { - s, ordered := make(chan state32, 6), t.Order() - go func() { - var states [8]state32 - for i, _ := range states { - states[i].depths = make([]int32, len(ordered)) - } - depths, state, depth := make([]int32, len(ordered)), 0, 1 - write := func(t token32, leaf bool) { - S := states[state] - state, S.pegRule, S.begin, S.end, S.next, S.leaf = (state+1)%8, t.pegRule, t.begin, t.end, int32(depth), leaf - copy(S.depths, depths) - s <- S - } - - states[state].token32 = ordered[0][0] - depths[0]++ - state++ - a, b := ordered[depth-1][depths[depth-1]-1], ordered[depth][depths[depth]] - depthFirstSearch: - for { - for { - if i := depths[depth]; i > 0 { - if c, j := ordered[depth][i-1], depths[depth-1]; a.isParentOf(c) && - (j < 2 || !ordered[depth-1][j-2].isParentOf(c)) { - if c.end != b.begin { - write(token32{pegRule: rule_In_, begin: c.end, end: b.begin}, true) - } - break - } - } - - if a.begin < b.begin { - write(token32{pegRule: rulePre_, begin: a.begin, end: b.begin}, true) - } - break - } - - next := depth + 1 - if c := ordered[next][depths[next]]; c.pegRule != ruleUnknown && b.isParentOf(c) { - write(b, false) - depths[depth]++ - depth, a, b = next, b, c - continue - } - - write(b, true) - depths[depth]++ - c, parent := ordered[depth][depths[depth]], true - for { - if c.pegRule != ruleUnknown && a.isParentOf(c) { - b = c - continue depthFirstSearch - } else if parent && b.end != a.end { - write(token32{pegRule: rule_Suf, begin: b.end, end: a.end}, true) - } - - depth-- - if depth > 0 { - a, b, c = ordered[depth-1][depths[depth-1]-1], a, ordered[depth][depths[depth]] - parent = a.isParentOf(b) - continue - } - - break depthFirstSearch - } - } - - close(s) - }() - return s, ordered -} - -func (t *tokens32) PrintSyntax() { - tokens, ordered := t.PreOrder() - max := -1 - for token := range tokens { - if !token.leaf { - fmt.Printf("%v", token.begin) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[36m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) - } - fmt.Printf(" \x1B[36m%v\x1B[m\n", rul3s[token.pegRule]) - } else if token.begin == token.end { - fmt.Printf("%v", token.begin) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[31m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) - } - fmt.Printf(" \x1B[31m%v\x1B[m\n", rul3s[token.pegRule]) - } else { - for c, end := token.begin, token.end; c < end; c++ { - if i := int(c); max+1 < i { - for j := max; j < i; j++ { - fmt.Printf("skip %v %v\n", j, token.String()) - } - max = i - } else if i := int(c); i <= max { - for j := i; j <= max; j++ { - fmt.Printf("dupe %v %v\n", j, token.String()) - } - } else { - max = int(c) - } - fmt.Printf("%v", c) - for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { - fmt.Printf(" \x1B[34m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) - } - fmt.Printf(" \x1B[34m%v\x1B[m\n", rul3s[token.pegRule]) - } - fmt.Printf("\n") - } - } -} - -func (t *tokens32) PrintSyntaxTree(buffer string) { - tokens, _ := t.PreOrder() - for token := range tokens { - for c := 0; c < int(token.next); c++ { - fmt.Printf(" ") - } - fmt.Printf("\x1B[34m%v\x1B[m %v\n", rul3s[token.pegRule], strconv.Quote(buffer[token.begin:token.end])) - } -} - -func (t *tokens32) Add(rule pegRule, begin, end, depth, index int) { - t.tree[index] = token32{pegRule: rule, begin: int32(begin), end: int32(end), next: int32(depth)} -} - -func (t *tokens32) Tokens() <-chan token32 { - s := make(chan token32, 16) - go func() { - for _, v := range t.tree { - s <- v.getToken32() - } - close(s) - }() - return s -} - -func (t *tokens32) Error() []token32 { - ordered := t.Order() - length := len(ordered) - tokens, length := make([]token32, length), length-1 - for i, _ := range tokens { - o := ordered[length-i] - if len(o) > 1 { - tokens[i] = o[len(o)-2].getToken32() - } - } - return tokens -} - -func (t *tokens16) Expand(index int) tokenTree { - tree := t.tree - if index >= len(tree) { - expanded := make([]token32, 2*len(tree)) - for i, v := range tree { - expanded[i] = v.getToken32() - } - return &tokens32{tree: expanded} - } - return nil -} - -func (t *tokens32) Expand(index int) tokenTree { - tree := t.tree - if index >= len(tree) { - expanded := make([]token32, 2*len(tree)) - copy(expanded, tree) - t.tree = expanded - } - return nil -} - -type Fbp struct { - BaseFbp - - Buffer string - buffer []rune - rules [35]func() bool - Parse func(rule ...int) error - Reset func() - tokenTree -} - -type textPosition struct { - line, symbol int -} - -type textPositionMap map[int]textPosition - -func translatePositions(buffer string, positions []int) textPositionMap { - length, translations, j, line, symbol := len(positions), make(textPositionMap, len(positions)), 0, 1, 0 - sort.Ints(positions) - -search: - for i, c := range buffer[0:] { - if c == '\n' { - line, symbol = line+1, 0 - } else { - symbol++ - } - if i == positions[j] { - translations[positions[j]] = textPosition{line, symbol} - for j++; j < length; j++ { - if i != positions[j] { - continue search - } - } - break search - } - } - - return translations -} - -type parseError struct { - p *Fbp -} - -func (e *parseError) Error() string { - tokens, error := e.p.tokenTree.Error(), "\n" - positions, p := make([]int, 2*len(tokens)), 0 - for _, token := range tokens { - positions[p], p = int(token.begin), p+1 - positions[p], p = int(token.end), p+1 - } - translations := translatePositions(e.p.Buffer, positions) - for _, token := range tokens { - begin, end := int(token.begin), int(token.end) - error += fmt.Sprintf("parse error near \x1B[34m%v\x1B[m (line %v symbol %v - line %v symbol %v):\n%v\n", - rul3s[token.pegRule], - translations[begin].line, translations[begin].symbol, - translations[end].line, translations[end].symbol, - /*strconv.Quote(*/ e.p.Buffer[begin:end] /*)*/) - } - - return error -} - -func (p *Fbp) PrintSyntaxTree() { - p.tokenTree.PrintSyntaxTree(p.Buffer) -} - -func (p *Fbp) Highlighter() { - p.tokenTree.PrintSyntax() -} - -func (p *Fbp) Execute() { - buffer, begin, end := p.Buffer, 0, 0 - for token := range p.tokenTree.Tokens() { - switch token.pegRule { - case rulePegText: - begin, end = int(token.begin), int(token.end) - case ruleAction0: - p.createInport(buffer[begin:end]) - case ruleAction1: - p.createOutport(buffer[begin:end]) - case ruleAction2: - p.inPort = p.port - p.inPortIndex = p.index - case ruleAction3: - p.outPort = p.port - p.outPortIndex = p.index - case ruleAction4: - p.createMiddlet() - case ruleAction5: - p.createLeftlet() - case ruleAction6: - p.createRightlet() - case ruleAction7: - p.iip = buffer[begin:end] - case ruleAction8: - p.nodeProcessName = buffer[begin:end] - case ruleAction9: - p.createNode() - case ruleAction10: - p.nodeComponentName = buffer[begin:end] - case ruleAction11: - p.nodeMeta = buffer[begin:end] - case ruleAction12: - p.port = buffer[begin:end] - case ruleAction13: - p.port = buffer[begin:end] - case ruleAction14: - p.index = buffer[begin:end] - - } - } -} - -func (p *Fbp) Init() { - p.buffer = []rune(p.Buffer) - if len(p.buffer) == 0 || p.buffer[len(p.buffer)-1] != end_symbol { - p.buffer = append(p.buffer, end_symbol) - } - - var tree tokenTree = &tokens16{tree: make([]token16, math.MaxInt16)} - position, depth, tokenIndex, buffer, rules := 0, 0, 0, p.buffer, p.rules - - p.Parse = func(rule ...int) error { - r := 1 - if len(rule) > 0 { - r = rule[0] - } - matches := p.rules[r]() - p.tokenTree = tree - if matches { - p.tokenTree.trim(tokenIndex) - return nil - } - return &parseError{p} - } - - p.Reset = func() { - position, tokenIndex, depth = 0, 0, 0 - } - - add := func(rule pegRule, begin int) { - if t := tree.Expand(tokenIndex); t != nil { - tree = t - } - tree.Add(rule, begin, position, depth, tokenIndex) - tokenIndex++ - } - - matchDot := func() bool { - if buffer[position] != end_symbol { - position++ - return true - } - return false - } - - /*matchChar := func(c byte) bool { - if buffer[position] == c { - position++ - return true - } - return false - }*/ - - /*matchRange := func(lower byte, upper byte) bool { - if c := buffer[position]; c >= lower && c <= upper { - position++ - return true - } - return false - }*/ - - rules = [...]func() bool{ - nil, - /* 0 start <- <(line* _ !.)> */ - func() bool { - position0, tokenIndex0, depth0 := position, tokenIndex, depth - { - position1 := position - depth++ - l2: - { - position3, tokenIndex3, depth3 := position, tokenIndex, depth - { - position4 := position - depth++ - { - position5, tokenIndex5, depth5 := position, tokenIndex, depth - if !rules[rule_]() { - goto l6 - } - { - position7, tokenIndex7, depth7 := position, tokenIndex, depth - if buffer[position] != rune('e') { - goto l8 - } - position++ - goto l7 - l8: - position, tokenIndex, depth = position7, tokenIndex7, depth7 - if buffer[position] != rune('E') { - goto l6 - } - position++ - } - l7: - { - position9, tokenIndex9, depth9 := position, tokenIndex, depth - if buffer[position] != rune('x') { - goto l10 - } - position++ - goto l9 - l10: - position, tokenIndex, depth = position9, tokenIndex9, depth9 - if buffer[position] != rune('X') { - goto l6 - } - position++ - } - l9: - { - position11, tokenIndex11, depth11 := position, tokenIndex, depth - if buffer[position] != rune('p') { - goto l12 - } - position++ - goto l11 - l12: - position, tokenIndex, depth = position11, tokenIndex11, depth11 - if buffer[position] != rune('P') { - goto l6 - } - position++ - } - l11: - { - position13, tokenIndex13, depth13 := position, tokenIndex, depth - if buffer[position] != rune('o') { - goto l14 - } - position++ - goto l13 - l14: - position, tokenIndex, depth = position13, tokenIndex13, depth13 - if buffer[position] != rune('O') { - goto l6 - } - position++ - } - l13: - { - position15, tokenIndex15, depth15 := position, tokenIndex, depth - if buffer[position] != rune('r') { - goto l16 - } - position++ - goto l15 - l16: - position, tokenIndex, depth = position15, tokenIndex15, depth15 - if buffer[position] != rune('R') { - goto l6 - } - position++ - } - l15: - { - position17, tokenIndex17, depth17 := position, tokenIndex, depth - if buffer[position] != rune('t') { - goto l18 - } - position++ - goto l17 - l18: - position, tokenIndex, depth = position17, tokenIndex17, depth17 - if buffer[position] != rune('T') { - goto l6 - } - position++ - } - l17: - if buffer[position] != rune('=') { - goto l6 - } - position++ - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l6 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l6 - } - position++ - break - case '.': - if buffer[position] != rune('.') { - goto l6 - } - position++ - break - case 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z': - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l6 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l6 - } - position++ - break - } - } - - l19: - { - position20, tokenIndex20, depth20 := position, tokenIndex, depth - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l20 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l20 - } - position++ - break - case '.': - if buffer[position] != rune('.') { - goto l20 - } - position++ - break - case 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z': - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l20 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l20 - } - position++ - break - } - } - - goto l19 - l20: - position, tokenIndex, depth = position20, tokenIndex20, depth20 - } - if buffer[position] != rune(':') { - goto l6 - } - position++ - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l6 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l6 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l6 - } - position++ - break - } - } - - l23: - { - position24, tokenIndex24, depth24 := position, tokenIndex, depth - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l24 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l24 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l24 - } - position++ - break - } - } - - goto l23 - l24: - position, tokenIndex, depth = position24, tokenIndex24, depth24 - } - if !rules[rule_]() { - goto l6 - } - { - position27, tokenIndex27, depth27 := position, tokenIndex, depth - if !rules[ruleLineTerminator]() { - goto l27 - } - goto l28 - l27: - position, tokenIndex, depth = position27, tokenIndex27, depth27 - } - l28: - goto l5 - l6: - position, tokenIndex, depth = position5, tokenIndex5, depth5 - if !rules[rule_]() { - goto l29 - } - { - position30, tokenIndex30, depth30 := position, tokenIndex, depth - if buffer[position] != rune('i') { - goto l31 - } - position++ - goto l30 - l31: - position, tokenIndex, depth = position30, tokenIndex30, depth30 - if buffer[position] != rune('I') { - goto l29 - } - position++ - } - l30: - { - position32, tokenIndex32, depth32 := position, tokenIndex, depth - if buffer[position] != rune('n') { - goto l33 - } - position++ - goto l32 - l33: - position, tokenIndex, depth = position32, tokenIndex32, depth32 - if buffer[position] != rune('N') { - goto l29 - } - position++ - } - l32: - { - position34, tokenIndex34, depth34 := position, tokenIndex, depth - if buffer[position] != rune('p') { - goto l35 - } - position++ - goto l34 - l35: - position, tokenIndex, depth = position34, tokenIndex34, depth34 - if buffer[position] != rune('P') { - goto l29 - } - position++ - } - l34: - { - position36, tokenIndex36, depth36 := position, tokenIndex, depth - if buffer[position] != rune('o') { - goto l37 - } - position++ - goto l36 - l37: - position, tokenIndex, depth = position36, tokenIndex36, depth36 - if buffer[position] != rune('O') { - goto l29 - } - position++ - } - l36: - { - position38, tokenIndex38, depth38 := position, tokenIndex, depth - if buffer[position] != rune('r') { - goto l39 - } - position++ - goto l38 - l39: - position, tokenIndex, depth = position38, tokenIndex38, depth38 - if buffer[position] != rune('R') { - goto l29 - } - position++ - } - l38: - { - position40, tokenIndex40, depth40 := position, tokenIndex, depth - if buffer[position] != rune('t') { - goto l41 - } - position++ - goto l40 - l41: - position, tokenIndex, depth = position40, tokenIndex40, depth40 - if buffer[position] != rune('T') { - goto l29 - } - position++ - } - l40: - if buffer[position] != rune('=') { - goto l29 - } - position++ - { - position42 := position - depth++ - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l29 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l29 - } - position++ - break - case 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z': - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l29 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l29 - } - position++ - break - } - } - - l43: - { - position44, tokenIndex44, depth44 := position, tokenIndex, depth - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l44 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l44 - } - position++ - break - case 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z': - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l44 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l44 - } - position++ - break - } - } - - goto l43 - l44: - position, tokenIndex, depth = position44, tokenIndex44, depth44 - } - if buffer[position] != rune('.') { - goto l29 - } - position++ - { - switch buffer[position] { - case ']': - if buffer[position] != rune(']') { - goto l29 - } - position++ - break - case '[': - if buffer[position] != rune('[') { - goto l29 - } - position++ - break - case '_': - if buffer[position] != rune('_') { - goto l29 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l29 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l29 - } - position++ - break - } - } - - l47: - { - position48, tokenIndex48, depth48 := position, tokenIndex, depth - { - switch buffer[position] { - case ']': - if buffer[position] != rune(']') { - goto l48 - } - position++ - break - case '[': - if buffer[position] != rune('[') { - goto l48 - } - position++ - break - case '_': - if buffer[position] != rune('_') { - goto l48 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l48 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l48 - } - position++ - break - } - } - - goto l47 - l48: - position, tokenIndex, depth = position48, tokenIndex48, depth48 - } - if buffer[position] != rune(':') { - goto l29 - } - position++ - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l29 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l29 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l29 - } - position++ - break - } - } - - l51: - { - position52, tokenIndex52, depth52 := position, tokenIndex, depth - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l52 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l52 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l52 - } - position++ - break - } - } - - goto l51 - l52: - position, tokenIndex, depth = position52, tokenIndex52, depth52 - } - depth-- - add(rulePegText, position42) - } - if !rules[rule_]() { - goto l29 - } - { - position55, tokenIndex55, depth55 := position, tokenIndex, depth - if !rules[ruleLineTerminator]() { - goto l55 - } - goto l56 - l55: - position, tokenIndex, depth = position55, tokenIndex55, depth55 - } - l56: - { - add(ruleAction0, position) - } - goto l5 - l29: - position, tokenIndex, depth = position5, tokenIndex5, depth5 - if !rules[rule_]() { - goto l58 - } - { - position59, tokenIndex59, depth59 := position, tokenIndex, depth - if buffer[position] != rune('o') { - goto l60 - } - position++ - goto l59 - l60: - position, tokenIndex, depth = position59, tokenIndex59, depth59 - if buffer[position] != rune('O') { - goto l58 - } - position++ - } - l59: - { - position61, tokenIndex61, depth61 := position, tokenIndex, depth - if buffer[position] != rune('u') { - goto l62 - } - position++ - goto l61 - l62: - position, tokenIndex, depth = position61, tokenIndex61, depth61 - if buffer[position] != rune('U') { - goto l58 - } - position++ - } - l61: - { - position63, tokenIndex63, depth63 := position, tokenIndex, depth - if buffer[position] != rune('t') { - goto l64 - } - position++ - goto l63 - l64: - position, tokenIndex, depth = position63, tokenIndex63, depth63 - if buffer[position] != rune('T') { - goto l58 - } - position++ - } - l63: - { - position65, tokenIndex65, depth65 := position, tokenIndex, depth - if buffer[position] != rune('p') { - goto l66 - } - position++ - goto l65 - l66: - position, tokenIndex, depth = position65, tokenIndex65, depth65 - if buffer[position] != rune('P') { - goto l58 - } - position++ - } - l65: - { - position67, tokenIndex67, depth67 := position, tokenIndex, depth - if buffer[position] != rune('o') { - goto l68 - } - position++ - goto l67 - l68: - position, tokenIndex, depth = position67, tokenIndex67, depth67 - if buffer[position] != rune('O') { - goto l58 - } - position++ - } - l67: - { - position69, tokenIndex69, depth69 := position, tokenIndex, depth - if buffer[position] != rune('r') { - goto l70 - } - position++ - goto l69 - l70: - position, tokenIndex, depth = position69, tokenIndex69, depth69 - if buffer[position] != rune('R') { - goto l58 - } - position++ - } - l69: - { - position71, tokenIndex71, depth71 := position, tokenIndex, depth - if buffer[position] != rune('t') { - goto l72 - } - position++ - goto l71 - l72: - position, tokenIndex, depth = position71, tokenIndex71, depth71 - if buffer[position] != rune('T') { - goto l58 - } - position++ - } - l71: - if buffer[position] != rune('=') { - goto l58 - } - position++ - { - position73 := position - depth++ - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l58 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l58 - } - position++ - break - case 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z': - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l58 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l58 - } - position++ - break - } - } - - l74: - { - position75, tokenIndex75, depth75 := position, tokenIndex, depth - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l75 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l75 - } - position++ - break - case 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z': - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l75 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l75 - } - position++ - break - } - } - - goto l74 - l75: - position, tokenIndex, depth = position75, tokenIndex75, depth75 - } - if buffer[position] != rune('.') { - goto l58 - } - position++ - { - switch buffer[position] { - case ']': - if buffer[position] != rune(']') { - goto l58 - } - position++ - break - case '[': - if buffer[position] != rune('[') { - goto l58 - } - position++ - break - case '_': - if buffer[position] != rune('_') { - goto l58 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l58 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l58 - } - position++ - break - } - } - - l78: - { - position79, tokenIndex79, depth79 := position, tokenIndex, depth - { - switch buffer[position] { - case ']': - if buffer[position] != rune(']') { - goto l79 - } - position++ - break - case '[': - if buffer[position] != rune('[') { - goto l79 - } - position++ - break - case '_': - if buffer[position] != rune('_') { - goto l79 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l79 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l79 - } - position++ - break - } - } - - goto l78 - l79: - position, tokenIndex, depth = position79, tokenIndex79, depth79 - } - if buffer[position] != rune(':') { - goto l58 - } - position++ - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l58 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l58 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l58 - } - position++ - break - } - } - - l82: - { - position83, tokenIndex83, depth83 := position, tokenIndex, depth - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l83 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l83 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l83 - } - position++ - break - } - } - - goto l82 - l83: - position, tokenIndex, depth = position83, tokenIndex83, depth83 - } - depth-- - add(rulePegText, position73) - } - if !rules[rule_]() { - goto l58 - } - { - position86, tokenIndex86, depth86 := position, tokenIndex, depth - if !rules[ruleLineTerminator]() { - goto l86 - } - goto l87 - l86: - position, tokenIndex, depth = position86, tokenIndex86, depth86 - } - l87: - { - add(ruleAction1, position) - } - goto l5 - l58: - position, tokenIndex, depth = position5, tokenIndex5, depth5 - if !rules[rulecomment]() { - goto l89 - } - { - position90, tokenIndex90, depth90 := position, tokenIndex, depth - { - position92, tokenIndex92, depth92 := position, tokenIndex, depth - if buffer[position] != rune('\n') { - goto l93 - } - position++ - goto l92 - l93: - position, tokenIndex, depth = position92, tokenIndex92, depth92 - if buffer[position] != rune('\r') { - goto l90 - } - position++ - } - l92: - goto l91 - l90: - position, tokenIndex, depth = position90, tokenIndex90, depth90 - } - l91: - goto l5 - l89: - position, tokenIndex, depth = position5, tokenIndex5, depth5 - if !rules[rule_]() { - goto l94 - } - { - position95, tokenIndex95, depth95 := position, tokenIndex, depth - if buffer[position] != rune('\n') { - goto l96 - } - position++ - goto l95 - l96: - position, tokenIndex, depth = position95, tokenIndex95, depth95 - if buffer[position] != rune('\r') { - goto l94 - } - position++ - } - l95: - goto l5 - l94: - position, tokenIndex, depth = position5, tokenIndex5, depth5 - if !rules[rule_]() { - goto l3 - } - if !rules[ruleconnection]() { - goto l3 - } - if !rules[rule_]() { - goto l3 - } - { - position97, tokenIndex97, depth97 := position, tokenIndex, depth - if !rules[ruleLineTerminator]() { - goto l97 - } - goto l98 - l97: - position, tokenIndex, depth = position97, tokenIndex97, depth97 - } - l98: - } - l5: - depth-- - add(ruleline, position4) - } - goto l2 - l3: - position, tokenIndex, depth = position3, tokenIndex3, depth3 - } - if !rules[rule_]() { - goto l0 - } - { - position99, tokenIndex99, depth99 := position, tokenIndex, depth - if !matchDot() { - goto l99 - } - goto l0 - l99: - position, tokenIndex, depth = position99, tokenIndex99, depth99 - } - depth-- - add(rulestart, position1) - } - return true - l0: - position, tokenIndex, depth = position0, tokenIndex0, depth0 - return false - }, - /* 1 line <- <((_ (('e' / 'E') ('x' / 'X') ('p' / 'P') ('o' / 'O') ('r' / 'R') ('t' / 'T') '=') ((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('.') '.') | (&('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') [a-z]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+ ':' ((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+ _ LineTerminator?) / (_ (('i' / 'I') ('n' / 'N') ('p' / 'P') ('o' / 'O') ('r' / 'R') ('t' / 'T') '=') <(((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') [a-z]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+ '.' ((&(']') ']') | (&('[') '[') | (&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+ ':' ((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+)> _ LineTerminator? Action0) / (_ (('o' / 'O') ('u' / 'U') ('t' / 'T') ('p' / 'P') ('o' / 'O') ('r' / 'R') ('t' / 'T') '=') <(((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') [a-z]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+ '.' ((&(']') ']') | (&('[') '[') | (&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+ ':' ((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+)> _ LineTerminator? Action1) / (comment ('\n' / '\r')?) / (_ ('\n' / '\r')) / (_ connection _ LineTerminator?))> */ - nil, - /* 2 LineTerminator <- <(_ ','? comment? ('\n' / '\r')?)> */ - func() bool { - position101, tokenIndex101, depth101 := position, tokenIndex, depth - { - position102 := position - depth++ - if !rules[rule_]() { - goto l101 - } - { - position103, tokenIndex103, depth103 := position, tokenIndex, depth - if buffer[position] != rune(',') { - goto l103 - } - position++ - goto l104 - l103: - position, tokenIndex, depth = position103, tokenIndex103, depth103 - } - l104: - { - position105, tokenIndex105, depth105 := position, tokenIndex, depth - if !rules[rulecomment]() { - goto l105 - } - goto l106 - l105: - position, tokenIndex, depth = position105, tokenIndex105, depth105 - } - l106: - { - position107, tokenIndex107, depth107 := position, tokenIndex, depth - { - position109, tokenIndex109, depth109 := position, tokenIndex, depth - if buffer[position] != rune('\n') { - goto l110 - } - position++ - goto l109 - l110: - position, tokenIndex, depth = position109, tokenIndex109, depth109 - if buffer[position] != rune('\r') { - goto l107 - } - position++ - } - l109: - goto l108 - l107: - position, tokenIndex, depth = position107, tokenIndex107, depth107 - } - l108: - depth-- - add(ruleLineTerminator, position102) - } - return true - l101: - position, tokenIndex, depth = position101, tokenIndex101, depth101 - return false - }, - /* 3 comment <- <(_ '#' anychar*)> */ - func() bool { - position111, tokenIndex111, depth111 := position, tokenIndex, depth - { - position112 := position - depth++ - if !rules[rule_]() { - goto l111 - } - if buffer[position] != rune('#') { - goto l111 - } - position++ - l113: - { - position114, tokenIndex114, depth114 := position, tokenIndex, depth - { - position115 := position - depth++ - { - position116, tokenIndex116, depth116 := position, tokenIndex, depth - { - position117, tokenIndex117, depth117 := position, tokenIndex, depth - if buffer[position] != rune('\n') { - goto l118 - } - position++ - goto l117 - l118: - position, tokenIndex, depth = position117, tokenIndex117, depth117 - if buffer[position] != rune('\r') { - goto l116 - } - position++ - } - l117: - goto l114 - l116: - position, tokenIndex, depth = position116, tokenIndex116, depth116 - } - if !matchDot() { - goto l114 - } - depth-- - add(ruleanychar, position115) - } - goto l113 - l114: - position, tokenIndex, depth = position114, tokenIndex114, depth114 - } - depth-- - add(rulecomment, position112) - } - return true - l111: - position, tokenIndex, depth = position111, tokenIndex111, depth111 - return false - }, - /* 4 connection <- <((bridge _ ('-' '>') _ connection) / bridge)> */ - func() bool { - position119, tokenIndex119, depth119 := position, tokenIndex, depth - { - position120 := position - depth++ - { - position121, tokenIndex121, depth121 := position, tokenIndex, depth - if !rules[rulebridge]() { - goto l122 - } - if !rules[rule_]() { - goto l122 - } - if buffer[position] != rune('-') { - goto l122 - } - position++ - if buffer[position] != rune('>') { - goto l122 - } - position++ - if !rules[rule_]() { - goto l122 - } - if !rules[ruleconnection]() { - goto l122 - } - goto l121 - l122: - position, tokenIndex, depth = position121, tokenIndex121, depth121 - if !rules[rulebridge]() { - goto l119 - } - } - l121: - depth-- - add(ruleconnection, position120) - } - return true - l119: - position, tokenIndex, depth = position119, tokenIndex119, depth119 - return false - }, - /* 5 bridge <- <((port _ Action2 node _ port Action3 Action4) / iip / (leftlet Action5) / (rightlet Action6))> */ - func() bool { - position123, tokenIndex123, depth123 := position, tokenIndex, depth - { - position124 := position - depth++ - { - position125, tokenIndex125, depth125 := position, tokenIndex, depth - if !rules[ruleport]() { - goto l126 - } - if !rules[rule_]() { - goto l126 - } - { - add(ruleAction2, position) - } - if !rules[rulenode]() { - goto l126 - } - if !rules[rule_]() { - goto l126 - } - if !rules[ruleport]() { - goto l126 - } - { - add(ruleAction3, position) - } - { - add(ruleAction4, position) - } - goto l125 - l126: - position, tokenIndex, depth = position125, tokenIndex125, depth125 - { - position131 := position - depth++ - if buffer[position] != rune('\'') { - goto l130 - } - position++ - { - position132 := position - depth++ - l133: - { - position134, tokenIndex134, depth134 := position, tokenIndex, depth - { - position135 := position - depth++ - { - position136, tokenIndex136, depth136 := position, tokenIndex, depth - if buffer[position] != rune('\\') { - goto l137 - } - position++ - if buffer[position] != rune('\'') { - goto l137 - } - position++ - goto l136 - l137: - position, tokenIndex, depth = position136, tokenIndex136, depth136 - { - position138, tokenIndex138, depth138 := position, tokenIndex, depth - if buffer[position] != rune('\'') { - goto l138 - } - position++ - goto l134 - l138: - position, tokenIndex, depth = position138, tokenIndex138, depth138 - } - if !matchDot() { - goto l134 - } - } - l136: - depth-- - add(ruleiipchar, position135) - } - goto l133 - l134: - position, tokenIndex, depth = position134, tokenIndex134, depth134 - } - depth-- - add(rulePegText, position132) - } - if buffer[position] != rune('\'') { - goto l130 - } - position++ - { - add(ruleAction7, position) - } - depth-- - add(ruleiip, position131) - } - goto l125 - l130: - position, tokenIndex, depth = position125, tokenIndex125, depth125 - { - position141 := position - depth++ - { - position142, tokenIndex142, depth142 := position, tokenIndex, depth - if !rules[rulenode]() { - goto l143 - } - if !rules[rule_]() { - goto l143 - } - if !rules[ruleportWithIndex]() { - goto l143 - } - goto l142 - l143: - position, tokenIndex, depth = position142, tokenIndex142, depth142 - if !rules[rulenode]() { - goto l140 - } - if !rules[rule_]() { - goto l140 - } - if !rules[ruleport]() { - goto l140 - } - } - l142: - depth-- - add(ruleleftlet, position141) - } - { - add(ruleAction5, position) - } - goto l125 - l140: - position, tokenIndex, depth = position125, tokenIndex125, depth125 - { - position145 := position - depth++ - { - position146, tokenIndex146, depth146 := position, tokenIndex, depth - if !rules[ruleportWithIndex]() { - goto l147 - } - if !rules[rule_]() { - goto l147 - } - if !rules[rulenode]() { - goto l147 - } - goto l146 - l147: - position, tokenIndex, depth = position146, tokenIndex146, depth146 - if !rules[ruleport]() { - goto l123 - } - if !rules[rule_]() { - goto l123 - } - if !rules[rulenode]() { - goto l123 - } - } - l146: - depth-- - add(rulerightlet, position145) - } - { - add(ruleAction6, position) - } - } - l125: - depth-- - add(rulebridge, position124) - } - return true - l123: - position, tokenIndex, depth = position123, tokenIndex123, depth123 - return false - }, - /* 6 leftlet <- <((node _ portWithIndex) / (node _ port))> */ - nil, - /* 7 iip <- <('\'' '\'' Action7)> */ - nil, - /* 8 rightlet <- <((portWithIndex _ node) / (port _ node))> */ - nil, - /* 9 node <- <(<((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]) | (&('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') [a-z]))+> Action8 component? Action9)> */ - func() bool { - position152, tokenIndex152, depth152 := position, tokenIndex, depth - { - position153 := position - depth++ - { - position154 := position - depth++ - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l152 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l152 - } - position++ - break - case 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z': - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l152 - } - position++ - break - default: - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l152 - } - position++ - break - } - } - - l155: - { - position156, tokenIndex156, depth156 := position, tokenIndex, depth - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l156 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l156 - } - position++ - break - case 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z': - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l156 - } - position++ - break - default: - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l156 - } - position++ - break - } - } - - goto l155 - l156: - position, tokenIndex, depth = position156, tokenIndex156, depth156 - } - depth-- - add(rulePegText, position154) - } - { - add(ruleAction8, position) - } - { - position160, tokenIndex160, depth160 := position, tokenIndex, depth - { - position162 := position - depth++ - if buffer[position] != rune('(') { - goto l160 - } - position++ - { - position163 := position - depth++ - l164: - { - position165, tokenIndex165, depth165 := position, tokenIndex, depth - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l165 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l165 - } - position++ - break - case '-': - if buffer[position] != rune('-') { - goto l165 - } - position++ - break - case '/': - if buffer[position] != rune('/') { - goto l165 - } - position++ - break - case 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z': - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l165 - } - position++ - break - default: - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l165 - } - position++ - break - } - } - - goto l164 - l165: - position, tokenIndex, depth = position165, tokenIndex165, depth165 - } - depth-- - add(rulePegText, position163) - } - { - add(ruleAction10, position) - } - { - position168, tokenIndex168, depth168 := position, tokenIndex, depth - { - position170 := position - depth++ - if buffer[position] != rune(':') { - goto l168 - } - position++ - { - position171 := position - depth++ - { - switch buffer[position] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l168 - } - position++ - break - case ',': - if buffer[position] != rune(',') { - goto l168 - } - position++ - break - case '_': - if buffer[position] != rune('_') { - goto l168 - } - position++ - break - case '=': - if buffer[position] != rune('=') { - goto l168 - } - position++ - break - case '/': - if buffer[position] != rune('/') { - goto l168 - } - position++ - break - case 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z': - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l168 - } - position++ - break - default: - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l168 - } - position++ - break - } - } - - l172: - { - position173, tokenIndex173, depth173 := position, tokenIndex, depth - { - switch buffer[position] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l173 - } - position++ - break - case ',': - if buffer[position] != rune(',') { - goto l173 - } - position++ - break - case '_': - if buffer[position] != rune('_') { - goto l173 - } - position++ - break - case '=': - if buffer[position] != rune('=') { - goto l173 - } - position++ - break - case '/': - if buffer[position] != rune('/') { - goto l173 - } - position++ - break - case 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z': - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l173 - } - position++ - break - default: - if c := buffer[position]; c < rune('a') || c > rune('z') { - goto l173 - } - position++ - break - } - } - - goto l172 - l173: - position, tokenIndex, depth = position173, tokenIndex173, depth173 - } - depth-- - add(rulePegText, position171) - } - { - add(ruleAction11, position) - } - depth-- - add(rulecompMeta, position170) - } - goto l169 - l168: - position, tokenIndex, depth = position168, tokenIndex168, depth168 - } - l169: - if buffer[position] != rune(')') { - goto l160 - } - position++ - depth-- - add(rulecomponent, position162) - } - goto l161 - l160: - position, tokenIndex, depth = position160, tokenIndex160, depth160 - } - l161: - { - add(ruleAction9, position) - } - depth-- - add(rulenode, position153) - } - return true - l152: - position, tokenIndex, depth = position152, tokenIndex152, depth152 - return false - }, - /* 10 component <- <('(' <((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('-') '-') | (&('/') '/') | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]) | (&('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') [a-z]))*> Action10 compMeta? ')')> */ - nil, - /* 11 compMeta <- <(':' <((&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&(',') ',') | (&('_') '_') | (&('=') '=') | (&('/') '/') | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]) | (&('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') [a-z]))+> Action11)> */ - nil, - /* 12 port <- <(<((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('.') '.') | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+> __ Action12)> */ - func() bool { - position180, tokenIndex180, depth180 := position, tokenIndex, depth - { - position181 := position - depth++ - { - position182 := position - depth++ - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l180 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l180 - } - position++ - break - case '.': - if buffer[position] != rune('.') { - goto l180 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l180 - } - position++ - break - } - } - - l183: - { - position184, tokenIndex184, depth184 := position, tokenIndex, depth - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l184 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l184 - } - position++ - break - case '.': - if buffer[position] != rune('.') { - goto l184 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l184 - } - position++ - break - } - } - - goto l183 - l184: - position, tokenIndex, depth = position184, tokenIndex184, depth184 - } - depth-- - add(rulePegText, position182) - } - if !rules[rule__]() { - goto l180 - } - { - add(ruleAction12, position) - } - depth-- - add(ruleport, position181) - } - return true - l180: - position, tokenIndex, depth = position180, tokenIndex180, depth180 - return false - }, - /* 13 portWithIndex <- <(<((&('_') '_') | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('.') '.') | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+> Action13 '[' <[0-9]+> Action14 ']' __)> */ - func() bool { - position188, tokenIndex188, depth188 := position, tokenIndex, depth - { - position189 := position - depth++ - { - position190 := position - depth++ - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l188 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l188 - } - position++ - break - case '.': - if buffer[position] != rune('.') { - goto l188 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l188 - } - position++ - break - } - } - - l191: - { - position192, tokenIndex192, depth192 := position, tokenIndex, depth - { - switch buffer[position] { - case '_': - if buffer[position] != rune('_') { - goto l192 - } - position++ - break - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l192 - } - position++ - break - case '.': - if buffer[position] != rune('.') { - goto l192 - } - position++ - break - default: - if c := buffer[position]; c < rune('A') || c > rune('Z') { - goto l192 - } - position++ - break - } - } - - goto l191 - l192: - position, tokenIndex, depth = position192, tokenIndex192, depth192 - } - depth-- - add(rulePegText, position190) - } - { - add(ruleAction13, position) - } - if buffer[position] != rune('[') { - goto l188 - } - position++ - { - position196 := position - depth++ - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l188 - } - position++ - l197: - { - position198, tokenIndex198, depth198 := position, tokenIndex, depth - if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l198 - } - position++ - goto l197 - l198: - position, tokenIndex, depth = position198, tokenIndex198, depth198 - } - depth-- - add(rulePegText, position196) - } - { - add(ruleAction14, position) - } - if buffer[position] != rune(']') { - goto l188 - } - position++ - if !rules[rule__]() { - goto l188 - } - depth-- - add(ruleportWithIndex, position189) - } - return true - l188: - position, tokenIndex, depth = position188, tokenIndex188, depth188 - return false - }, - /* 14 anychar <- <(!('\n' / '\r') .)> */ - nil, - /* 15 iipchar <- <(('\\' '\'') / (!'\'' .))> */ - nil, - /* 16 _ <- <(' ' / '\t')*> */ - func() bool { - { - position203 := position - depth++ - l204: - { - position205, tokenIndex205, depth205 := position, tokenIndex, depth - { - position206, tokenIndex206, depth206 := position, tokenIndex, depth - if buffer[position] != rune(' ') { - goto l207 - } - position++ - goto l206 - l207: - position, tokenIndex, depth = position206, tokenIndex206, depth206 - if buffer[position] != rune('\t') { - goto l205 - } - position++ - } - l206: - goto l204 - l205: - position, tokenIndex, depth = position205, tokenIndex205, depth205 - } - depth-- - add(rule_, position203) - } - return true - }, - /* 17 __ <- <(' ' / '\t')+> */ - func() bool { - position208, tokenIndex208, depth208 := position, tokenIndex, depth - { - position209 := position - depth++ - { - position212, tokenIndex212, depth212 := position, tokenIndex, depth - if buffer[position] != rune(' ') { - goto l213 - } - position++ - goto l212 - l213: - position, tokenIndex, depth = position212, tokenIndex212, depth212 - if buffer[position] != rune('\t') { - goto l208 - } - position++ - } - l212: - l210: - { - position211, tokenIndex211, depth211 := position, tokenIndex, depth - { - position214, tokenIndex214, depth214 := position, tokenIndex, depth - if buffer[position] != rune(' ') { - goto l215 - } - position++ - goto l214 - l215: - position, tokenIndex, depth = position214, tokenIndex214, depth214 - if buffer[position] != rune('\t') { - goto l211 - } - position++ - } - l214: - goto l210 - l211: - position, tokenIndex, depth = position211, tokenIndex211, depth211 - } - depth-- - add(rule__, position209) - } - return true - l208: - position, tokenIndex, depth = position208, tokenIndex208, depth208 - return false - }, - nil, - /* 20 Action0 <- <{ p.createInport(buffer[begin:end]) }> */ - nil, - /* 21 Action1 <- <{ p.createOutport(buffer[begin:end]) }> */ - nil, - /* 22 Action2 <- <{ p.inPort = p.port; p.inPortIndex = p.index }> */ - nil, - /* 23 Action3 <- <{ p.outPort = p.port; p.outPortIndex = p.index }> */ - nil, - /* 24 Action4 <- <{ p.createMiddlet() }> */ - nil, - /* 25 Action5 <- <{ p.createLeftlet() }> */ - nil, - /* 26 Action6 <- <{ p.createRightlet() }> */ - nil, - /* 27 Action7 <- <{ p.iip = buffer[begin:end] }> */ - nil, - /* 28 Action8 <- <{ p.nodeProcessName = buffer[begin:end] }> */ - nil, - /* 29 Action9 <- <{ p.createNode() }> */ - nil, - /* 30 Action10 <- <{ p.nodeComponentName = buffer[begin:end] }> */ - nil, - /* 31 Action11 <- <{ p.nodeMeta = buffer[begin:end] }> */ - nil, - /* 32 Action12 <- <{ p.port = buffer[begin:end] }> */ - nil, - /* 33 Action13 <- <{ p.port = buffer[begin:end] }> */ - nil, - /* 34 Action14 <- <{ p.index = buffer[begin:end] }> */ - nil, - } - p.rules = rules -} diff --git a/Godeps/_workspace/src/github.com/oleksandr/fbp/parser.go b/Godeps/_workspace/src/github.com/oleksandr/fbp/parser.go deleted file mode 100644 index 32e8c00..0000000 --- a/Godeps/_workspace/src/github.com/oleksandr/fbp/parser.go +++ /dev/null @@ -1,267 +0,0 @@ -package fbp - -import ( - "fmt" - "strconv" - "strings" -) - -// -// Process of FBP flow -// -type Process struct { - Name string `json:"-"` - Component string `json:"component"` - Metadata map[string]string `json:"metadata,omitempty"` -} - -func (p *Process) String() string { - return p.Name + "(" + p.Component + ")" -} - -// -// Endpoint (in/out port of a Process) -// -type Endpoint struct { - Process string `json:"process"` - Port string `json:"port"` - Index *int `json:"index,omitempty"` -} - -func (e *Endpoint) String() string { - if e.Index != nil { - return fmt.Sprintf("(%s, %s[%v])", e.Process, e.Port, *e.Index) - } - return fmt.Sprintf("(%s, %s)", e.Process, e.Port) -} - -// -// Connection (arc) between endpoints -// -type Connection struct { - Data string `json:"data,omitempty"` - Source *Endpoint `json:"src,omitempty"` - Target *Endpoint `json:"tgt"` -} - -func (c *Connection) String() string { - if c.Data != "" { - return fmt.Sprintf("(%s -> %s )", c.Data, c.Target.String()) - } else if c.Source != nil { - return fmt.Sprintf("(%s -> %s)", c.Source, c.Target.String()) - } else { - return fmt.Sprintf("(???????? -> %s)", c.Target.String()) - } -} - -// -// In/Out ports for composites -// - -// -// Base structure for FBP parser to inherit -// -type BaseFbp struct { - // Private variables to keep state during .fbp parsing - iip string - port string - index string - inPort string - inPortIndex string - outPort string - outPortIndex string - nodeProcessName string - nodeComponentName string - nodeMeta string - srcEndpoint *Endpoint - tgtEndpoint *Endpoint - - // Reference to a name of the composite (if any) - Subgraph string - - // Keeps parsed processes - Processes []*Process - // Keeps parsed connections - Connections []*Connection - - // In/Out ports to export outside (composite components) - Inports map[string]*Endpoint - Outports map[string]*Endpoint -} - -func (self *BaseFbp) createProcessName(name string) string { - if self.Subgraph != "" { - return self.Subgraph + "_" + name - } - return name -} - -func (self *BaseFbp) createLeftlet() { - //log.Println("createLeftlet()", self.nodeProcessName, self.port) - self.srcEndpoint = &Endpoint{ - Process: self.createProcessName(self.nodeProcessName), - Port: self.port, - } - if self.index != "" { - i, err := strconv.Atoi(self.index) - if err == nil { - self.srcEndpoint.Index = new(int) - *self.srcEndpoint.Index = i - } - } - self.nodeProcessName = "" - self.port = "" - self.index = "" -} - -func (self *BaseFbp) createRightlet() { - //log.Println("createRightlet()", self.nodeProcessName, self.port) - self.tgtEndpoint = &Endpoint{ - Process: self.createProcessName(self.nodeProcessName), - Port: self.port, - } - if self.index != "" { - i, err := strconv.Atoi(self.index) - if err == nil { - self.tgtEndpoint.Index = new(int) - *self.tgtEndpoint.Index = i - } - } - var connection *Connection - if self.srcEndpoint != nil { - connection = &Connection{ - Source: self.srcEndpoint, - Target: self.tgtEndpoint, - } - } else { - connection = &Connection{ - Data: self.iip, - Target: self.tgtEndpoint, - } - } - self.Connections = append(self.Connections, connection) - - self.nodeProcessName = "" - self.port = "" - self.index = "" - self.srcEndpoint = nil - self.tgtEndpoint = nil - self.iip = "" -} - -func (self *BaseFbp) createMiddlet() { - //log.Println("createMiddlet()") - self.tgtEndpoint = &Endpoint{ - Process: self.createProcessName(self.nodeProcessName), - Port: self.inPort, - } - if self.inPortIndex != "" { - i, err := strconv.Atoi(self.inPortIndex) - if err == nil { - *self.tgtEndpoint.Index = i - } - } - - var connection *Connection - if self.srcEndpoint != nil { - connection = &Connection{ - Source: self.srcEndpoint, - Target: self.tgtEndpoint, - } - } else { - connection = &Connection{ - Data: self.iip, - Target: self.tgtEndpoint, - } - } - self.Connections = append(self.Connections, connection) - - self.port = self.outPort - self.inPort = "" - self.outPort = "" - self.createLeftlet() -} - -func (self *BaseFbp) createNode() { - if self.nodeComponentName != "" && !self.processExists(self.nodeProcessName) { - process := &Process{ - Name: self.createProcessName(self.nodeProcessName), - Component: self.nodeComponentName, - } - if self.nodeMeta != "" { - m := make(map[string]string) - pairs := strings.Split(self.nodeMeta, ",") - for _, v := range pairs { - kv := strings.SplitN(v, "=", 2) - if len(kv) < 2 { - m[strings.TrimSpace(kv[0])] = "" - } else { - m[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1]) - } - } - process.Metadata = m - } - self.nodeMeta = "" - self.Processes = append(self.Processes, process) - } -} - -func (self *BaseFbp) processExists(name string) bool { - for _, ps := range self.Processes { - if ps.Name == self.createProcessName(name) { - return true - } - } - return false -} - -func (self *BaseFbp) parseExportedPort(str string) (name string, endpoint *Endpoint) { - // str = component.port:externalport - parts := strings.Split(str, ":") - if len(parts) != 2 { - return "", nil - } - name = strings.TrimSpace(parts[1]) - parts = strings.Split(parts[0], ".") - endpoint = &Endpoint{} - endpoint.Port = strings.TrimSpace(parts[1]) - if parts := strings.SplitN(endpoint.Port, "[", 2); len(parts) == 2 { - i, err := strconv.Atoi(strings.TrimSuffix(parts[1], "]")) - if err != nil { - endpoint.Port = parts[0] - *endpoint.Index = i - } - } - endpoint.Process = self.createProcessName(strings.TrimSpace(parts[0])) - return name, endpoint -} - -func (self *BaseFbp) createInport(str string) { - port, endpoint := self.parseExportedPort(str) - if endpoint == nil { - return - } - if self.Inports == nil { - self.Inports = make(map[string]*Endpoint) - } - self.Inports[port] = endpoint -} - -func (self *BaseFbp) createOutport(str string) { - port, endpoint := self.parseExportedPort(str) - if endpoint == nil { - return - } - if self.Outports == nil { - self.Outports = make(map[string]*Endpoint) - } - self.Outports[port] = endpoint -} - -func (self *BaseFbp) Validate() error { - //TODO: check if the network can be executed (it can conform to PEG but be invalid) - // - Process without component (compare # of components with # of processes) - // - Check if all endpoints in connections are in the processes - // - etc - return nil -} diff --git a/Godeps/_workspace/src/github.com/oleksandr/fbp/parser_test.go b/Godeps/_workspace/src/github.com/oleksandr/fbp/parser_test.go deleted file mode 100644 index 83ea8ba..0000000 --- a/Godeps/_workspace/src/github.com/oleksandr/fbp/parser_test.go +++ /dev/null @@ -1,162 +0,0 @@ -package fbp - -import ( - "testing" -) - -const ( - graphIIP string = ` - '5s' - ` - graphTickLogger string = ` - '5s' -> INTERVAL Ticker(core/ticker) OUT -> IN Forward(core/passthru) - Forward OUT -> IN Log(core/console) - ` - graphOneLiner string = ` - Demo OUT -> IN Process RESULT -> INPUT Visualize DISPLAY -> IN Console LOG -> IN D1 - Console ERR -> IN D2 - ` - graphDemo string = ` - 'somefile.txt' -> SOURCE Read(ReadFile:main) - Read() OUT -> IN Split(SplitStr:main) - Split() OUT -> IN Count(Counter:main) - Count() COUNT -> IN Display(Output:main) - Read() ERROR -> IN Display() - ` - graphExportedInPort = ` - INPORT=Read.IN:FILENAME - INPORT=Read.OPTIONS:CONFIG - OUTPORT=Process.OUT:RESULT - Read(ReadFile) OUT -> IN Process(Output) - ` - - graphArrayPorts string = ` - 'pattern1' -> IN[0] Router(router) - Router OUT[0] -> IN Log1(console) - 'pattern2' -> IN[1] Router - Router OUT[1] -> IN Log2(console) - 'pattern3' -> IN[2] Router - Router OUT[2] -> IN Log3(console) - 'some data' -> DATA Router - ` - - graphExportedArrayPort = ` - INPORT=Read.IN:FILENAME - INPORT=Read.OPTIONS:CONFIG - INPORT=Process.IN[0]:EXTRA - OUTPORT=Process.OUT[1]:RESULT - Read(ReadFile) OUT -> IN[0] Process(Output) - Process OUT[0] -> IN Log(Console) - ` - - graphArrayPortsOneline string = ` - 'pattern1' -> IN[0] Router(router) OUT[0] -> IN Log(console) - ` -) - -func testGraph(t *testing.T, graph string) *Fbp { - parser := &Fbp{Buffer: graph} - parser.Init() - err := parser.Parse() - if err != nil { - t.Log(err.Error()) - t.Fail() - } - parser.Execute() - if err = parser.Validate(); err != nil { - t.Log(err.Error()) - t.Fail() - } - - t.Log("------------ Processes --------------") - for _, p := range parser.Processes { - t.Logf("%#v", p.String()) - } - t.Log("----------- Connections -------------") - for _, c := range parser.Connections { - t.Logf("%#v", c.String()) - } - t.Log("----------- Inports -------------") - for k, p := range parser.Inports { - t.Logf("%s: %#v", k, p.String()) - } - t.Log("----------- Outports -------------") - for k, p := range parser.Outports { - t.Logf("%s: %#v", k, p.String()) - } - return parser -} - -func TestGraphIIP(t *testing.T) { - testGraph(t, graphIIP) -} - -func TestGraphTickLogger(t *testing.T) { - parser := testGraph(t, graphTickLogger) - if len(parser.Processes) != 3 { - t.Fatal("Should be only 3 processes") - } - if len(parser.Connections) != 3 { - t.Fatal("Should be only 3 connections") - } -} - -func TestGraphGraphOneLiner(t *testing.T) { - parser := testGraph(t, graphOneLiner) - if len(parser.Processes) != 0 { - t.Fatal("Should be only 0 processes") - } - if len(parser.Connections) != 5 { - t.Fatal("Should be only 5 connections") - } -} - -func TestGraphDemo(t *testing.T) { - parser := testGraph(t, graphDemo) - if len(parser.Processes) != 4 { - t.Fatal("Should be only 4 processes") - } - if len(parser.Connections) != 5 { - t.Fatal("Should be only 5 connections") - } -} - -func TestGraphExportedInPort(t *testing.T) { - parser := testGraph(t, graphExportedInPort) - if len(parser.Processes) != 2 { - t.Fatal("Should be only 2 processes") - } - if len(parser.Connections) != 1 { - t.Fatal("Should be only 1 connections") - } - if len(parser.Inports) != 2 { - t.Fatal("Should be only 2 inports") - } - if len(parser.Outports) != 1 { - t.Fatal("Should be only 1 outports") - } -} - -func TestGraphArrayPorts(t *testing.T) { - parser := testGraph(t, graphArrayPorts) - if len(parser.Processes) != 4 { - t.Fatal("Should be only 4 processes") - } - if len(parser.Connections) != 7 { - t.Fatal("Should be only 7 connections") - } -} - -func TestGraphExportedArrayPort(t *testing.T) { - testGraph(t, graphExportedArrayPort) -} - -func TestGraphArrayPortsOneline(t *testing.T) { - parser := testGraph(t, graphArrayPortsOneline) - if len(parser.Processes) != 4 { - t.Fatal("Should be only 4 processes") - } - if len(parser.Connections) != 7 { - t.Fatal("Should be only 7 connections") - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/LICENSE.txt b/Godeps/_workspace/src/github.com/pebbe/zmq4/LICENSE.txt deleted file mode 100644 index 5b2a4b2..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/LICENSE.txt +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2013-2014, Peter Kleiweg -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/README.md b/Godeps/_workspace/src/github.com/pebbe/zmq4/README.md deleted file mode 100644 index ee9fec6..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/README.md +++ /dev/null @@ -1,58 +0,0 @@ - -A Go interface to [ZeroMQ](http://www.zeromq.org/) version 4. - -This requires ZeroMQ version 4.0.1 or above. To use CURVE security, -ZeroMQ must be installed with [libsodium](https://github.com/jedisct1/libsodium) enabled. - -For ZeroMQ version 3, see: http://github.com/pebbe/zmq3 - -For ZeroMQ version 2, see: http://github.com/pebbe/zmq2 - -Including all examples of [ØMQ - The Guide](http://zguide.zeromq.org/page:all). - -Keywords: zmq, zeromq, 0mq, networks, distributed computing, message passing, fanout, pubsub, pipeline, request-reply - -## Install - - go get github.com/pebbe/zmq4 - -## Docs - - * [package help](http://godoc.org/github.com/pebbe/zmq4) - * [wiki](https://github.com/pebbe/zmq4/wiki) - -## API change - -There has been an API change in commit -0bc5ab465849847b0556295d9a2023295c4d169e of 2014-06-27, 10:17:55 UTC -in the functions `AuthAllow` and `AuthDeny`. - -Old: - - func AuthAllow(addresses ...string) - func AuthDeny(addresses ...string) - -New: - - func AuthAllow(domain string, addresses ...string) - func AuthDeny(domain string, addresses ...string) - -If `domain` can be parsed as an IP address, it will be interpreted as -such, and it and all remaining addresses are added to all domains. - -So this should still work as before: - - zmq.AuthAllow("127.0.0.1", "123.123.123.123") - -But this won't compile: - - a := []string{"127.0.0.1", "123.123.123.123"} - zmq.AuthAllow(a...) - -And needs to be rewritten as: - - a := []string{"127.0.0.1", "123.123.123.123"} - zmq.AuthAllow("*", a...) - -Furthermore, an address can now be a single IP address, as well as an IP -address and mask in CIDR notation, e.g. "123.123.123.0/24". diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/auth.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/auth.go deleted file mode 100644 index 0c2e68e..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/auth.go +++ /dev/null @@ -1,592 +0,0 @@ -/* - -This file implements functionality very similar to that of the xauth module in czmq. - -Notable differences in here: - - - domains are supported - - domains are used in AuthAllow and AuthDeny too - - usernames/passwords are read from memory, not from file - - public keys are read from memory, not from file - - an address can be a single IP address, or an IP address and mask in CIDR notation - - additional functions for configuring server or client socket with a single command - -*/ - -package zmq4 - -import ( - "errors" - "fmt" - "net" -) - -const CURVE_ALLOW_ANY = "*" - -var ( - auth_handler *Socket - auth_quit *Socket - - auth_init = false - auth_verbose = false - - auth_allow = make(map[string]map[string]bool) - auth_deny = make(map[string]map[string]bool) - auth_allow_net = make(map[string][]*net.IPNet) - auth_deny_net = make(map[string][]*net.IPNet) - - auth_users = make(map[string]map[string]string) - - auth_pubkeys = make(map[string]map[string]bool) - - auth_meta_handler = auth_meta_handler_default -) - -func auth_meta_handler_default(version, request_id, domain, address, identity, mechanism string, credentials ...string) (metadata map[string]string) { - return map[string]string{} -} - -func auth_isIP(addr string) bool { - if net.ParseIP(addr) != nil { - return true - } - if _, _, err := net.ParseCIDR(addr); err == nil { - return true - } - return false -} - -func auth_is_allowed(domain, address string) bool { - for _, d := range []string{domain, "*"} { - if a, ok := auth_allow[d]; ok { - if a[address] { - return true - } - } - } - addr := net.ParseIP(address) - if addr != nil { - for _, d := range []string{domain, "*"} { - if a, ok := auth_allow_net[d]; ok { - for _, m := range a { - if m.Contains(addr) { - return true - } - } - } - } - } - return false -} - -func auth_is_denied(domain, address string) bool { - for _, d := range []string{domain, "*"} { - if a, ok := auth_deny[d]; ok { - if a[address] { - return true - } - } - } - addr := net.ParseIP(address) - if addr != nil { - for _, d := range []string{domain, "*"} { - if a, ok := auth_deny_net[d]; ok { - for _, m := range a { - if m.Contains(addr) { - return true - } - } - } - } - } - return false -} - -func auth_has_allow(domain string) bool { - for _, d := range []string{domain, "*"} { - if a, ok := auth_allow[d]; ok { - if len(a) > 0 || len(auth_allow_net[d]) > 0 { - return true - } - } - } - return false -} - -func auth_has_deny(domain string) bool { - for _, d := range []string{domain, "*"} { - if a, ok := auth_deny[d]; ok { - if len(a) > 0 || len(auth_deny_net[d]) > 0 { - return true - } - } - } - return false -} - -func auth_do_handler() { - for { - - msg, err := auth_handler.RecvMessage(0) - if err != nil { - if auth_verbose { - fmt.Println("AUTH: Terminating") - } - break - } - - if msg[0] == "QUIT" { - if auth_verbose { - fmt.Println("AUTH: Quiting") - } - auth_handler.SendMessage("QUIT") - break - } - - version := msg[0] - if version != "1.0" { - panic("AUTH: version != 1.0") - } - - request_id := msg[1] - domain := msg[2] - address := msg[3] - identity := msg[4] - mechanism := msg[5] - credentials := msg[6:] - - username := "" - password := "" - client_key := "" - if mechanism == "PLAIN" { - username = msg[6] - password = msg[7] - } else if mechanism == "CURVE" { - s := msg[6] - if len(s) != 32 { - panic("AUTH: len(client_key) != 32") - } - client_key = Z85encode(s) - } - - allowed := false - denied := false - - if auth_has_allow(domain) { - if auth_is_allowed(domain, address) { - allowed = true - if auth_verbose { - fmt.Printf("AUTH: PASSED (whitelist) domain=%q address=%q\n", domain, address) - } - } else { - denied = true - if auth_verbose { - fmt.Printf("AUTH: DENIED (not in whitelist) domain=%q address=%q\n", domain, address) - } - } - } else if auth_has_deny(domain) { - if auth_is_denied(domain, address) { - denied = true - if auth_verbose { - fmt.Printf("AUTH: DENIED (blacklist) domain=%q address=%q\n", domain, address) - } - } else { - allowed = true - if auth_verbose { - fmt.Printf("AUTH: PASSED (not in blacklist) domain=%q address=%q\n", domain, address) - } - } - } - - // Mechanism-specific checks - if !denied { - if mechanism == "NULL" && !allowed { - // For NULL, we allow if the address wasn't blacklisted - if auth_verbose { - fmt.Printf("AUTH: ALLOWED (NULL)\n") - } - allowed = true - } else if mechanism == "PLAIN" { - // For PLAIN, even a whitelisted address must authenticate - allowed = authenticate_plain(domain, username, password) - } else if mechanism == "CURVE" { - // For CURVE, even a whitelisted address must authenticate - allowed = authenticate_curve(domain, client_key) - } - } - if allowed { - m := auth_meta_handler(version, request_id, domain, address, identity, mechanism, credentials...) - user_id := "" - if uid, ok := m["User-Id"]; ok { - user_id = uid - delete(m, "User-Id") - } - metadata := make([]byte, 0) - for key, value := range m { - if len(key) < 256 { - metadata = append(metadata, auth_meta_blob(key, value)...) - } - } - auth_handler.SendMessage(version, request_id, "200", "OK", user_id, metadata) - } else { - auth_handler.SendMessage(version, request_id, "400", "NO ACCESS", "", "") - } - } - - auth_handler.Close() -} - -func authenticate_plain(domain, username, password string) bool { - for _, dom := range []string{domain, "*"} { - if m, ok := auth_users[dom]; ok { - if m[username] == password { - if auth_verbose { - fmt.Printf("AUTH: ALLOWED (PLAIN) domain=%q username=%q password=%q\n", dom, username, password) - } - return true - } - } - } - if auth_verbose { - fmt.Printf("AUTH: DENIED (PLAIN) domain=%q username=%q password=%q\n", domain, username, password) - } - return false -} - -func authenticate_curve(domain, client_key string) bool { - for _, dom := range []string{domain, "*"} { - if m, ok := auth_pubkeys[dom]; ok { - if m[CURVE_ALLOW_ANY] { - if auth_verbose { - fmt.Printf("AUTH: ALLOWED (CURVE any client) domain=%q\n", dom) - } - return true - } - if m[client_key] { - if auth_verbose { - fmt.Printf("AUTH: ALLOWED (CURVE) domain=%q client_key=%q\n", dom, client_key) - } - return true - } - } - } - if auth_verbose { - fmt.Printf("AUTH: DENIED (CURVE) domain=%q client_key=%q\n", domain, client_key) - } - return false -} - -// Start authentication. -// -// Note that until you add policies, all incoming NULL connections are allowed -// (classic ZeroMQ behaviour), and all PLAIN and CURVE connections are denied. -func AuthStart() (err error) { - if auth_init { - if auth_verbose { - fmt.Println("AUTH: Already running") - } - return errors.New("Auth is already running") - } - - auth_handler, err = NewSocket(REP) - if err != nil { - return - } - err = auth_handler.Bind("inproc://zeromq.zap.01") - if err != nil { - auth_handler.Close() - return - } - - auth_quit, err = NewSocket(REQ) - if err != nil { - auth_handler.Close() - return - } - err = auth_quit.Connect("inproc://zeromq.zap.01") - if err != nil { - auth_handler.Close() - auth_quit.Close() - return - } - - go auth_do_handler() - - if auth_verbose { - fmt.Println("AUTH: Starting") - } - - auth_init = true - - return -} - -// Stop authentication. -func AuthStop() { - if !auth_init { - if auth_verbose { - fmt.Println("AUTH: Not running, can't stop") - } - return - } - if auth_verbose { - fmt.Println("AUTH: Stopping") - } - auth_quit.SendMessage("QUIT") - auth_quit.RecvMessage(0) - auth_quit.Close() - if auth_verbose { - fmt.Println("AUTH: Stopped") - } - - auth_init = false - -} - -// Allow (whitelist) some addresses for a domain. -// -// An address can be a single IP address, or an IP address and mask in CIDR notation. -// -// For NULL, all clients from these addresses will be accepted. -// -// For PLAIN and CURVE, they will be allowed to continue with authentication. -// -// You can call this method multiple times to whitelist multiple IP addresses. -// -// If you whitelist a single address for a domain, any non-whitelisted addresses -// for that domain are treated as blacklisted. -// -// Use domain "*" for all domains. -// -// For backward compatibility: if domain can be parsed as an IP address, it will be -// interpreted as another address, and it and all remaining addresses will be added -// to all domains. -func AuthAllow(domain string, addresses ...string) { - if auth_isIP(domain) { - auth_allow_for_domain("*", domain) - auth_allow_for_domain("*", addresses...) - } else { - auth_allow_for_domain(domain, addresses...) - } -} - -func auth_allow_for_domain(domain string, addresses ...string) { - if _, ok := auth_allow[domain]; !ok { - auth_allow[domain] = make(map[string]bool) - auth_allow_net[domain] = make([]*net.IPNet, 0) - } - for _, address := range addresses { - if _, ipnet, err := net.ParseCIDR(address); err == nil { - auth_allow_net[domain] = append(auth_allow_net[domain], ipnet) - } else if net.ParseIP(address) != nil { - auth_allow[domain][address] = true - } else { - if auth_verbose { - fmt.Printf("AUTH: Allow for domain %q: %q is not a valid address or network\n", domain, address) - } - } - } -} - -// Deny (blacklist) some addresses for a domain. -// -// An address can be a single IP address, or an IP address and mask in CIDR notation. -// -// For all security mechanisms, this rejects the connection without any further authentication. -// -// Use either a whitelist for a domain, or a blacklist for a domain, not both. -// If you define both a whitelist and a blacklist for a domain, only the whitelist takes effect. -// -// Use domain "*" for all domains. -// -// For backward compatibility: if domain can be parsed as an IP address, it will be -// interpreted as another address, and it and all remaining addresses will be added -// to all domains. -func AuthDeny(domain string, addresses ...string) { - if auth_isIP(domain) { - auth_deny_for_domain("*", domain) - auth_deny_for_domain("*", addresses...) - } else { - auth_deny_for_domain(domain, addresses...) - } -} - -func auth_deny_for_domain(domain string, addresses ...string) { - if _, ok := auth_deny[domain]; !ok { - auth_deny[domain] = make(map[string]bool) - auth_deny_net[domain] = make([]*net.IPNet, 0) - } - for _, address := range addresses { - if _, ipnet, err := net.ParseCIDR(address); err == nil { - auth_deny_net[domain] = append(auth_deny_net[domain], ipnet) - } else if net.ParseIP(address) != nil { - auth_deny[domain][address] = true - } else { - if auth_verbose { - fmt.Printf("AUTH: Deny for domain %q: %q is not a valid address or network\n", domain, address) - } - } - } -} - -// Add a user for PLAIN authentication for a given domain. -// -// Set `domain` to "*" to apply to all domains. -func AuthPlainAdd(domain, username, password string) { - if _, ok := auth_users[domain]; !ok { - auth_users[domain] = make(map[string]string) - } - auth_users[domain][username] = password -} - -// Remove users from PLAIN authentication for a given domain. -func AuthPlainRemove(domain string, usernames ...string) { - if u, ok := auth_users[domain]; ok { - for _, username := range usernames { - delete(u, username) - } - } -} - -// Remove all users from PLAIN authentication for a given domain. -func AuthPlainRemoveAll(domain string) { - delete(auth_users, domain) -} - -// Add public user keys for CURVE authentication for a given domain. -// -// To cover all domains, use "*". -// -// Public keys are in Z85 printable text format. -// -// To allow all client keys without checking, specify CURVE_ALLOW_ANY for the key. -func AuthCurveAdd(domain string, pubkeys ...string) { - if _, ok := auth_pubkeys[domain]; !ok { - auth_pubkeys[domain] = make(map[string]bool) - } - for _, key := range pubkeys { - auth_pubkeys[domain][key] = true - } -} - -// Remove user keys from CURVE authentication for a given domain. -func AuthCurveRemove(domain string, pubkeys ...string) { - if p, ok := auth_pubkeys[domain]; ok { - for _, pubkey := range pubkeys { - delete(p, pubkey) - } - } -} - -// Remove all user keys from CURVE authentication for a given domain. -func AuthCurveRemoveAll(domain string) { - delete(auth_pubkeys, domain) -} - -// Enable verbose tracing of commands and activity. -func AuthSetVerbose(verbose bool) { - auth_verbose = verbose -} - -/* -This function sets the metadata handler that is called by the ZAP -handler to retrieve key/value properties that should be set on reply -messages in case of a status code "200" (succes). - -Default properties are `Socket-Type`, which is already set, and -`Identity` and `User-Id` that are empty by default. The last two can be -set, and more properties can be added. - -The `User-Id` property is used for the `user id` frame of the reply -message. All other properties are stored in the `metadata` frame of the -reply message. - -The default handler returns an empty map. - -For the meaning of the handler arguments, and other details, see: -http://rfc.zeromq.org/spec:27#toc10 -*/ -func AuthSetMetadataHandler( - handler func( - version, request_id, domain, address, identity, mechanism string, credentials ...string) (metadata map[string]string)) { - auth_meta_handler = handler -} - -/* -This encodes a key/value pair into the format used by a ZAP handler. - -Returns an error if key is more then 255 characters long. -*/ -func AuthMetaBlob(key, value string) (blob []byte, err error) { - if len(key) > 255 { - return []byte{}, errors.New("Key too long") - } - return auth_meta_blob(key, value), nil -} - -func auth_meta_blob(name, value string) []byte { - l1 := len(name) - l2 := len(value) - b := make([]byte, l1+l2+5) - b[0] = byte(l1) - b[l1+1] = byte(l2 >> 24 & 255) - b[l1+2] = byte(l2 >> 16 & 255) - b[l1+3] = byte(l2 >> 8 & 255) - b[l1+4] = byte(l2 & 255) - copy(b[1:], []byte(name)) - copy(b[5+l1:], []byte(value)) - return b -} - -//. Additional functions for configuring server or client socket with a single command - -// Set NULL server role. -func (server *Socket) ServerAuthNull(domain string) error { - err := server.SetPlainServer(0) - if err == nil { - err = server.SetZapDomain(domain) - } - return err -} - -// Set PLAIN server role. -func (server *Socket) ServerAuthPlain(domain string) error { - err := server.SetPlainServer(1) - if err == nil { - err = server.SetZapDomain(domain) - } - return err -} - -// Set CURVE server role. -func (server *Socket) ServerAuthCurve(domain, secret_key string) error { - err := server.SetCurveServer(1) - if err == nil { - err = server.SetCurveSecretkey(secret_key) - } - if err == nil { - err = server.SetZapDomain(domain) - } - return err -} - -// Set PLAIN client role. -func (client *Socket) ClientAuthPlain(username, password string) error { - err := client.SetPlainUsername(username) - if err == nil { - err = client.SetPlainPassword(password) - } - return err -} - -// Set CURVE client role. -func (client *Socket) ClientAuthCurve(server_public_key, client_public_key, client_secret_key string) error { - err := client.SetCurveServerkey(server_public_key) - if err == nil { - err = client.SetCurvePublickey(client_public_key) - } - if err == nil { - client.SetCurveSecretkey(client_secret_key) - } - return err -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/auth_test.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/auth_test.go deleted file mode 100644 index 95d139d..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/auth_test.go +++ /dev/null @@ -1,117 +0,0 @@ -package zmq4_test - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" -) - -func ExampleAuthStart() { - - checkErr := func(err error) bool { - if err == nil { - return false - } - log.Println(err) - return true - } - - zmq.AuthSetVerbose(false) - - // Start authentication engine - err := zmq.AuthStart() - if checkErr(err) { - return - } - defer zmq.AuthStop() - - zmq.AuthSetMetadataHandler( - func(version, request_id, domain, address, identity, mechanism string, credentials ...string) (metadata map[string]string) { - return map[string]string{ - "Identity": identity, - "User-Id": "anonymous", - "Hello": "World!", - "Foo": "Bar", - } - }) - - zmq.AuthAllow("domain1", "127.0.0.1") - - // We need two certificates, one for the client and one for - // the server. The client must know the server's public key - // to make a CURVE connection. - client_public, client_secret, err := zmq.NewCurveKeypair() - if checkErr(err) { - return - } - server_public, server_secret, err := zmq.NewCurveKeypair() - if checkErr(err) { - return - } - - // Tell authenticator to use this public client key - zmq.AuthCurveAdd("domain1", client_public) - - // Create and bind server socket - server, err := zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - defer server.Close() - server.SetIdentity("Server1") - server.ServerAuthCurve("domain1", server_secret) - err = server.Bind("tcp://*:9000") - if checkErr(err) { - return - } - - // Create and connect client socket - client, err := zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - defer client.Close() - server.SetIdentity("Client1") - client.ClientAuthCurve(server_public, client_public, client_secret) - err = client.Connect("tcp://127.0.0.1:9000") - if checkErr(err) { - return - } - - // Send a message from client to server - _, err = client.SendMessage("Greatings", "Earthlings!") - if checkErr(err) { - return - } - - // Receive message and metadata on the server - keys := []string{"Identity", "User-Id", "Socket-Type", "Hello", "Foo", "Fuz"} - message, metadata, err := server.RecvMessageWithMetadata(0, keys...) - if checkErr(err) { - return - } - fmt.Println(message) - if _, minor, _ := zmq.Version(); minor < 1 { - // Metadata requires at least ZeroMQ version 4.1 - fmt.Println(`Identity: "Server1" true`) - fmt.Println(`User-Id: "anonymous" true`) - fmt.Println(`Socket-Type: "DEALER" true`) - fmt.Println(`Hello: "World!" true`) - fmt.Println(`Foo: "Bar" true`) - fmt.Println(`Fuz: "" false`) - } else { - for _, key := range keys { - value, ok := metadata[key] - fmt.Printf("%v: %q %v\n", key, value, ok) - } - } - // Output: - // [Greatings Earthlings!] - // Identity: "Server1" true - // User-Id: "anonymous" true - // Socket-Type: "DEALER" true - // Hello: "World!" true - // Foo: "Bar" true - // Fuz: "" false -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/doc.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/doc.go deleted file mode 100644 index eee1186..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -/* -A Go interface to ZeroMQ (zmq, 0mq) version 4. - -For ZeroMQ version 3, see: http://github.com/pebbe/zmq3 - -For ZeroMQ version 2, see: http://github.com/pebbe/zmq2 - -http://www.zeromq.org/ - -See also the wiki: https://github.com/pebbe/zmq4/wiki - -A note on the use of a context: - -This package provides a default context. This is what will be used by -the functions without a context receiver, that create a socket or -manipulate the context. Package developers that import this package -should probably not use the default context with its associated -functions, but create their own context(s). See: type Context. -*/ -package zmq4 diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/errors.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/errors.go deleted file mode 100644 index 48dcdc3..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/errors.go +++ /dev/null @@ -1,92 +0,0 @@ -package zmq4 - -/* -#include -*/ -import "C" - -import ( - "syscall" -) - -// An Errno is an unsigned number describing an error condition as returned by a call to ZeroMQ. -// It implements the error interface. -// The number is either a standard system error, or an error defined by the C library of ZeroMQ. -type Errno uintptr - -const ( - // Error conditions defined by the C library of ZeroMQ. - - // On Windows platform some of the standard POSIX errnos are not defined. - EADDRINUSE = Errno(C.EADDRINUSE) - EADDRNOTAVAIL = Errno(C.EADDRNOTAVAIL) - EAFNOSUPPORT = Errno(C.EAFNOSUPPORT) - ECONNABORTED = Errno(C.ECONNABORTED) - ECONNREFUSED = Errno(C.ECONNREFUSED) - ECONNRESET = Errno(C.ECONNRESET) - EHOSTUNREACH = Errno(C.EHOSTUNREACH) - EINPROGRESS = Errno(C.EINPROGRESS) - EMSGSIZE = Errno(C.EMSGSIZE) - ENETDOWN = Errno(C.ENETDOWN) - ENETRESET = Errno(C.ENETRESET) - ENETUNREACH = Errno(C.ENETUNREACH) - ENOBUFS = Errno(C.ENOBUFS) - ENOTCONN = Errno(C.ENOTCONN) - ENOTSOCK = Errno(C.ENOTSOCK) - ENOTSUP = Errno(C.ENOTSUP) - EPROTONOSUPPORT = Errno(C.EPROTONOSUPPORT) - ETIMEDOUT = Errno(C.ETIMEDOUT) - - // Native 0MQ error codes. - EFSM = Errno(C.EFSM) - EMTHREAD = Errno(C.EMTHREAD) - ENOCOMPATPROTO = Errno(C.ENOCOMPATPROTO) - ETERM = Errno(C.ETERM) -) - -func errget(err error) error { - eno, ok := err.(syscall.Errno) - if ok { - return Errno(eno) - } - return err -} - -// Return Errno as string. -func (errno Errno) Error() string { - if errno >= C.ZMQ_HAUSNUMERO { - return C.GoString(C.zmq_strerror(C.int(errno))) - } - return syscall.Errno(errno).Error() -} - -/* -Convert error to Errno. - -Example usage: - - switch AsErrno(err) { - - case zmq.Errno(syscall.EINTR): - // standard system error - - // call was interrupted - - case zmq.ETERM: - // error defined by ZeroMQ - - // context was terminated - - } - -See also: examples/interrupt.go -*/ -func AsErrno(err error) Errno { - if eno, ok := err.(Errno); ok { - return eno - } - if eno, ok := err.(syscall.Errno); ok { - return Errno(eno) - } - return Errno(0) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/Build.sh b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/Build.sh deleted file mode 100644 index bad3a07..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/Build.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh - -go get code.google.com/p/go-uuid/uuid - -for i in bstar mdapi flcliapi kvsimple kvmsg clone intface -do - go install github.com/pebbe/zmq4/examples/$i -done - -cd `dirname $0` - -goos=`go env GOOS` -gobin=`go env GOBIN` -if [ "$gobin" = "" ] -then - gobin=`go env GOPATH` - if [ "$gobin" = "" ] - then - gobin=`go env GOROOT` - fi - gobin=`echo $gobin | sed -e 's/:.*//'` - gobin=$gobin/bin -fi - -dir=$gobin/zmq4-examples - -echo Installing examples in $dir - -mkdir -p $dir - -for i in *.sh -do - if [ $i != Build.sh ] - then - cp -u $i $dir - fi -done - -src='' -for i in *.go -do - if [ $i = interrupt.go ] - then - if [ $goos = windows -o $goos = plan9 ] - then - continue - fi - fi - bin=$dir/`basename $i .go` - if [ ! -f $bin -o $i -nt $bin ] - then - src="$src $i" - fi -done - -libs=`pkg-config --libs-only-L libzmq` -if [ "$libs" = "" ] -then - for i in $src - do - go build -o $dir/`basename $i .go` $i - done -else - libs="-r `echo $libs | sed -e 's/-L//; s/ *-L/:/g'`" - for i in $src - do - go build -ldflags="$libs" -o $dir/`basename $i .go` $i - done -fi diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/README.md b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/README.md deleted file mode 100644 index 764a7ea..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/README.md +++ /dev/null @@ -1,2 +0,0 @@ -These are examples from [ØMQ - The Guide](http://zguide.zeromq.org/page:all), -re-implemented for the current Go package. diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/asyncsrv.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/asyncsrv.go deleted file mode 100644 index 16ec3c9..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/asyncsrv.go +++ /dev/null @@ -1,138 +0,0 @@ -// -// Asynchronous client-to-server (DEALER to ROUTER). -// -// While this example runs in a single process, that is just to make -// it easier to start and stop the example. Each task has its own -// context and conceptually acts as a separate process. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" - "math/rand" - "sync" - "time" -) - -// --------------------------------------------------------------------- -// This is our client task -// It connects to the server, and then sends a request once per second -// It collects responses as they arrive, and it prints them out. We will -// run several client tasks in parallel, each with a different random ID. - -func client_task() { - var mu sync.Mutex - - client, _ := zmq.NewSocket(zmq.DEALER) - defer client.Close() - - // Set random identity to make tracing easier - set_id(client) - client.Connect("tcp://localhost:5570") - - go func() { - for request_nbr := 1; true; request_nbr++ { - time.Sleep(time.Second) - mu.Lock() - client.SendMessage(fmt.Sprintf("request #%d", request_nbr)) - mu.Unlock() - } - }() - - for { - time.Sleep(10 * time.Millisecond) - mu.Lock() - msg, err := client.RecvMessage(zmq.DONTWAIT) - if err == nil { - id, _ := client.GetIdentity() - fmt.Println(msg[0], id) - } - mu.Unlock() - } -} - -// This is our server task. -// It uses the multithreaded server model to deal requests out to a pool -// of workers and route replies back to clients. One worker can handle -// one request at a time but one client can talk to multiple workers at -// once. - -func server_task() { - - // Frontend socket talks to clients over TCP - frontend, _ := zmq.NewSocket(zmq.ROUTER) - defer frontend.Close() - frontend.Bind("tcp://*:5570") - - // Backend socket talks to workers over inproc - backend, _ := zmq.NewSocket(zmq.DEALER) - defer backend.Close() - backend.Bind("inproc://backend") - - // Launch pool of worker threads, precise number is not critical - for i := 0; i < 5; i++ { - go server_worker() - } - - // Connect backend to frontend via a proxy - err := zmq.Proxy(frontend, backend, nil) - log.Fatalln("Proxy interrupted:", err) -} - -// Each worker task works on one request at a time and sends a random number -// of replies back, with random delays between replies: - -func server_worker() { - - worker, _ := zmq.NewSocket(zmq.DEALER) - defer worker.Close() - worker.Connect("inproc://backend") - - for { - // The DEALER socket gives us the reply envelope and message - msg, _ := worker.RecvMessage(0) - identity, content := pop(msg) - - // Send 0..4 replies back - replies := rand.Intn(5) - for reply := 0; reply < replies; reply++ { - // Sleep for some fraction of a second - time.Sleep(time.Duration(rand.Intn(1000)+1) * time.Millisecond) - worker.SendMessage(identity, content) - } - } -} - -// The main thread simply starts several clients, and a server, and then -// waits for the server to finish. - -func main() { - rand.Seed(time.Now().UnixNano()) - - go client_task() - go client_task() - go client_task() - go server_task() - - // Run for 5 seconds then quit - time.Sleep(5 * time.Second) -} - -func set_id(soc *zmq.Socket) { - identity := fmt.Sprintf("%04X-%04X", rand.Intn(0x10000), rand.Intn(0x10000)) - soc.SetIdentity(identity) -} - -func pop(msg []string) (head, tail []string) { - if msg[1] == "" { - head = msg[:2] - tail = msg[2:] - } else { - head = msg[:1] - tail = msg[1:] - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstar/bstar.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstar/bstar.go deleted file mode 100644 index 05939cd..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstar/bstar.go +++ /dev/null @@ -1,275 +0,0 @@ -// bstar - Binary Star reactor. -package bstar - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "errors" - "log" - "strconv" - "time" -) - -const ( - PRIMARY = true - BACKUP = false -) - -// States we can be in at any point in time -type state_t int - -const ( - _ = state_t(iota) - state_PRIMARY // Primary, waiting for peer to connect - state_BACKUP // Backup, waiting for peer to connect - state_ACTIVE // Active - accepting connections - state_PASSIVE // Passive - not accepting connections -) - -// Events, which start with the states our peer can be in -type event_t int - -const ( - _ = event_t(iota) - peer_PRIMARY // HA peer is pending primary - peer_BACKUP // HA peer is pending backup - peer_ACTIVE // HA peer is active - peer_PASSIVE // HA peer is passive - client_REQUEST // Client makes request -) - -// Structure of our class - -type Bstar struct { - Reactor *zmq.Reactor // Reactor loop - statepub *zmq.Socket // State publisher - statesub *zmq.Socket // State subscriber - state state_t // Current state - event event_t // Current event - peer_expiry time.Time // When peer is considered 'dead' - voter_fn func(*zmq.Socket) error // Voting socket handler - active_fn func() error // Call when become active - passive_fn func() error // Call when become passive -} - -// The finite-state machine is the same as in the proof-of-concept server. -// To understand this reactor in detail, first read the CZMQ zloop class. - -// We send state information every this often -// If peer doesn't respond in two heartbeats, it is 'dead' -const ( - bstar_HEARTBEAT = 1000 * time.Millisecond // In msecs -) - -// --------------------------------------------------------------------- -// Binary Star finite state machine (applies event to state) -// Returns error if there was an exception, nil if event was valid. - -func (bstar *Bstar) execute_fsm() (exception error) { - // Primary server is waiting for peer to connect - // Accepts client_REQUEST events in this state - if bstar.state == state_PRIMARY { - if bstar.event == peer_BACKUP { - log.Println("I: connected to backup (passive), ready as active") - bstar.state = state_ACTIVE - if bstar.active_fn != nil { - bstar.active_fn() - } - } else if bstar.event == peer_ACTIVE { - log.Println("I: connected to backup (active), ready as passive") - bstar.state = state_PASSIVE - if bstar.passive_fn != nil { - bstar.passive_fn() - } - } else if bstar.event == client_REQUEST { - // Allow client requests to turn us into the active if we've - // waited sufficiently long to believe the backup is not - // currently acting as active (i.e., after a failover) - if time.Now().After(bstar.peer_expiry) { - log.Println("I: request from client, ready as active") - bstar.state = state_ACTIVE - if bstar.active_fn != nil { - bstar.active_fn() - } - } else { - // Don't respond to clients yet - it's possible we're - // performing a failback and the backup is currently active - exception = errors.New("Exception") - } - } - } else if bstar.state == state_BACKUP { - // Backup server is waiting for peer to connect - // Rejects client_REQUEST events in this state - if bstar.event == peer_ACTIVE { - log.Println("I: connected to primary (active), ready as passive") - bstar.state = state_PASSIVE - if bstar.passive_fn != nil { - bstar.passive_fn() - } - } else if bstar.event == client_REQUEST { - exception = errors.New("Exception") - } - } else if bstar.state == state_ACTIVE { - // Server is active - // Accepts client_REQUEST events in this state - // The only way out of ACTIVE is death - if bstar.event == peer_ACTIVE { - // Two actives would mean split-brain - log.Println("E: fatal error - dual actives, aborting") - exception = errors.New("Exception") - } - } else if bstar.state == state_PASSIVE { - // Server is passive - // client_REQUEST events can trigger failover if peer looks dead - if bstar.event == peer_PRIMARY { - // Peer is restarting - become active, peer will go passive - log.Println("I: primary (passive) is restarting, ready as active") - bstar.state = state_ACTIVE - } else if bstar.event == peer_BACKUP { - // Peer is restarting - become active, peer will go passive - log.Println("I: backup (passive) is restarting, ready as active") - bstar.state = state_ACTIVE - } else if bstar.event == peer_PASSIVE { - // Two passives would mean cluster would be non-responsive - log.Println("E: fatal error - dual passives, aborting") - exception = errors.New("Exception") - } else if bstar.event == client_REQUEST { - // Peer becomes active if timeout has passed - // It's the client request that triggers the failover - if time.Now().After(bstar.peer_expiry) { - // If peer is dead, switch to the active state - log.Println("I: failover successful, ready as active") - bstar.state = state_ACTIVE - } else { - // If peer is alive, reject connections - exception = errors.New("Exception") - } - } - // Call state change handler if necessary - if bstar.state == state_ACTIVE && bstar.active_fn != nil { - bstar.active_fn() - } - } - return -} - -func (bstar *Bstar) update_peer_expiry() { - bstar.peer_expiry = time.Now().Add(2 * bstar_HEARTBEAT) -} - -// --------------------------------------------------------------------- -// Reactor event handlers... - -// Publish our state to peer -func (bstar *Bstar) send_state() (err error) { - _, err = bstar.statepub.SendMessage(int(bstar.state)) - return -} - -// Receive state from peer, execute finite state machine -func (bstar *Bstar) recv_state() (err error) { - msg, err := bstar.statesub.RecvMessage(0) - if err == nil { - e, _ := strconv.Atoi(msg[0]) - bstar.event = event_t(e) - } - return bstar.execute_fsm() -} - -// Application wants to speak to us, see if it's possible -func (bstar *Bstar) voter_ready(socket *zmq.Socket) error { - // If server can accept input now, call appl handler - bstar.event = client_REQUEST - err := bstar.execute_fsm() - if err == nil { - bstar.voter_fn(socket) - } else { - // Destroy waiting message, no-one to read it - socket.RecvMessage(0) - } - return nil -} - -// This is the constructor for our bstar class. We have to tell it whether -// we're primary or backup server, and our local and remote endpoints to -// bind and connect to: - -func New(primary bool, local, remote string) (bstar *Bstar, err error) { - - bstar = &Bstar{} - - // Initialize the Binary Star - bstar.Reactor = zmq.NewReactor() - if primary { - bstar.state = state_PRIMARY - } else { - bstar.state = state_BACKUP - } - - // Create publisher for state going to peer - bstar.statepub, err = zmq.NewSocket(zmq.PUB) - bstar.statepub.Bind(local) - - // Create subscriber for state coming from peer - bstar.statesub, err = zmq.NewSocket(zmq.SUB) - bstar.statesub.SetSubscribe("") - bstar.statesub.Connect(remote) - - // Set-up basic reactor events - bstar.Reactor.AddChannelTime(time.Tick(bstar_HEARTBEAT), 1, - func(i interface{}) error { return bstar.send_state() }) - bstar.Reactor.AddSocket(bstar.statesub, zmq.POLLIN, - func(e zmq.State) error { return bstar.recv_state() }) - - return -} - -// The voter method registers a client voter socket. Messages received -// on this socket provide the client_REQUEST events for the Binary Star -// FSM and are passed to the provided application handler. We require -// exactly one voter per bstar instance: - -func (bstar *Bstar) Voter(endpoint string, socket_type zmq.Type, handler func(*zmq.Socket) error) { - // Hold actual handler so we can call this later - socket, _ := zmq.NewSocket(socket_type) - socket.Bind(endpoint) - if bstar.voter_fn != nil { - panic("Double voter function") - } - bstar.voter_fn = handler - bstar.Reactor.AddSocket(socket, zmq.POLLIN, - func(e zmq.State) error { return bstar.voter_ready(socket) }) -} - -// Register handlers to be called each time there's a state change: - -func (bstar *Bstar) NewActive(handler func() error) { - if bstar.active_fn != nil { - panic("Double Active") - } - bstar.active_fn = handler -} - -func (bstar *Bstar) NewPassive(handler func() error) { - if bstar.passive_fn != nil { - panic("Double Passive") - } - bstar.passive_fn = handler -} - -// Enable/disable verbose tracing, for debugging: - -func (bstar *Bstar) SetVerbose(verbose bool) { - bstar.Reactor.SetVerbose(verbose) -} - -//? Finally, start the configured reactor. It will end if any handler -//? returns error to the reactor, or if the process receives SIGINT or SIGTERM: - -func (bstar *Bstar) Start() error { - if bstar.voter_fn == nil { - panic("Missing voter function") - } - bstar.update_peer_expiry() - return bstar.Reactor.Run(bstar_HEARTBEAT / 5) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarcli.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarcli.go deleted file mode 100644 index caca793..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarcli.go +++ /dev/null @@ -1,83 +0,0 @@ -// -// Binary Star client proof-of-concept implementation. This client does no -// real work; it just demonstrates the Binary Star failover model. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "strconv" - "time" -) - -const ( - REQUEST_TIMEOUT = 1000 * time.Millisecond // msecs - SETTLE_DELAY = 2000 * time.Millisecond // Before failing over -) - -func main() { - - server := []string{"tcp://localhost:5001", "tcp://localhost:5002"} - server_nbr := 0 - - fmt.Printf("I: connecting to server at %s...\n", server[server_nbr]) - client, _ := zmq.NewSocket(zmq.REQ) - client.Connect(server[server_nbr]) - - poller := zmq.NewPoller() - poller.Add(client, zmq.POLLIN) - - sequence := 0 -LOOP: - for { - // We send a request, then we work to get a reply - sequence++ - client.SendMessage(sequence) - - for expect_reply := true; expect_reply; { - // Poll socket for a reply, with timeout - polled, err := poller.Poll(REQUEST_TIMEOUT) - if err != nil { - break LOOP // Interrupted - } - - // We use a Lazy Pirate strategy in the client. If there's no - // reply within our timeout, we close the socket and try again. - // In Binary Star, it's the client vote which decides which - // server is primary; the client must therefore try to connect - // to each server in turn: - - if len(polled) == 1 { - // We got a reply from the server, must match sequence - reply, _ := client.RecvMessage(0) - seq, _ := strconv.Atoi(reply[0]) - if seq == sequence { - fmt.Printf("I: server replied OK (%s)\n", reply[0]) - expect_reply = false - time.Sleep(time.Second) // One request per second - } else { - fmt.Printf("E: bad reply from server: %q\n", reply) - } - - } else { - fmt.Println("W: no response from server, failing over") - - // Old socket is confused; close it and open a new one - client.Close() - server_nbr = 1 - server_nbr - time.Sleep(SETTLE_DELAY) - fmt.Printf("I: connecting to server at %s...\n", server[server_nbr]) - client, _ = zmq.NewSocket(zmq.REQ) - client.Connect(server[server_nbr]) - - poller = zmq.NewPoller() - poller.Add(client, zmq.POLLIN) - - // Send request again, on new socket - client.SendMessage(sequence) - } - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarsrv.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarsrv.go deleted file mode 100644 index 25bfefb..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarsrv.go +++ /dev/null @@ -1,194 +0,0 @@ -// -// Binary Star server proof-of-concept implementation. This server does no -// real work; it just demonstrates the Binary Star failover model. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "os" - "strconv" - "time" -) - -// States we can be in at any point in time -type state_t int - -const ( - _ = state_t(iota) - STATE_PRIMARY // Primary, waiting for peer to connect - STATE_BACKUP // Backup, waiting for peer to connect - STATE_ACTIVE // Active - accepting connections - STATE_PASSIVE // Passive - not accepting connections -) - -// Events, which start with the states our peer can be in -type event_t int - -const ( - _ = event_t(iota) - PEER_PRIMARY // HA peer is pending primary - PEER_BACKUP // HA peer is pending backup - PEER_ACTIVE // HA peer is active - PEER_PASSIVE // HA peer is passive - CLIENT_REQUEST // Client makes request -) - -// Our finite state machine -type bstar_t struct { - state state_t // Current state - event event_t // Current event - peer_expiry time.Time // When peer is considered 'dead' -} - -// We send state information every this often -// If peer doesn't respond in two heartbeats, it is 'dead' -const ( - HEARTBEAT = 1000 * time.Millisecond // In msecs -) - -// The heart of the Binary Star design is its finite-state machine (FSM). -// The FSM runs one event at a time. We apply an event to the current state, -// which checks if the event is accepted, and if so sets a new state: - -func StateMachine(fsm *bstar_t) (exception bool) { - // These are the PRIMARY and BACKUP states; we're waiting to become - // ACTIVE or PASSIVE depending on events we get from our peer: - if fsm.state == STATE_PRIMARY { - if fsm.event == PEER_BACKUP { - fmt.Println("I: connected to backup (passive), ready as active") - fsm.state = STATE_ACTIVE - } else if fsm.event == PEER_ACTIVE { - fmt.Println("I: connected to backup (active), ready as passive") - fsm.state = STATE_PASSIVE - } - // Accept client connections - } else if fsm.state == STATE_BACKUP { - if fsm.event == PEER_ACTIVE { - fmt.Println("I: connected to primary (active), ready as passive") - fsm.state = STATE_PASSIVE - } else if fsm.event == CLIENT_REQUEST { - // Reject client connections when acting as backup - exception = true - } - } else if fsm.state == STATE_ACTIVE { - // These are the ACTIVE and PASSIVE states: - if fsm.event == PEER_ACTIVE { - // Two actives would mean split-brain - fmt.Println("E: fatal error - dual actives, aborting") - exception = true - } - } else if fsm.state == STATE_PASSIVE { - // Server is passive - // CLIENT_REQUEST events can trigger failover if peer looks dead - if fsm.event == PEER_PRIMARY { - // Peer is restarting - become active, peer will go passive - fmt.Println("I: primary (passive) is restarting, ready as active") - fsm.state = STATE_ACTIVE - } else if fsm.event == PEER_BACKUP { - // Peer is restarting - become active, peer will go passive - fmt.Println("I: backup (passive) is restarting, ready as active") - fsm.state = STATE_ACTIVE - } else if fsm.event == PEER_PASSIVE { - // Two passives would mean cluster would be non-responsive - fmt.Println("E: fatal error - dual passives, aborting") - exception = true - } else if fsm.event == CLIENT_REQUEST { - // Peer becomes active if timeout has passed - // It's the client request that triggers the failover - if time.Now().After(fsm.peer_expiry) { - // If peer is dead, switch to the active state - fmt.Println("I: failover successful, ready as active") - fsm.state = STATE_ACTIVE - } else { - // If peer is alive, reject connections - exception = true - } - } - } - return -} - -// This is our main task. First we bind/connect our sockets with our -// peer and make sure we will get state messages correctly. We use -// three sockets; one to publish state, one to subscribe to state, and -// one for client requests/replies: - -func main() { - // Arguments can be either of: - // -p primary server, at tcp://localhost:5001 - // -b backup server, at tcp://localhost:5002 - statepub, _ := zmq.NewSocket(zmq.PUB) - statesub, _ := zmq.NewSocket(zmq.SUB) - statesub.SetSubscribe("") - frontend, _ := zmq.NewSocket(zmq.ROUTER) - fsm := &bstar_t{peer_expiry: time.Now().Add(2 * HEARTBEAT)} - - if len(os.Args) == 2 && os.Args[1] == "-p" { - fmt.Println("I: Primary active, waiting for backup (passive)") - frontend.Bind("tcp://*:5001") - statepub.Bind("tcp://*:5003") - statesub.Connect("tcp://localhost:5004") - fsm.state = STATE_PRIMARY - } else if len(os.Args) == 2 && os.Args[1] == "-b" { - fmt.Println("I: Backup passive, waiting for primary (active)") - frontend.Bind("tcp://*:5002") - statepub.Bind("tcp://*:5004") - statesub.Connect("tcp://localhost:5003") - fsm.state = STATE_BACKUP - } else { - fmt.Println("Usage: bstarsrv { -p | -b }") - return - } - // We now process events on our two input sockets, and process these - // events one at a time via our finite-state machine. Our "work" for - // a client request is simply to echo it back: - - // Set timer for next outgoing state message - send_state_at := time.Now().Add(HEARTBEAT) - - poller := zmq.NewPoller() - poller.Add(frontend, zmq.POLLIN) - poller.Add(statesub, zmq.POLLIN) - -LOOP: - for { - time_left := send_state_at.Sub(time.Now()) - if time_left < 0 { - time_left = 0 - } - polled, err := poller.Poll(time_left) - if err != nil { - break // Context has been shut down - } - for _, socket := range polled { - switch socket.Socket { - case frontend: - // Have a client request - msg, _ := frontend.RecvMessage(0) - fsm.event = CLIENT_REQUEST - if !StateMachine(fsm) { - // Answer client by echoing request back - frontend.SendMessage(msg) - } - case statesub: - // Have state from our peer, execute as event - message, _ := statesub.RecvMessage(0) - i, _ := strconv.Atoi(message[0]) - fsm.event = event_t(i) - if StateMachine(fsm) { - break LOOP // Error, so exit - } - fsm.peer_expiry = time.Now().Add(2 * HEARTBEAT) - } - } - // If we timed-out, send state to peer - if time.Now().After(send_state_at) { - statepub.SendMessage(int(fsm.state)) - send_state_at = time.Now().Add(HEARTBEAT) - } - } - fmt.Println("W: interrupted") -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarsrv2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarsrv2.go deleted file mode 100644 index 420b4a9..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstarsrv2.go +++ /dev/null @@ -1,43 +0,0 @@ -// -// Binary Star server, using bstar reactor. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstar" - - "fmt" - "os" -) - -// Echo service -func echo(socket *zmq.Socket) (err error) { - msg, err := socket.RecvMessage(0) - if err != nil { - return - } - _, err = socket.SendMessage(msg) - return -} - -func main() { - // Arguments can be either of: - // -p primary server, at tcp://localhost:5001 - // -b backup server, at tcp://localhost:5002 - var bst *bstar.Bstar - if len(os.Args) == 2 && os.Args[1] == "-p" { - fmt.Println("I: Primary active, waiting for backup (passive)") - bst, _ = bstar.New(bstar.PRIMARY, "tcp://*:5003", "tcp://localhost:5004") - bst.Voter("tcp://*:5001", zmq.ROUTER, echo) - } else if len(os.Args) == 2 && os.Args[1] == "-b" { - fmt.Println("I: Backup passive, waiting for primary (active)") - bst, _ = bstar.New(bstar.BACKUP, "tcp://*:5004", "tcp://localhost:5003") - bst.Voter("tcp://*:5002", zmq.ROUTER, echo) - } else { - fmt.Println("Usage: bstarsrvs { -p | -b }") - return - } - bst.Start() -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clone/clone.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clone/clone.go deleted file mode 100644 index 84b8a5f..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clone/clone.go +++ /dev/null @@ -1,304 +0,0 @@ -// Clone client API stack (multithreaded). -package clone - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg" - - "fmt" - "strconv" - "time" -) - -// ===================================================================== -// Synchronous part, works in our application thread - -// --------------------------------------------------------------------- -// Structure of our class - -var ( - pipe_nmb uint64 -) - -type Clone struct { - pipe *zmq.Socket // Pipe through to clone agent -} - -// This is the thread that handles our real clone class - -// Constructor for the clone class. Note that we create -// the pipe that connects our frontend to the -// backend agent: - -func New() (clone *Clone) { - clone = &Clone{} - clone.pipe, _ = zmq.NewSocket(zmq.PAIR) - pipename := fmt.Sprint("inproc://pipe", pipe_nmb) - pipe_nmb++ - clone.pipe.Bind(pipename) - go clone_agent(pipename) - return -} - -// Specify subtree for snapshot and updates, which we must do before -// connecting to a server since the subtree specification is sent as -// first command to the server. Sends a [SUBTREE][subtree] command to -// the agent: - -func (clone *Clone) Subtree(subtree string) { - clone.pipe.SendMessage("SUBTREE", subtree) -} - -// Connect to a new server endpoint. We can connect to at most two -// servers. Sends [CONNECT][endpoint][service] to the agent: - -func (clone *Clone) Connect(address, service string) { - clone.pipe.SendMessage("CONNECT", address, service) -} - -// Set a new value in the shared hashmap. Sends a [SET][key][value][ttl] -// command through to the agent which does the actual work: - -func (clone *Clone) Set(key, value string, ttl int) { - clone.pipe.SendMessage("SET", key, value, ttl) -} - -// Look-up value in distributed hash table. Sends [GET][key] to the agent and -// waits for a value response. If there is no value available, will eventually -// return error: - -func (clone *Clone) Get(key string) (value string, err error) { - - clone.pipe.SendMessage("GET", key) - - reply, e := clone.pipe.RecvMessage(0) - if e != nil { - err = e - return - } - value = reply[0] - return -} - -// The back-end agent manages a set of servers, which we implement using -// our simple class model: - -type server_t struct { - address string // Server address - port int // Server port - snapshot *zmq.Socket // Snapshot socket - subscriber *zmq.Socket // Incoming updates - expiry time.Time // When server expires - requests int64 // How many snapshot requests made? -} - -func server_new(address string, port int, subtree string) (server *server_t) { - server = &server_t{} - - fmt.Printf("I: adding server %s:%d...\n", address, port) - server.address = address - server.port = port - - server.snapshot, _ = zmq.NewSocket(zmq.DEALER) - server.snapshot.Connect(fmt.Sprintf("%s:%d", address, port)) - server.subscriber, _ = zmq.NewSocket(zmq.SUB) - server.subscriber.Connect(fmt.Sprintf("%s:%d", address, port+1)) - server.subscriber.SetSubscribe(subtree) - return -} - -// Here is the implementation of the back-end agent itself: - -const ( - // Number of servers we will talk to - server_MAX = 2 - - // Server considered dead if silent for this long - server_TTL = 5000 * time.Millisecond -) - -const ( - // States we can be in - state_INITIAL = iota // Before asking server for state - state_SYNCING // Getting state from server - state_ACTIVE // Getting new updates from server -) - -type agent_t struct { - pipe *zmq.Socket // Pipe back to application - kvmap map[string]*kvmsg.Kvmsg // Actual key/value table - subtree string // Subtree specification, if any - server [server_MAX]*server_t - nbr_servers int // 0 to SERVER_MAX - state int // Current state - cur_server int // If active, server 0 or 1 - sequence int64 // Last kvmsg processed - publisher *zmq.Socket // Outgoing updates -} - -func agent_new(pipe *zmq.Socket) (agent *agent_t) { - agent = &agent_t{} - agent.pipe = pipe - agent.kvmap = make(map[string]*kvmsg.Kvmsg) - agent.subtree = "" - agent.state = state_INITIAL - agent.publisher, _ = zmq.NewSocket(zmq.PUB) - return -} - -// Here we handle the different control messages from the front-end; -// SUBTREE, CONNECT, SET, and GET: - -func (agent *agent_t) control_message() (err error) { - msg, e := agent.pipe.RecvMessage(0) - if e != nil { - return e - } - command := msg[0] - msg = msg[1:] - - switch command { - case "SUBTREE": - agent.subtree = msg[0] - case "CONNECT": - address := msg[0] - service := msg[1] - if agent.nbr_servers < server_MAX { - serv, _ := strconv.Atoi(service) - agent.server[agent.nbr_servers] = server_new(address, serv, agent.subtree) - agent.nbr_servers++ - // We broadcast updates to all known servers - agent.publisher.Connect(fmt.Sprintf("%s:%d", address, serv+2)) - } else { - fmt.Printf("E: too many servers (max. %d)\n", server_MAX) - } - case "SET": - // When we set a property, we push the new key-value pair onto - // all our connected servers: - key := msg[0] - value := msg[1] - ttl := msg[2] - - // Send key-value pair on to server - kvmsg := kvmsg.NewKvmsg(0) - kvmsg.SetKey(key) - kvmsg.SetUuid() - kvmsg.SetBody(value) - kvmsg.SetProp("ttl", ttl) - kvmsg.Store(agent.kvmap) - kvmsg.Send(agent.publisher) - case "GET": - key := msg[0] - value := "" - if kvmsg, ok := agent.kvmap[key]; ok { - value, _ = kvmsg.GetBody() - } - agent.pipe.SendMessage(value) - } - return -} - -// The asynchronous agent manages a server pool and handles the -// request/reply dialog when the application asks for it: - -func clone_agent(pipename string) { - - pipe, _ := zmq.NewSocket(zmq.PAIR) - pipe.Connect(pipename) - - agent := agent_new(pipe) - -LOOP: - for { - poller := zmq.NewPoller() - poller.Add(pipe, zmq.POLLIN) - server := agent.server[agent.cur_server] - switch agent.state { - case state_INITIAL: - // In this state we ask the server for a snapshot, - // if we have a server to talk to... - if agent.nbr_servers > 0 { - fmt.Printf("I: waiting for server at %s:%d...\n", server.address, server.port) - if server.requests < 2 { - server.snapshot.SendMessage("ICANHAZ?", agent.subtree) - server.requests++ - } - server.expiry = time.Now().Add(server_TTL) - agent.state = state_SYNCING - poller.Add(server.snapshot, zmq.POLLIN) - } - - case state_SYNCING: - // In this state we read from snapshot and we expect - // the server to respond, else we fail over. - poller.Add(server.snapshot, zmq.POLLIN) - - case state_ACTIVE: - // In this state we read from subscriber and we expect - // the server to give hugz, else we fail over. - poller.Add(server.subscriber, zmq.POLLIN) - break - } - poll_timer := time.Duration(-1) - if server != nil { - poll_timer = server.expiry.Sub(time.Now()) - if poll_timer < 0 { - poll_timer = 0 - } - } - // We're ready to process incoming messages; if nothing at all - // comes from our server within the timeout, that means the - // server is dead: - - polled, err := poller.Poll(poll_timer) - if err != nil { - break - } - - if len(polled) > 0 { - for _, item := range polled { - switch socket := item.Socket; socket { - case pipe: - - err = agent.control_message() - if err != nil { - break LOOP - } - - default: - kvmsg, e := kvmsg.RecvKvmsg(socket) - if e != nil { - err = e - break LOOP - } - - // Anything from server resets its expiry time - server.expiry = time.Now().Add(server_TTL) - if agent.state == state_SYNCING { - // Store in snapshot until we're finished - server.requests = 0 - if key, _ := kvmsg.GetKey(); key == "KTHXBAI" { - agent.sequence, _ = kvmsg.GetSequence() - agent.state = state_ACTIVE - fmt.Printf("I: received from %s:%d snapshot=%d\n", server.address, server.port, agent.sequence) - } else { - kvmsg.Store(agent.kvmap) - } - } else if agent.state == state_ACTIVE { - // Discard out-of-sequence updates, incl. hugz - if seq, _ := kvmsg.GetSequence(); seq > agent.sequence { - agent.sequence = seq - kvmsg.Store(agent.kvmap) - fmt.Printf("I: received from %s:%d update=%d\n", server.address, server.port, agent.sequence) - } - } - } - } - } else { - // Server has died, failover to next - fmt.Printf("I: server at %s:%d didn't give hugz\n", server.address, server.port) - agent.cur_server = (agent.cur_server + 1) % agent.nbr_servers - agent.state = state_INITIAL - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli1.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli1.go deleted file mode 100644 index dd26c42..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli1.go +++ /dev/null @@ -1,31 +0,0 @@ -// -// Clone client Model One -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple" - - "fmt" -) - -func main() { - // Prepare our context and updates socket - updates, _ := zmq.NewSocket(zmq.SUB) - updates.SetSubscribe("") - updates.Connect("tcp://localhost:5556") - - kvmap := make(map[string]*kvsimple.Kvmsg) - - sequence := int64(0) - for ; true; sequence++ { - kvmsg, err := kvsimple.RecvKvmsg(updates) - if err != nil { - break // Interrupted - } - kvmsg.Store(kvmap) - } - fmt.Printf("Interrupted\n%d messages in\n", sequence) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli2.go deleted file mode 100644 index baa37ee..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli2.go +++ /dev/null @@ -1,70 +0,0 @@ -// -// Clone client Model Two -// -// In the original C example, the client misses updates between snapshot -// and further updates. Sometimes, it even misses the END message of -// the snapshot, so it waits for it forever. -// This Go implementation has some modifications to improve this, but it -// is still not fully reliable. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple" - - "fmt" - "time" -) - -func main() { - snapshot, _ := zmq.NewSocket(zmq.DEALER) - snapshot.Connect("tcp://localhost:5556") - - subscriber, _ := zmq.NewSocket(zmq.SUB) - subscriber.SetRcvhwm(100000) // or messages between snapshot and next are lost - subscriber.SetSubscribe("") - subscriber.Connect("tcp://localhost:5557") - - time.Sleep(time.Second) // or messages between snapshot and next are lost - - kvmap := make(map[string]*kvsimple.Kvmsg) - - // Get state snapshot - sequence := int64(0) - snapshot.SendMessage("ICANHAZ?") - for { - kvmsg, err := kvsimple.RecvKvmsg(snapshot) - if err != nil { - fmt.Println(err) - break // Interrupted - } - if key, _ := kvmsg.GetKey(); key == "KTHXBAI" { - sequence, _ = kvmsg.GetSequence() - fmt.Printf("Received snapshot=%d\n", sequence) - break // Done - } - kvmsg.Store(kvmap) - } - snapshot.Close() - - first := true - // Now apply pending updates, discard out-of-sequence messages - for { - kvmsg, err := kvsimple.RecvKvmsg(subscriber) - if err != nil { - fmt.Println(err) - break // Interrupted - } - if seq, _ := kvmsg.GetSequence(); seq > sequence { - sequence, _ = kvmsg.GetSequence() - kvmsg.Store(kvmap) - if first { - // Show what the first regular update is after the snapshot, - // to see if we missed updates. - first = false - fmt.Println("Next:", sequence) - } - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli3.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli3.go deleted file mode 100644 index cab5025..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli3.go +++ /dev/null @@ -1,83 +0,0 @@ -// -// Clone client Model Three -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple" - - "fmt" - "math/rand" - "time" -) - -func main() { - snapshot, _ := zmq.NewSocket(zmq.DEALER) - snapshot.Connect("tcp://localhost:5556") - subscriber, _ := zmq.NewSocket(zmq.SUB) - subscriber.SetSubscribe("") - subscriber.Connect("tcp://localhost:5557") - publisher, _ := zmq.NewSocket(zmq.PUSH) - publisher.Connect("tcp://localhost:5558") - - kvmap := make(map[string]*kvsimple.Kvmsg) - rand.Seed(time.Now().UnixNano()) - - // We first request a state snapshot: - sequence := int64(0) - snapshot.SendMessage("ICANHAZ?") - for { - kvmsg, err := kvsimple.RecvKvmsg(snapshot) - if err != nil { - break // Interrupted - } - if key, _ := kvmsg.GetKey(); key == "KTHXBAI" { - sequence, _ := kvmsg.GetSequence() - fmt.Println("I: received snapshot =", sequence) - break // Done - } - kvmsg.Store(kvmap) - } - snapshot.Close() - - // Now we wait for updates from the server, and every so often, we - // send a random key-value update to the server: - - poller := zmq.NewPoller() - poller.Add(subscriber, zmq.POLLIN) - alarm := time.Now().Add(1000 * time.Millisecond) - for { - tickless := alarm.Sub(time.Now()) - if tickless < 0 { - tickless = 0 - } - polled, err := poller.Poll(tickless) - if err != nil { - break // Context has been shut down - } - if len(polled) == 1 { - kvmsg, err := kvsimple.RecvKvmsg(subscriber) - if err != nil { - break // Interrupted - } - - // Discard out-of-sequence kvmsgs, incl. heartbeats - if seq, _ := kvmsg.GetSequence(); seq > sequence { - sequence = seq - kvmsg.Store(kvmap) - fmt.Println("I: received update =", sequence) - } - } - // If we timed-out, generate a random kvmsg - if time.Now().After(alarm) { - kvmsg := kvsimple.NewKvmsg(0) - kvmsg.SetKey(fmt.Sprint(rand.Intn(10000))) - kvmsg.SetBody(fmt.Sprint(rand.Intn(1000000))) - kvmsg.Send(publisher) - alarm = time.Now().Add(1000 * time.Millisecond) - } - } - fmt.Printf("Interrupted\n%d messages in\n", sequence) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli4.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli4.go deleted file mode 100644 index db4d692..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli4.go +++ /dev/null @@ -1,84 +0,0 @@ -// -// Clone client Model Four -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple" - - "fmt" - "math/rand" - "time" -) - -const ( - SUBTREE = "/client/" -) - -func main() { - snapshot, _ := zmq.NewSocket(zmq.DEALER) - snapshot.Connect("tcp://localhost:5556") - subscriber, _ := zmq.NewSocket(zmq.SUB) - subscriber.SetSubscribe(SUBTREE) - subscriber.Connect("tcp://localhost:5557") - publisher, _ := zmq.NewSocket(zmq.PUSH) - publisher.Connect("tcp://localhost:5558") - - kvmap := make(map[string]*kvsimple.Kvmsg) - rand.Seed(time.Now().UnixNano()) - - // We first request a state snapshot: - sequence := int64(0) - snapshot.SendMessage("ICANHAZ?", SUBTREE) - for { - kvmsg, err := kvsimple.RecvKvmsg(snapshot) - if err != nil { - break // Interrupted - } - if key, _ := kvmsg.GetKey(); key == "KTHXBAI" { - sequence, _ := kvmsg.GetSequence() - fmt.Println("I: received snapshot =", sequence) - break // Done - } - kvmsg.Store(kvmap) - } - snapshot.Close() - - poller := zmq.NewPoller() - poller.Add(subscriber, zmq.POLLIN) - alarm := time.Now().Add(1000 * time.Millisecond) - for { - tickless := alarm.Sub(time.Now()) - if tickless < 0 { - tickless = 0 - } - polled, err := poller.Poll(tickless) - if err != nil { - break // Context has been shut down - } - if len(polled) == 1 { - kvmsg, err := kvsimple.RecvKvmsg(subscriber) - if err != nil { - break // Interrupted - } - - // Discard out-of-sequence kvmsgs, incl. heartbeats - if seq, _ := kvmsg.GetSequence(); seq > sequence { - sequence = seq - kvmsg.Store(kvmap) - fmt.Println("I: received update =", sequence) - } - } - // If we timed-out, generate a random kvmsg - if time.Now().After(alarm) { - kvmsg := kvsimple.NewKvmsg(0) - kvmsg.SetKey(fmt.Sprintf("%s%d", SUBTREE, rand.Intn(10000))) - kvmsg.SetBody(fmt.Sprint(rand.Intn(1000000))) - kvmsg.Send(publisher) - alarm = time.Now().Add(1000 * time.Millisecond) - } - } - fmt.Printf("Interrupted\n%d messages in\n", sequence) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli5.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli5.go deleted file mode 100644 index 6228a8a..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli5.go +++ /dev/null @@ -1,85 +0,0 @@ -// -// Clone client Model Five -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg" - - "fmt" - "math/rand" - "time" -) - -const ( - SUBTREE = "/client/" -) - -func main() { - snapshot, _ := zmq.NewSocket(zmq.DEALER) - snapshot.Connect("tcp://localhost:5556") - subscriber, _ := zmq.NewSocket(zmq.SUB) - subscriber.SetSubscribe(SUBTREE) - subscriber.Connect("tcp://localhost:5557") - publisher, _ := zmq.NewSocket(zmq.PUSH) - publisher.Connect("tcp://localhost:5558") - - kvmap := make(map[string]*kvmsg.Kvmsg) - rand.Seed(time.Now().UnixNano()) - - // We first request a state snapshot: - sequence := int64(0) - snapshot.SendMessage("ICANHAZ?", SUBTREE) - for { - kvmsg, err := kvmsg.RecvKvmsg(snapshot) - if err != nil { - break // Interrupted - } - if key, _ := kvmsg.GetKey(); key == "KTHXBAI" { - sequence, _ := kvmsg.GetSequence() - fmt.Println("I: received snapshot =", sequence) - break // Done - } - kvmsg.Store(kvmap) - } - snapshot.Close() - - poller := zmq.NewPoller() - poller.Add(subscriber, zmq.POLLIN) - alarm := time.Now().Add(1000 * time.Millisecond) - for { - tickless := alarm.Sub(time.Now()) - if tickless < 0 { - tickless = 0 - } - polled, err := poller.Poll(tickless) - if err != nil { - break // Context has been shut down - } - if len(polled) == 1 { - kvmsg, err := kvmsg.RecvKvmsg(subscriber) - if err != nil { - break // Interrupted - } - - // Discard out-of-sequence kvmsgs, incl. heartbeats - if seq, _ := kvmsg.GetSequence(); seq > sequence { - sequence = seq - kvmsg.Store(kvmap) - fmt.Println("I: received update =", sequence) - } - } - // If we timed-out, generate a random kvmsg - if time.Now().After(alarm) { - kvmsg := kvmsg.NewKvmsg(0) - kvmsg.SetKey(fmt.Sprintf("%s%d", SUBTREE, rand.Intn(10000))) - kvmsg.SetBody(fmt.Sprint(rand.Intn(1000000))) - kvmsg.SetProp("ttl", fmt.Sprintf("%d", rand.Intn((30)))) // seconds - kvmsg.Send(publisher) - alarm = time.Now().Add(1000 * time.Millisecond) - } - } - fmt.Printf("Interrupted\n%d messages in\n", sequence) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli6.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli6.go deleted file mode 100644 index ebaa7e0..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonecli6.go +++ /dev/null @@ -1,41 +0,0 @@ -// -// Clone client Model Six -// - -package main - -import ( - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clone" - - "fmt" - "log" - "math/rand" - "time" -) - -const ( - SUBTREE = "/client/" -) - -func main() { - // Create distributed hash instance - clone := clone.New() - - // Specify configuration - clone.Subtree(SUBTREE) - clone.Connect("tcp://localhost", "5556") - clone.Connect("tcp://localhost", "5566") - - // Set random tuples into the distributed hash - for { - // Set random value, check it was stored - key := fmt.Sprintf("%s%d", SUBTREE, rand.Intn(10000)) - value := fmt.Sprint(rand.Intn(1000000)) - clone.Set(key, value, rand.Intn(30)) - v, _ := clone.Get(key) - if v != value { - log.Fatalf("Set: %v - Get: %v - Equal: %v\n", value, v, value == v) - } - time.Sleep(time.Second) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv1.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv1.go deleted file mode 100644 index b1563cc..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv1.go +++ /dev/null @@ -1,38 +0,0 @@ -// -// Clone server Model One -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple" - - "fmt" - "math/rand" - "time" -) - -func main() { - // Prepare our context and publisher socket - publisher, _ := zmq.NewSocket(zmq.PUB) - publisher.Bind("tcp://*:5556") - time.Sleep(200 * time.Millisecond) - - kvmap := make(map[string]*kvsimple.Kvmsg) - rand.Seed(time.Now().UnixNano()) - - sequence := int64(1) - for ; true; sequence++ { - // Distribute as key-value message - kvmsg := kvsimple.NewKvmsg(sequence) - kvmsg.SetKey(fmt.Sprint(rand.Intn(10000))) - kvmsg.SetBody(fmt.Sprint(rand.Intn(1000000))) - err := kvmsg.Send(publisher) - kvmsg.Store(kvmap) - if err != nil { - break - } - } - fmt.Printf("Interrupted\n%d messages out\n", sequence) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv2.go deleted file mode 100644 index 81447dc..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv2.go +++ /dev/null @@ -1,119 +0,0 @@ -// -// Clone server Model Two -// -// In the original C example, the client misses updates between snapshot -// and further updates. Sometimes, it even misses the END message of -// the snapshot, so it waits for it forever. -// This Go implementation has some modifications to improve this, but it -// is still not fully reliable. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple" - - "fmt" - "math/rand" - "time" -) - -func main() { - // Prepare our context and sockets - publisher, _ := zmq.NewSocket(zmq.PUB) - publisher.Bind("tcp://*:5557") - - sequence := int64(0) - rand.Seed(time.Now().UnixNano()) - - // Start state manager and wait for synchronization signal - updates, _ := zmq.NewSocket(zmq.PAIR) - updates.Bind("inproc://pipe") - go state_manager() - updates.RecvMessage(0) // "READY" - - for { - // Distribute as key-value message - sequence++ - kvmsg := kvsimple.NewKvmsg(sequence) - kvmsg.SetKey(fmt.Sprint(rand.Intn(10000))) - kvmsg.SetBody(fmt.Sprint(rand.Intn(1000000))) - if kvmsg.Send(publisher) != nil { - break - } - if kvmsg.Send(updates) != nil { - break - } - } - fmt.Printf("Interrupted\n%d messages out\n", sequence) -} - -// The state manager task maintains the state and handles requests from -// clients for snapshots: - -func state_manager() { - kvmap := make(map[string]*kvsimple.Kvmsg) - - pipe, _ := zmq.NewSocket(zmq.PAIR) - pipe.Connect("inproc://pipe") - pipe.SendMessage("READY") - snapshot, _ := zmq.NewSocket(zmq.ROUTER) - snapshot.Bind("tcp://*:5556") - - poller := zmq.NewPoller() - poller.Add(pipe, zmq.POLLIN) - poller.Add(snapshot, zmq.POLLIN) - sequence := int64(0) // Current snapshot version number -LOOP: - for { - polled, err := poller.Poll(-1) - if err != nil { - break // Context has been shut down - } - for _, item := range polled { - switch socket := item.Socket; socket { - case pipe: - // Apply state update from main thread - kvmsg, err := kvsimple.RecvKvmsg(pipe) - if err != nil { - break LOOP // Interrupted - } - sequence, _ = kvmsg.GetSequence() - kvmsg.Store(kvmap) - case snapshot: - // Execute state snapshot request - msg, err := snapshot.RecvMessage(0) - if err != nil { - break LOOP // Interrupted - } - identity := msg[0] - // Request is in second frame of message - request := msg[1] - if request != "ICANHAZ?" { - fmt.Println("E: bad request, aborting") - break LOOP - } - // Send state snapshot to client - - // For each entry in kvmap, send kvmsg to client - for _, kvmsg := range kvmap { - snapshot.Send(identity, zmq.SNDMORE) - kvmsg.Send(snapshot) - } - - // Give client some time to deal with it. - // This reduces the risk that the client won't see - // the END message, but it doesn't eliminate the risk. - time.Sleep(100 * time.Millisecond) - - // Now send END message with sequence number - fmt.Printf("Sending state shapshot=%d\n", sequence) - snapshot.Send(identity, zmq.SNDMORE) - kvmsg := kvsimple.NewKvmsg(sequence) - kvmsg.SetKey("KTHXBAI") - kvmsg.SetBody("") - kvmsg.Send(snapshot) - } - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv3.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv3.go deleted file mode 100644 index 3752780..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv3.go +++ /dev/null @@ -1,84 +0,0 @@ -// -// Clone server Model Three -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple" - - "fmt" - "time" -) - -func main() { - snapshot, _ := zmq.NewSocket(zmq.ROUTER) - snapshot.Bind("tcp://*:5556") - publisher, _ := zmq.NewSocket(zmq.PUB) - publisher.Bind("tcp://*:5557") - collector, _ := zmq.NewSocket(zmq.PULL) - collector.Bind("tcp://*:5558") - - // The body of the main task collects updates from clients and - // publishes them back out to clients: - - sequence := int64(0) - kvmap := make(map[string]*kvsimple.Kvmsg) - - poller := zmq.NewPoller() - poller.Add(collector, zmq.POLLIN) - poller.Add(snapshot, zmq.POLLIN) -LOOP: - for { - polled, err := poller.Poll(1000 * time.Millisecond) - if err != nil { - break - } - for _, item := range polled { - switch socket := item.Socket; socket { - case collector: - // Apply state update sent from client - kvmsg, err := kvsimple.RecvKvmsg(collector) - if err != nil { - break LOOP // Interrupted - } - sequence++ - kvmsg.SetSequence(sequence) - kvmsg.Send(publisher) - kvmsg.Store(kvmap) - fmt.Println("I: publishing update", sequence) - case snapshot: - // Execute state snapshot request - msg, err := snapshot.RecvMessage(0) - if err != nil { - break LOOP - } - identity := msg[0] - - // Request is in second frame of message - request := msg[1] - if request != "ICANHAZ?" { - fmt.Println("E: bad request, aborting") - break LOOP - } - // Send state snapshot to client - - // For each entry in kvmap, send kvmsg to client - for _, kvmsg := range kvmap { - snapshot.Send(identity, zmq.SNDMORE) - kvmsg.Send(snapshot) - } - - // Now send END message with sequence number - fmt.Println("I: sending shapshot =", sequence) - snapshot.Send(identity, zmq.SNDMORE) - kvmsg := kvsimple.NewKvmsg(sequence) - kvmsg.SetKey("KTHXBAI") - kvmsg.SetBody("") - kvmsg.Send(snapshot) - } - } - } - fmt.Printf("Interrupted\n%d messages handled\n", sequence) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv4.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv4.go deleted file mode 100644 index 49f4a6b..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv4.go +++ /dev/null @@ -1,91 +0,0 @@ -// -// Clone server Model Four -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple" - - "fmt" - "strings" - "time" -) - -// The main task is identical to clonesrv3 except for where it -// handles subtrees. - -func main() { - snapshot, _ := zmq.NewSocket(zmq.ROUTER) - snapshot.Bind("tcp://*:5556") - publisher, _ := zmq.NewSocket(zmq.PUB) - publisher.Bind("tcp://*:5557") - collector, _ := zmq.NewSocket(zmq.PULL) - collector.Bind("tcp://*:5558") - - // The body of the main task collects updates from clients and - // publishes them back out to clients: - - sequence := int64(0) - kvmap := make(map[string]*kvsimple.Kvmsg) - - poller := zmq.NewPoller() - poller.Add(collector, zmq.POLLIN) - poller.Add(snapshot, zmq.POLLIN) -LOOP: - for { - polled, err := poller.Poll(1000 * time.Millisecond) - if err != nil { - break - } - for _, item := range polled { - switch socket := item.Socket; socket { - case collector: - // Apply state update sent from client - kvmsg, err := kvsimple.RecvKvmsg(collector) - if err != nil { - break LOOP // Interrupted - } - sequence++ - kvmsg.SetSequence(sequence) - kvmsg.Send(publisher) - kvmsg.Store(kvmap) - fmt.Println("I: publishing update", sequence) - case snapshot: - // Execute state snapshot request - msg, err := snapshot.RecvMessage(0) - if err != nil { - break LOOP - } - identity := msg[0] - - // Request is in second frame of message - request := msg[1] - if request != "ICANHAZ?" { - fmt.Println("E: bad request, aborting") - break LOOP - } - subtree := msg[2] - // Send state snapshot to client - - // For each entry in kvmap, send kvmsg to client - for _, kvmsg := range kvmap { - if key, _ := kvmsg.GetKey(); strings.HasPrefix(key, subtree) { - snapshot.Send(identity, zmq.SNDMORE) - kvmsg.Send(snapshot) - } - } - - // Now send END message with sequence number - fmt.Println("I: sending shapshot =", sequence) - snapshot.Send(identity, zmq.SNDMORE) - kvmsg := kvsimple.NewKvmsg(sequence) - kvmsg.SetKey("KTHXBAI") - kvmsg.SetBody(subtree) - kvmsg.Send(snapshot) - } - } - } - fmt.Printf("Interrupted\n%d messages handled\n", sequence) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv5.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv5.go deleted file mode 100644 index 7b203c9..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv5.go +++ /dev/null @@ -1,152 +0,0 @@ -// -// Clone server Model Five -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg" - - "errors" - "fmt" - "log" - "strconv" - "strings" - "time" -) - -// Our server is defined by these properties -type clonesrv_t struct { - kvmap map[string]*kvmsg.Kvmsg // Key-value store - port int // Main port we're working on - sequence int64 // How many updates we're at - snapshot *zmq.Socket // Handle snapshot requests - publisher *zmq.Socket // Publish updates to clients - collector *zmq.Socket // Collect updates from clients -} - -func main() { - - srv := &clonesrv_t{ - port: 5556, - kvmap: make(map[string]*kvmsg.Kvmsg), - } - - // Set up our clone server sockets - srv.snapshot, _ = zmq.NewSocket(zmq.ROUTER) - srv.snapshot.Bind(fmt.Sprint("tcp://*:", srv.port)) - srv.publisher, _ = zmq.NewSocket(zmq.PUB) - srv.publisher.Bind(fmt.Sprint("tcp://*:", srv.port+1)) - srv.collector, _ = zmq.NewSocket(zmq.PULL) - srv.collector.Bind(fmt.Sprint("tcp://*:", srv.port+2)) - - // Register our handlers with reactor - reactor := zmq.NewReactor() - reactor.AddSocket(srv.snapshot, zmq.POLLIN, - func(e zmq.State) error { return snapshots(srv) }) - reactor.AddSocket(srv.collector, zmq.POLLIN, - func(e zmq.State) error { return collector(srv) }) - reactor.AddChannelTime(time.Tick(1000*time.Millisecond), 1, - func(v interface{}) error { return flush_ttl(srv) }) - - log.Println(reactor.Run(100 * time.Millisecond)) // precision: .1 seconds -} - -// This is the reactor handler for the snapshot socket; it accepts -// just the ICANHAZ? request and replies with a state snapshot ending -// with a KTHXBAI message: - -func snapshots(srv *clonesrv_t) (err error) { - - msg, err := srv.snapshot.RecvMessage(0) - if err != nil { - return - } - identity := msg[0] - - // Request is in second frame of message - request := msg[1] - if request != "ICANHAZ?" { - err = errors.New("E: bad request, aborting") - return - } - subtree := msg[2] - - // Send state socket to client - for _, kvmsg := range srv.kvmap { - if key, _ := kvmsg.GetKey(); strings.HasPrefix(key, subtree) { - srv.snapshot.Send(identity, zmq.SNDMORE) - kvmsg.Send(srv.snapshot) - } - } - - // Now send END message with sequence number - log.Println("I: sending shapshot =", srv.sequence) - srv.snapshot.Send(identity, zmq.SNDMORE) - kvmsg := kvmsg.NewKvmsg(srv.sequence) - kvmsg.SetKey("KTHXBAI") - kvmsg.SetBody(subtree) - kvmsg.Send(srv.snapshot) - - return -} - -// We store each update with a new sequence number, and if necessary, a -// time-to-live. We publish updates immediately on our publisher socket: - -func collector(srv *clonesrv_t) (err error) { - kvmsg, err := kvmsg.RecvKvmsg(srv.collector) - if err != nil { - return - } - - srv.sequence++ - kvmsg.SetSequence(srv.sequence) - kvmsg.Send(srv.publisher) - if ttls, e := kvmsg.GetProp("ttl"); e == nil { - // change duration into specific time, using the same property: ugly! - ttl, e := strconv.ParseInt(ttls, 10, 64) - if e != nil { - err = e - return - } - kvmsg.SetProp("ttl", fmt.Sprint(time.Now().Add(time.Duration(ttl)*time.Second).Unix())) - } - kvmsg.Store(srv.kvmap) - log.Println("I: publishing update =", srv.sequence) - - return -} - -// At regular intervals we flush ephemeral values that have expired. This -// could be slow on very large data sets: - -func flush_ttl(srv *clonesrv_t) (err error) { - - for _, kvmsg := range srv.kvmap { - - // If key-value pair has expired, delete it and publish the - // fact to listening clients. - - if ttls, e := kvmsg.GetProp("ttl"); e == nil { - ttl, e := strconv.ParseInt(ttls, 10, 64) - if e != nil { - err = e - continue - } - if time.Now().After(time.Unix(ttl, 0)) { - srv.sequence++ - kvmsg.SetSequence(srv.sequence) - kvmsg.SetBody("") - e = kvmsg.Send(srv.publisher) - if e != nil { - err = e - } - kvmsg.Store(srv.kvmap) - log.Println("I: publishing delete =", srv.sequence) - } - } - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv6.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv6.go deleted file mode 100644 index aef1993..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/clonesrv6.go +++ /dev/null @@ -1,336 +0,0 @@ -// -// Clone server Model Six -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/bstar" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg" - - "errors" - "fmt" - "log" - "os" - "strconv" - "strings" - "time" -) - -// Our server is defined by these properties -type clonesrv_t struct { - kvmap map[string]*kvmsg.Kvmsg // Key-value store - kvmap_init bool - bstar *bstar.Bstar // Bstar reactor core - sequence int64 // How many updates we're at - port int // Main port we're working on - peer int // Main port of our peer - publisher *zmq.Socket // Publish updates and hugz - collector *zmq.Socket // Collect updates from clients - subscriber *zmq.Socket // Get updates from peer - pending []*kvmsg.Kvmsg // Pending updates from clients - primary bool // TRUE if we're primary - active bool // TRUE if we're active - passive bool // TRUE if we're passive -} - -// The main task parses the command line to decide whether to start -// as primary or backup server. We're using the Binary Star pattern -// for reliability. This interconnects the two servers so they can -// agree on which is primary, and which is backup. To allow the two -// servers to run on the same box, we use different ports for primary -// and backup. Ports 5003/5004 are used to interconnect the servers. -// Ports 5556/5566 are used to receive voting events (snapshot requests -// in the clone pattern). Ports 5557/5567 are used by the publisher, -// and ports 5558/5568 by the collector: - -func main() { - var err error - - srv := &clonesrv_t{} - - if len(os.Args) == 2 && os.Args[1] == "-p" { - log.Println("I: primary active, waiting for backup (passive)") - srv.bstar, err = bstar.New(bstar.PRIMARY, "tcp://*:5003", "tcp://localhost:5004") - if err != nil { - log.Println(err) - return - } - srv.bstar.Voter("tcp://*:5556", zmq.ROUTER, func(soc *zmq.Socket) error { return snapshots(soc, srv) }) - srv.port = 5556 - srv.peer = 5566 - srv.primary = true - } else if len(os.Args) == 2 && os.Args[1] == "-b" { - log.Println("I: backup passive, waiting for primary (active)") - srv.bstar, err = bstar.New(bstar.BACKUP, "tcp://*:5004", "tcp://localhost:5003") - srv.bstar.Voter("tcp://*:5566", zmq.ROUTER, func(soc *zmq.Socket) error { return snapshots(soc, srv) }) - srv.port = 5566 - srv.peer = 5556 - srv.primary = false - } else { - fmt.Println("Usage: clonesrv4 { -p | -b }") - return - } - // Primary server will become first active - if srv.primary { - srv.kvmap = make(map[string]*kvmsg.Kvmsg, 0) - srv.kvmap_init = true - } - - srv.pending = make([]*kvmsg.Kvmsg, 0) - srv.bstar.SetVerbose(true) - - // Set up our clone server sockets - srv.publisher, _ = zmq.NewSocket(zmq.PUB) - srv.collector, _ = zmq.NewSocket(zmq.SUB) - srv.collector.SetSubscribe("") - srv.publisher.Bind(fmt.Sprint("tcp://*:", srv.port+1)) - srv.collector.Bind(fmt.Sprint("tcp://*:", srv.port+2)) - - // Set up our own clone client interface to peer - srv.subscriber, _ = zmq.NewSocket(zmq.SUB) - srv.subscriber.SetSubscribe("") - srv.subscriber.Connect(fmt.Sprint("tcp://localhost:", srv.peer+1)) - - // After we've set-up our sockets we register our binary star - // event handlers, and then start the bstar reactor. This finishes - // when the user presses Ctrl-C, or the process receives a SIGINT - // interrupt: - - // Register state change handlers - srv.bstar.NewActive(func() error { return new_active(srv) }) - srv.bstar.NewPassive(func() error { return new_passive(srv) }) - - // Register our other handlers with the bstar reactor - srv.bstar.Reactor.AddSocket(srv.collector, zmq.POLLIN, - func(e zmq.State) error { return collector(srv) }) - srv.bstar.Reactor.AddChannelTime(time.Tick(1000*time.Millisecond), 1, - func(i interface{}) error { - if e := flush_ttl(srv); e != nil { - return e - } - return send_hugz(srv) - }) - - err = srv.bstar.Start() - log.Println(err) -} - -func snapshots(socket *zmq.Socket, srv *clonesrv_t) (err error) { - - msg, err := socket.RecvMessage(0) - if err != nil { - return - } - identity := msg[0] - - // Request is in second frame of message - request := msg[1] - if request != "ICANHAZ?" { - err = errors.New("E: bad request, aborting") - return - } - subtree := msg[2] - - // Send state socket to client - for _, kvmsg := range srv.kvmap { - if key, _ := kvmsg.GetKey(); strings.HasPrefix(key, subtree) { - socket.Send(identity, zmq.SNDMORE) - kvmsg.Send(socket) - } - } - - // Now send END message with sequence number - log.Println("I: sending shapshot =", srv.sequence) - socket.Send(identity, zmq.SNDMORE) - kvmsg := kvmsg.NewKvmsg(srv.sequence) - kvmsg.SetKey("KTHXBAI") - kvmsg.SetBody(subtree) - kvmsg.Send(socket) - - return -} - -// The collector is more complex than in the clonesrv5 example since how -// process updates depends on whether we're active or passive. The active -// applies them immediately to its kvmap, whereas the passive queues them -// as pending: - -// If message was already on pending list, remove it and return TRUE, -// else return FALSE. - -func (srv *clonesrv_t) was_pending(kvmsg *kvmsg.Kvmsg) bool { - uuid1, _ := kvmsg.GetUuid() - for i, msg := range srv.pending { - if uuid2, _ := msg.GetUuid(); uuid1 == uuid2 { - srv.pending = append(srv.pending[:i], srv.pending[i+1:]...) - return true - } - } - return false -} - -func collector(srv *clonesrv_t) (err error) { - - kvmsg, err := kvmsg.RecvKvmsg(srv.collector) - if err != nil { - return - } - - if srv.active { - srv.sequence++ - kvmsg.SetSequence(srv.sequence) - kvmsg.Send(srv.publisher) - if ttls, e := kvmsg.GetProp("ttl"); e == nil { - ttl, e := strconv.ParseInt(ttls, 10, 64) - if e != nil { - err = e - return - } - kvmsg.SetProp("ttl", fmt.Sprint(time.Now().Add(time.Duration(ttl)*time.Second).Unix())) - } - kvmsg.Store(srv.kvmap) - log.Println("I: publishing update =", srv.sequence) - } else { - // If we already got message from active, drop it, else - // hold on pending list - if !srv.was_pending(kvmsg) { - srv.pending = append(srv.pending, kvmsg) - } - } - return -} - -// We purge ephemeral values using exactly the same code as in -// the previous clonesrv5 example. -// If key-value pair has expired, delete it and publish the -// fact to listening clients. - -func flush_ttl(srv *clonesrv_t) (err error) { - for _, kvmsg := range srv.kvmap { - - // If key-value pair has expired, delete it and publish the - // fact to listening clients. - - if ttls, e := kvmsg.GetProp("ttl"); e == nil { - ttl, e := strconv.ParseInt(ttls, 10, 64) - if e != nil { - err = e - continue - } - if time.Now().After(time.Unix(ttl, 0)) { - srv.sequence++ - kvmsg.SetSequence(srv.sequence) - kvmsg.SetBody("") - e = kvmsg.Send(srv.publisher) - if e != nil { - err = e - } - kvmsg.Store(srv.kvmap) - log.Println("I: publishing delete =", srv.sequence) - } - } - } - return -} - -// // We send a HUGZ message once a second to all subscribers so that they -// // can detect if our server dies. They'll then switch over to the backup -// // server, which will become active: - -func send_hugz(srv *clonesrv_t) (err error) { - - kvmsg := kvmsg.NewKvmsg(srv.sequence) - kvmsg.SetKey("HUGZ") - kvmsg.SetBody("") - err = kvmsg.Send(srv.publisher) - return -} - -// When we switch from passive to active, we apply our pending list so that -// our kvmap is up-to-date. When we switch to passive, we wipe our kvmap -// and grab a new snapshot from the active: - -func new_active(srv *clonesrv_t) (err error) { - - srv.active = true - srv.passive = false - - // Stop subscribing to updates - srv.bstar.Reactor.RemoveSocket(srv.subscriber) - - // Apply pending list to own hash table - for _, msg := range srv.pending { - srv.sequence++ - msg.SetSequence(srv.sequence) - msg.Send(srv.publisher) - msg.Store(srv.kvmap) - fmt.Println("I: publishing pending =", srv.sequence) - } - srv.pending = srv.pending[0:0] - return -} - -func new_passive(srv *clonesrv_t) (err error) { - - srv.kvmap = make(map[string]*kvmsg.Kvmsg) - srv.kvmap_init = false - srv.active = false - srv.passive = true - - // Start subscribing to updates - srv.bstar.Reactor.AddSocket(srv.subscriber, zmq.POLLIN, - func(e zmq.State) error { return subscriber(srv) }) - - return -} - -// When we get an update, we create a new kvmap if necessary, and then -// add our update to our kvmap. We're always passive in this case: - -func subscriber(srv *clonesrv_t) (err error) { - // Get state snapshot if necessary - if !srv.kvmap_init { - srv.kvmap_init = true - snapshot, _ := zmq.NewSocket(zmq.DEALER) - snapshot.Connect(fmt.Sprint("tcp://localhost:", srv.peer)) - fmt.Printf("I: asking for snapshot from: tcp://localhost:%v\n", srv.peer) - snapshot.SendMessage("ICANHAZ?", "") // blank subtree to get all - for { - kvmsg, e := kvmsg.RecvKvmsg(snapshot) - if e != nil { - err = e - break - } - if key, _ := kvmsg.GetKey(); key == "KTHXBAI" { - srv.sequence, _ = kvmsg.GetSequence() - break // Done - } - kvmsg.Store(srv.kvmap) - } - fmt.Println("I: received snapshot =", srv.sequence) - } - // Find and remove update off pending list - kvmsg, e := kvmsg.RecvKvmsg(srv.subscriber) - if e != nil { - err = e - return - } - - if key, _ := kvmsg.GetKey(); key != "HUGZ" { - if !srv.was_pending(kvmsg) { - // If active update came before client update, flip it - // around, store active update (with sequence) on pending - // list and use to clear client update when it comes later - srv.pending = append(srv.pending, kvmsg) - } - // If update is more recent than our kvmap, apply it - if seq, _ := kvmsg.GetSequence(); seq > srv.sequence { - srv.sequence = seq - kvmsg.Store(srv.kvmap) - fmt.Println("I: received update =", srv.sequence) - } - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/eagain.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/eagain.go deleted file mode 100644 index 02ced83..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/eagain.go +++ /dev/null @@ -1,28 +0,0 @@ -// -// Shows how to provoke EAGAIN when reaching HWM -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" -) - -func main() { - - mailbox, _ := zmq.NewSocket(zmq.DEALER) - mailbox.SetSndhwm(4) - mailbox.SetSndtimeo(0) - mailbox.Connect("tcp://localhost:9876") - - for count := 0; count < 10; count++ { - fmt.Println("Sending message", count) - _, err := mailbox.SendMessage(fmt.Sprint("message ", count)) - if err != nil { - fmt.Println(err) - break - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/espresso.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/espresso.go deleted file mode 100644 index a72ab60..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/espresso.go +++ /dev/null @@ -1,89 +0,0 @@ -// -// Espresso Pattern -// This shows how to capture data using a pub-sub proxy -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "time" -) - -// The subscriber thread requests messages starting with -// A and B, then reads and counts incoming messages. - -func subscriber_thread() { - // Subscribe to "A" and "B" - subscriber, _ := zmq.NewSocket(zmq.SUB) - subscriber.Connect("tcp://localhost:6001") - subscriber.SetSubscribe("A") - subscriber.SetSubscribe("B") - defer subscriber.Close() // cancel subscribe - - for count := 0; count < 5; count++ { - _, err := subscriber.RecvMessage(0) - if err != nil { - break // Interrupted - } - } -} - -// The publisher sends random messages starting with A-J: - -func publisher_thread() { - publisher, _ := zmq.NewSocket(zmq.PUB) - publisher.Bind("tcp://*:6000") - - for { - s := fmt.Sprintf("%c-%05d", rand.Intn(10)+'A', rand.Intn(100000)) - _, err := publisher.SendMessage(s) - if err != nil { - break // Interrupted - } - time.Sleep(100 * time.Millisecond) // Wait for 1/10th second - } -} - -// The listener receives all messages flowing through the proxy, on its -// pipe. In CZMQ, the pipe is a pair of ZMQ_PAIR sockets that connects -// attached child threads. In other languages your mileage may vary: - -func listener_thread() { - pipe, _ := zmq.NewSocket(zmq.PAIR) - pipe.Bind("inproc://pipe") - - // Print everything that arrives on pipe - for { - msg, err := pipe.RecvMessage(0) - if err != nil { - break // Interrupted - } - fmt.Printf("%q\n", msg) - } -} - -// The main task starts the subscriber and publisher, and then sets -// itself up as a listening proxy. The listener runs as a child thread: - -func main() { - // Start child threads - go publisher_thread() - go subscriber_thread() - go listener_thread() - - time.Sleep(100 * time.Millisecond) - - subscriber, _ := zmq.NewSocket(zmq.XSUB) - subscriber.Connect("tcp://localhost:6000") - publisher, _ := zmq.NewSocket(zmq.XPUB) - publisher.Bind("tcp://*:6001") - listener, _ := zmq.NewSocket(zmq.PAIR) - listener.Connect("inproc://pipe") - zmq.Proxy(subscriber, publisher, listener) - - fmt.Println("interrupted") -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio1.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio1.go deleted file mode 100644 index dfd9c25..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio1.go +++ /dev/null @@ -1,98 +0,0 @@ -// File Transfer model #1 -// -// In which the server sends the entire file to the client in -// large chunks with no attempt at flow control. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "io" - "os" -) - -const ( - CHUNK_SIZE = 250000 -) - -func client_thread(pipe chan<- string) { - dealer, _ := zmq.NewSocket(zmq.DEALER) - dealer.Connect("tcp://127.0.0.1:6000") - - dealer.Send("fetch", 0) - total := 0 // Total bytes received - chunks := 0 // Total chunks received - - for { - frame, err := dealer.RecvBytes(0) - if err != nil { - break // Shutting down, quit - } - chunks++ - size := len(frame) - total += size - if size == 0 { - break // Whole file received - } - } - fmt.Printf("%v chunks received, %v bytes\n", chunks, total) - pipe <- "OK" -} - -// The server thread reads the file from disk in chunks, and sends -// each chunk to the client as a separate message. We only have one -// test file, so open that once and then serve it out as needed: - -func server_thread() { - file, err := os.Open("testdata") - if err != nil { - panic(err) - } - - router, _ := zmq.NewSocket(zmq.ROUTER) - // Default HWM is 1000, which will drop messages here - // since we send more than 1,000 chunks of test data, - // so set an infinite HWM as a simple, stupid solution: - router.SetRcvhwm(0) - router.SetSndhwm(0) - router.Bind("tcp://*:6000") - for { - // First frame in each message is the sender identity - identity, err := router.Recv(0) - if err != nil { - break // Shutting down, quit - } - - // Second frame is "fetch" command - command, _ := router.Recv(0) - if command != "fetch" { - panic("command != \"fetch\"") - } - - chunk := make([]byte, CHUNK_SIZE) - for { - n, _ := io.ReadFull(file, chunk) - router.SendMessage(identity, chunk[:n]) - if n == 0 { - break // Always end with a zero-size frame - } - } - } - file.Close() -} - -// The main task starts the client and server threads; it's easier -// to test this as a single process with threads, than as multiple -// processes: - -func main() { - pipe := make(chan string) - - // Start child threads - go server_thread() - go client_thread(pipe) - // Loop until client tells us it's done - <-pipe -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio2.go deleted file mode 100644 index 073d665..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio2.go +++ /dev/null @@ -1,98 +0,0 @@ -// File Transfer model #2 -// -// In which the client requests each chunk individually, thus -// eliminating server queue overflows, but at a cost in speed. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "os" - "strconv" -) - -const ( - CHUNK_SIZE = 250000 -) - -func client_thread(pipe chan<- string) { - dealer, _ := zmq.NewSocket(zmq.DEALER) - dealer.Connect("tcp://127.0.0.1:6000") - - total := 0 // Total bytes received - chunks := 0 // Total chunks received - - for { - // Ask for next chunk - dealer.SendMessage("fetch", total, CHUNK_SIZE) - - chunk, err := dealer.RecvBytes(0) - if err != nil { - break // Shutting down, quit - } - chunks++ - size := len(chunk) - total += size - if size < CHUNK_SIZE { - break // Last chunk received; exit - } - } - fmt.Printf("%v chunks received, %v bytes\n", chunks, total) - pipe <- "OK" -} - -// The server thread waits for a chunk request from a client, -// reads that chunk and sends it back to the client: - -func server_thread() { - file, err := os.Open("testdata") - if err != nil { - panic(err) - } - - router, _ := zmq.NewSocket(zmq.ROUTER) - router.SetRcvhwm(1) - router.SetSndhwm(1) - router.Bind("tcp://*:6000") - for { - msg, err := router.RecvMessage(0) - if err != nil { - break // Shutting down, quit - } - // First frame in each message is the sender identity - identity := msg[0] - - // Second frame is "fetch" command - if msg[1] != "fetch" { - panic("command != \"fetch\"") - } - - // Third frame is chunk offset in file - offset, _ := strconv.ParseInt(msg[2], 10, 64) - - // Fourth frame is maximum chunk size - chunksz, _ := strconv.Atoi(msg[3]) - - // Read chunk of data from file - chunk := make([]byte, chunksz) - n, _ := file.ReadAt(chunk, offset) - - // Send resulting chunk to client - router.SendMessage(identity, chunk[:n]) - } - file.Close() -} - -// The main task is just the same as in the first model. - -func main() { - pipe := make(chan string) - - // Start child threads - go server_thread() - go client_thread(pipe) - // Loop until client tells us it's done - <-pipe -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio3.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio3.go deleted file mode 100644 index b631ddf..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/fileio3.go +++ /dev/null @@ -1,111 +0,0 @@ -// File Transfer model #3 -// -// In which the client requests each chunk individually, using -// command pipelining to give us a credit-based flow control. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "os" - "strconv" -) - -const ( - CHUNK_SIZE = 250000 - PIPELINE = 10 -) - -func client_thread(pipe chan<- string) { - dealer, _ := zmq.NewSocket(zmq.DEALER) - dealer.Connect("tcp://127.0.0.1:6000") - - // Up to this many chunks in transit - credit := PIPELINE - - total := 0 // Total bytes received - chunks := 0 // Total chunks received - offset := 0 // Offset of next chunk request - - for { - for credit > 0 { - // Ask for next chunk - dealer.SendMessage("fetch", offset, CHUNK_SIZE) - offset += CHUNK_SIZE - credit-- - } - chunk, err := dealer.RecvBytes(0) - if err != nil { - break // Shutting down, quit - } - chunks++ - credit++ - size := len(chunk) - total += size - if size < CHUNK_SIZE { - break // Last chunk received; exit - } - } - fmt.Printf("%v chunks received, %v bytes\n", chunks, total) - pipe <- "OK" -} - -// The rest of the code is exactly the same as in model 2, except -// that we set the HWM on the server's ROUTER socket to PIPELINE -// to act as a sanity check. - -// The server thread waits for a chunk request from a client, -// reads that chunk and sends it back to the client: - -func server_thread() { - file, err := os.Open("testdata") - if err != nil { - panic(err) - } - - router, _ := zmq.NewSocket(zmq.ROUTER) - router.SetRcvhwm(PIPELINE * 2) - router.SetSndhwm(PIPELINE * 2) - router.Bind("tcp://*:6000") - for { - msg, err := router.RecvMessage(0) - if err != nil { - break // Shutting down, quit - } - // First frame in each message is the sender identity - identity := msg[0] - - // Second frame is "fetch" command - if msg[1] != "fetch" { - panic("command != \"fetch\"") - } - - // Third frame is chunk offset in file - offset, _ := strconv.ParseInt(msg[2], 10, 64) - - // Fourth frame is maximum chunk size - chunksz, _ := strconv.Atoi(msg[3]) - - // Read chunk of data from file - chunk := make([]byte, chunksz) - n, _ := file.ReadAt(chunk, offset) - - // Send resulting chunk to client - router.SendMessage(identity, chunk[:n]) - } - file.Close() -} - -// The main task is just the same as in the first model. - -func main() { - pipe := make(chan string) - - // Start child threads - go server_thread() - go client_thread(pipe) - // Loop until client tells us it's done - <-pipe -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flcliapi/flcliapi.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flcliapi/flcliapi.go deleted file mode 100644 index 5c27a43..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flcliapi/flcliapi.go +++ /dev/null @@ -1,268 +0,0 @@ -// flcliapi - Freelance Pattern agent class. -// Implements the Freelance Protocol at http://rfc.zeromq.org/spec:10. -package flcliapi - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "strconv" - "time" -) - -const ( - // If no server replies within this time, abandon request - GLOBAL_TIMEOUT = 3000 * time.Millisecond - // PING interval for servers we think are alive - PING_INTERVAL = 2000 * time.Millisecond - // Server considered dead if silent for this long - SERVER_TTL = 6000 * time.Millisecond -) - -// This API works in two halves, a common pattern for APIs that need to -// run in the background. One half is an front-end object our application -// creates and works with; the other half is a back-end "agent" that runs -// in a background thread. The front-end talks to the back-end over an -// inproc pipe socket: - -// --------------------------------------------------------------------- -// Structure of our front-end class - -type Flcliapi struct { - pipe *zmq.Socket // Pipe through to flcliapi agent -} - -// This is the thread that handles our real flcliapi class - -// --------------------------------------------------------------------- -// Constructor - -func New() (flcliapi *Flcliapi) { - flcliapi = &Flcliapi{} - flcliapi.pipe, _ = zmq.NewSocket(zmq.PAIR) - flcliapi.pipe.Bind("inproc://pipe") - go flcliapi_agent() - return -} - -// To implement the connect method, the front-end object sends a multi-part -// message to the back-end agent. The first part is a string "CONNECT", and -// the second part is the endpoint. It waits 100msec for the connection to -// come up, which isn't pretty, but saves us from sending all requests to a -// single server, at start-up time: - -func (flcliapi *Flcliapi) Connect(endpoint string) { - flcliapi.pipe.SendMessage("CONNECT", endpoint) - time.Sleep(100 * time.Millisecond) // Allow connection to come up -} - -// To implement the request method, the front-end object sends a message -// to the back-end, specifying a command "REQUEST" and the request message: - -func (flcliapi *Flcliapi) Request(request []string) (reply []string, err error) { - flcliapi.pipe.SendMessage("REQUEST", request) - reply, err = flcliapi.pipe.RecvMessage(0) - if err == nil { - status := reply[0] - reply = reply[1:] - if status == "FAILED" { - reply = reply[0:0] - } - } - return -} - -// Here we see the back-end agent. It runs as an attached thread, talking -// to its parent over a pipe socket. It is a fairly complex piece of work -// so we'll break it down into pieces. First, the agent manages a set of -// servers, using our familiar class approach: - -// --------------------------------------------------------------------- -// Simple class for one server we talk to - -type server_t struct { - endpoint string // Server identity/endpoint - alive bool // true if known to be alive - ping_at time.Time // Next ping at this time - expires time.Time // Expires at this time -} - -func server_new(endpoint string) (server *server_t) { - server = &server_t{ - endpoint: endpoint, - alive: false, - ping_at: time.Now().Add(PING_INTERVAL), - expires: time.Now().Add(SERVER_TTL), - } - return -} - -func (server *server_t) ping(socket *zmq.Socket) { - if time.Now().After(server.ping_at) { - socket.SendMessage(server.endpoint, "PING") - server.ping_at = time.Now().Add(PING_INTERVAL) - } -} - -func (server *server_t) tickless(t time.Time) time.Time { - if t.After(server.ping_at) { - return server.ping_at - } - return t -} - -// We build the agent as a class that's capable of processing messages -// coming in from its various sockets: - -// --------------------------------------------------------------------- -// Simple class for one background agent - -type agent_t struct { - pipe *zmq.Socket // Socket to talk back to application - router *zmq.Socket // Socket to talk to servers - servers map[string]*server_t // Servers we've connected to - actives []*server_t // Servers we know are alive - sequence int // Number of requests ever sent - request []string // Current request if any - reply []string // Current reply if any - expires time.Time // Timeout for request/reply -} - -func agent_new() (agent *agent_t) { - agent = &agent_t{ - servers: make(map[string]*server_t), - actives: make([]*server_t, 0), - request: make([]string, 0), - reply: make([]string, 0), - } - agent.pipe, _ = zmq.NewSocket(zmq.PAIR) - agent.pipe.Connect("inproc://pipe") - agent.router, _ = zmq.NewSocket(zmq.ROUTER) - return -} - -// The control_message method processes one message from our front-end -// class (it's going to be CONNECT or REQUEST): - -func (agent *agent_t) control_message() { - msg, _ := agent.pipe.RecvMessage(0) - command := msg[0] - msg = msg[1:] - - switch command { - case "CONNECT": - endpoint := msg[0] - fmt.Printf("I: connecting to %s...\n", endpoint) - err := agent.router.Connect(endpoint) - if err != nil { - panic("agent.router.Connect(endpoint) failed") - } - server := server_new(endpoint) - agent.servers[endpoint] = server - agent.actives = append(agent.actives, server) - server.ping_at = time.Now().Add(PING_INTERVAL) - server.expires = time.Now().Add(SERVER_TTL) - case "REQUEST": - if len(agent.request) > 0 { - panic("len(agent.request) > 0") // Strict request-reply cycle - } - // Prefix request with sequence number --(and empty envelope)-- - agent.request = make([]string, 1, 1+len(msg)) - agent.sequence++ - agent.request[0] = fmt.Sprint(agent.sequence) - agent.request = append(agent.request, msg...) - // Request expires after global timeout - agent.expires = time.Now().Add(GLOBAL_TIMEOUT) - } -} - -// The router_message method processes one message from a connected -// server: - -func (agent *agent_t) router_message() { - reply, _ := agent.router.RecvMessage(0) - - // Frame 0 is server that replied - endpoint := reply[0] - reply = reply[1:] - server, ok := agent.servers[endpoint] - if !ok { - panic("No server for endpoint") - } - if !server.alive { - agent.actives = append(agent.actives, server) - server.alive = true - } - server.ping_at = time.Now().Add(PING_INTERVAL) - server.expires = time.Now().Add(SERVER_TTL) - - // Frame 1 may be sequence number for reply - sequence, _ := strconv.Atoi(reply[0]) - reply = reply[1:] - if sequence == agent.sequence { - agent.pipe.SendMessage("OK", reply) - agent.request = agent.request[0:0] - } -} - -// Finally here's the agent task itself, which polls its two sockets -// and processes incoming messages: - -func flcliapi_agent() { - - agent := agent_new() - - poller := zmq.NewPoller() - poller.Add(agent.pipe, zmq.POLLIN) - poller.Add(agent.router, zmq.POLLIN) - for { - // Calculate tickless timer, up to 1 hour - tickless := time.Now().Add(time.Hour) - if len(agent.request) > 0 && tickless.After(agent.expires) { - tickless = agent.expires - } - for key := range agent.servers { - tickless = agent.servers[key].tickless(tickless) - } - - polled, err := poller.Poll(tickless.Sub(time.Now())) - if err != nil { - break // Context has been shut down - } - - for _, item := range polled { - switch item.Socket { - case agent.pipe: - agent.control_message() - case agent.router: - agent.router_message() - } - } - - // If we're processing a request, dispatch to next server - if len(agent.request) > 0 { - if time.Now().After(agent.expires) { - // Request expired, kill it - agent.pipe.SendMessage("FAILED") - agent.request = agent.request[0:0] - } else { - // Find server to talk to, remove any expired ones - for len(agent.actives) > 0 { - server := agent.actives[0] - if time.Now().After(server.expires) { - agent.actives = agent.actives[1:] - server.alive = false - } else { - agent.router.SendMessage(server.endpoint, agent.request) - break - } - } - } - } - // --(Disconnect and delete any expired servers)-- - // Send heartbeats to idle servers if needed - for key := range agent.servers { - agent.servers[key].ping(agent.router) - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient1.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient1.go deleted file mode 100644 index bc17802..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient1.go +++ /dev/null @@ -1,77 +0,0 @@ -// -// Freelance client - Model 1. -// Uses REQ socket to query one or more services -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "errors" - "fmt" - "os" - "time" -) - -const ( - REQUEST_TIMEOUT = 1000 * time.Millisecond - MAX_RETRIES = 3 // Before we abandon -) - -func try_request(endpoint string, request []string) (reply []string, err error) { - fmt.Printf("I: trying echo service at %s...\n", endpoint) - client, _ := zmq.NewSocket(zmq.REQ) - client.Connect(endpoint) - - // Send request, wait safely for reply - client.SendMessage(request) - poller := zmq.NewPoller() - poller.Add(client, zmq.POLLIN) - polled, err := poller.Poll(REQUEST_TIMEOUT) - reply = []string{} - if len(polled) == 1 { - reply, err = client.RecvMessage(0) - } else { - err = errors.New("Time out") - } - return -} - -// The client uses a Lazy Pirate strategy if it only has one server to talk -// to. If it has 2 or more servers to talk to, it will try each server just -// once: - -func main() { - request := []string{"Hello world"} - reply := []string{} - var err error - - endpoints := len(os.Args) - 1 - if endpoints == 0 { - fmt.Printf("I: syntax: %s ...\n", os.Args[0]) - } else if endpoints == 1 { - // For one endpoint, we retry N times - for retries := 0; retries < MAX_RETRIES; retries++ { - endpoint := os.Args[1] - reply, err = try_request(endpoint, request) - if err == nil { - break // Successful - } - fmt.Printf("W: no response from %s, retrying...\n", endpoint) - } - } else { - // For multiple endpoints, try each at most once - for endpoint_nbr := 0; endpoint_nbr < endpoints; endpoint_nbr++ { - endpoint := os.Args[endpoint_nbr+1] - reply, err = try_request(endpoint, request) - if err == nil { - break // Successful - } - fmt.Println("W: no response from", endpoint) - } - } - if len(reply) > 0 { - fmt.Printf("Service is running OK: %q\n", reply) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient2.go deleted file mode 100644 index bb7091d..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient2.go +++ /dev/null @@ -1,118 +0,0 @@ -// -// Freelance client - Model 2. -// Uses DEALER socket to blast one or more services -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "errors" - "fmt" - "os" - "strconv" - "time" -) - -const ( - - // If not a single service replies within this time, give up - GLOBAL_TIMEOUT = 2500 * time.Millisecond -) - -func main() { - if len(os.Args) == 1 { - fmt.Printf("I: syntax: %s ...\n", os.Args[0]) - return - } - // Create new freelance client object - client := new_flclient() - - // Connect to each endpoint - for argn := 1; argn < len(os.Args); argn++ { - client.connect(os.Args[argn]) - } - - // Send a bunch of name resolution 'requests', measure time - start := time.Now() - for requests := 10000; requests > 0; requests-- { - _, err := client.request("random name") - if err != nil { - fmt.Println("E: name service not available, aborting") - break - } - } - fmt.Println("Average round trip cost:", time.Now().Sub(start)) -} - -// Here is the flclient class implementation. Each instance has -// a DEALER socket it uses to talk to the servers, a counter of how many -// servers it's connected to, and a request sequence number: - -type flclient_t struct { - socket *zmq.Socket // DEALER socket talking to servers - servers int // How many servers we have connected to - sequence int // Number of requests ever sent -} - -// -------------------------------------------------------------------- -// Constructor - -func new_flclient() (client *flclient_t) { - client = &flclient_t{} - - client.socket, _ = zmq.NewSocket(zmq.DEALER) - return -} - -// -------------------------------------------------------------------- -// Connect to new server endpoint - -func (client *flclient_t) connect(endpoint string) { - client.socket.Connect(endpoint) - client.servers++ -} - -// The request method does the hard work. It sends a request to all -// connected servers in parallel (for this to work, all connections -// have to be successful and completed by this time). It then waits -// for a single successful reply, and returns that to the caller. -// Any other replies are just dropped: - -func (client *flclient_t) request(request ...string) (reply []string, err error) { - reply = []string{} - - // Prefix request with sequence number and empty envelope - client.sequence++ - - // Blast the request to all connected servers - for server := 0; server < client.servers; server++ { - client.socket.SendMessage("", client.sequence, request) - } - // Wait for a matching reply to arrive from anywhere - // Since we can poll several times, calculate each one - endtime := time.Now().Add(GLOBAL_TIMEOUT) - poller := zmq.NewPoller() - poller.Add(client.socket, zmq.POLLIN) - for time.Now().Before(endtime) { - polled, err := poller.Poll(endtime.Sub(time.Now())) - if err == nil && len(polled) > 0 { - // Reply is [empty][sequence][OK] - reply, _ = client.socket.RecvMessage(0) - if len(reply) != 3 { - panic("len(reply) != 3") - } - sequence := reply[1] - reply = reply[2:] - sequence_nbr, _ := strconv.Atoi(sequence) - if sequence_nbr == client.sequence { - break - } - } - } - if len(reply) == 0 { - err = errors.New("No reply") - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient3.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient3.go deleted file mode 100644 index 75b44b8..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flclient3.go +++ /dev/null @@ -1,35 +0,0 @@ -// -// Freelance client - Model 3. -// Uses flcliapi class to encapsulate Freelance pattern -// - -package main - -import ( - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flcliapi" - - "fmt" - "time" -) - -func main() { - // Create new freelance client object - client := flcliapi.New() - - // Connect to several endpoints - client.Connect("tcp://localhost:5555") - client.Connect("tcp://localhost:5556") - client.Connect("tcp://localhost:5557") - - // Send a bunch of name resolution 'requests', measure time - start := time.Now() - req := []string{"random name"} - for requests := 1000; requests > 0; requests-- { - _, err := client.Request(req) - if err != nil { - fmt.Println("E: name service not available, aborting") - break - } - } - fmt.Println("Average round trip cost:", time.Now().Sub(start)/1000) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver1.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver1.go deleted file mode 100644 index 0fdd1e1..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver1.go +++ /dev/null @@ -1,32 +0,0 @@ -// -// Freelance server - Model 1. -// Trivial echo service -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "os" -) - -func main() { - if len(os.Args) < 2 { - fmt.Printf("I: syntax: %s \n", os.Args[0]) - return - } - server, _ := zmq.NewSocket(zmq.REP) - server.Bind(os.Args[1]) - - fmt.Println("I: echo service is ready at", os.Args[1]) - for { - msg, err := server.RecvMessage(0) - if err != nil { - break // Interrupted - } - server.SendMessage(msg) - } - fmt.Println("W: interrupted") -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver2.go deleted file mode 100644 index 8ad3c94..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver2.go +++ /dev/null @@ -1,39 +0,0 @@ -// -// Freelance server - Model 2. -// Does some work, replies OK, with message sequencing -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "os" -) - -func main() { - if len(os.Args) < 2 { - fmt.Printf("I: syntax: %s \n", os.Args[0]) - return - } - server, _ := zmq.NewSocket(zmq.REP) - server.Bind(os.Args[1]) - - fmt.Println("I: service is ready at", os.Args[1]) - for { - request, err := server.RecvMessage(0) - if err != nil { - break // Interrupted - } - // Fail nastily if run against wrong client - if len(request) != 2 { - panic("len(request) != 2") - } - - identity := request[0] - - server.SendMessage(identity, "OK") - } - fmt.Println("W: interrupted") -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver3.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver3.go deleted file mode 100644 index d9f57e4..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/flserver3.go +++ /dev/null @@ -1,57 +0,0 @@ -// -// Freelance server - Model 3. -// Uses an ROUTER/ROUTER socket but just one thread -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "os" -) - -func main() { - var verbose bool - if len(os.Args) > 1 && os.Args[1] == "-v" { - verbose = true - } - - // Prepare server socket with predictable identity - bind_endpoint := "tcp://*:5555" - connect_endpoint := "tcp://localhost:5555" - server, _ := zmq.NewSocket(zmq.ROUTER) - server.SetIdentity(connect_endpoint) - server.Bind(bind_endpoint) - fmt.Println("I: service is ready at", bind_endpoint) - - for { - request, err := server.RecvMessage(0) - if err != nil { - break - } - if verbose { - fmt.Printf("%q\n", request) - } - - // Frame 0: identity of client - // Frame 1: PING, or client control frame - // Frame 2: request body - identity := request[0] - control := request[1] - reply := make([]string, 1, 3) - if control == "PING" { - reply = append(reply, "PONG") - } else { - reply = append(reply, control) - reply = append(reply, "OK") - } - reply[0] = identity - if verbose { - fmt.Printf("%q\n", reply) - } - server.SendMessage(reply) - } - fmt.Println("W: interrupted") -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/hwclient.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/hwclient.go deleted file mode 100644 index 26d063c..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/hwclient.go +++ /dev/null @@ -1,32 +0,0 @@ -// -// Hello World client. -// Connects REQ socket to tcp://localhost:5555 -// Sends "Hello" to server, expects "World" back -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" -) - -func main() { - // Socket to talk to server - fmt.Println("Connecting to hello world server...") - requester, _ := zmq.NewSocket(zmq.REQ) - defer requester.Close() - requester.Connect("tcp://localhost:5555") - - for request_nbr := 0; request_nbr != 10; request_nbr++ { - // send hello - msg := fmt.Sprintf("Hello %d", request_nbr) - fmt.Println("Sending ", msg) - requester.Send(msg, 0) - - // Wait for reply: - reply, _ := requester.Recv(0) - fmt.Println("Received ", reply) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/hwserver.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/hwserver.go deleted file mode 100644 index d909ac7..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/hwserver.go +++ /dev/null @@ -1,34 +0,0 @@ -// -// Hello World server. -// Binds REP socket to tcp://*:5555 -// Expects "Hello" from client, replies with "World" -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "time" -) - -func main() { - // Socket to talk to clients - responder, _ := zmq.NewSocket(zmq.REP) - defer responder.Close() - responder.Bind("tcp://*:5555") - - for { - // Wait for next request from client - msg, _ := responder.Recv(0) - fmt.Println("Received ", msg) - - // Do some 'work' - time.Sleep(time.Second) - - // Send reply back to client - reply := "World" - responder.Send(reply, 0) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/identity.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/identity.go deleted file mode 100644 index 70042cc..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/identity.go +++ /dev/null @@ -1,62 +0,0 @@ -// -// Demonstrate identities as used by the request-reply pattern. -// Run this program by itself. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "regexp" -) - -var ( - all_char = regexp.MustCompile("^[^[:cntrl:]]*$") -) - -func main() { - sink, _ := zmq.NewSocket(zmq.ROUTER) - defer sink.Close() - sink.Bind("inproc://example") - - // First allow 0MQ to set the identity - anonymous, _ := zmq.NewSocket(zmq.REQ) - defer anonymous.Close() - anonymous.Connect("inproc://example") - anonymous.Send("ROUTER uses a generated UUID", 0) - dump(sink) - - // Then set the identity ourselves - identified, _ := zmq.NewSocket(zmq.REQ) - defer identified.Close() - identified.SetIdentity("PEER2") - identified.Connect("inproc://example") - identified.Send("ROUTER socket uses REQ's socket identity", 0) - dump(sink) -} - -func dump(soc *zmq.Socket) { - fmt.Println("----------------------------------------") - for { - // Process all parts of the message - message, _ := soc.Recv(0) - - // Dump the message as text or binary - fmt.Printf("[%03d] ", len(message)) - if all_char.MatchString(message) { - fmt.Print(message) - } else { - for i := 0; i < len(message); i++ { - fmt.Printf("%02X ", message[i]) - } - } - fmt.Println() - - more, _ := soc.GetRcvmore() - if !more { - break - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/interrupt.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/interrupt.go deleted file mode 100644 index b5ff4e2..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/interrupt.go +++ /dev/null @@ -1,57 +0,0 @@ -// WARNING: This won't build on Windows and Plan9. - -// -// Handling Ctrl-C cleanly in C. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" - "os" - "os/signal" - "syscall" - "time" -) - -func main() { - // Socket to talk to server - fmt.Println("Connecting to hello world server...") - client, _ := zmq.NewSocket(zmq.REQ) - defer client.Close() - client.Connect("tcp://localhost:5555") - - // Without signal handling, Go will exit on signal, even if the signal was caught by ZeroMQ - chSignal := make(chan os.Signal, 1) - signal.Notify(chSignal, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM) - -LOOP: - for { - client.Send("HELLO", 0) - reply, err := client.Recv(0) - if err != nil { - if zmq.AsErrno(err) == zmq.Errno(syscall.EINTR) { - // signal was caught by 0MQ - log.Println("Client Recv:", err) - break - } else { - // some error occured - log.Panicln(err) - } - } - - fmt.Println("Client:", reply) - time.Sleep(time.Second) - - select { - case sig := <-chSignal: - // signal was caught by Go - log.Println("Signal:", sig) - break LOOP - default: - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/intface/intface.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/intface/intface.go deleted file mode 100644 index 014c04b..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/intface/intface.go +++ /dev/null @@ -1,254 +0,0 @@ -// Interface class for Chapter 8. -// This implements an "interface" to our network of nodes. -package intface - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "code.google.com/p/go-uuid/uuid" - - "bytes" - "errors" - "net" - "time" -) - -// ===================================================================== -// Synchronous part, works in our application thread - -// --------------------------------------------------------------------- -// Structure of our class - -type Intface struct { - pipe *zmq.Socket // Pipe through to agent -} - -// This is the thread that handles our real interface class - -// Here is the constructor for the interface class. -// Note that the class has barely any properties, it is just an excuse -// to start the background thread, and a wrapper around zmsg_recv(): - -func New() (iface *Intface) { - iface = &Intface{} - var err error - iface.pipe, err = zmq.NewSocket(zmq.PAIR) - if err != nil { - panic(err) - } - err = iface.pipe.Bind("inproc://iface") - if err != nil { - panic(err) - } - go iface.agent() - time.Sleep(100 * time.Millisecond) - return -} - -// Here we wait for a message from the interface. This returns -// us a []string, or error if interrupted: - -func (iface *Intface) Recv() (msg []string, err error) { - msg, err = iface.pipe.RecvMessage(0) - return -} - -// ===================================================================== -// // Asynchronous part, works in the background - -// This structure defines each peer that we discover and track: - -type peer_t struct { - uuid_bytes []byte - uuid_string string - expires_at time.Time -} - -const ( - PING_PORT_NUMBER = 9999 - PING_INTERVAL = 1000 * time.Millisecond // Once per second - PEER_EXPIRY = 5000 * time.Millisecond // Five seconds and it's gone -) - -// We have a constructor for the peer class: - -func new_peer(uuid uuid.UUID) (peer *peer_t) { - peer = &peer_t{ - uuid_bytes: []byte(uuid), - uuid_string: uuid.String(), - } - return -} - -// Just resets the peers expiry time; we call this method -// whenever we get any activity from a peer. - -func (peer *peer_t) is_alive() { - peer.expires_at = time.Now().Add(PEER_EXPIRY) -} - -// This structure holds the context for our agent, so we can -// pass that around cleanly to methods which need it: - -type agent_t struct { - pipe *zmq.Socket // Pipe back to application - udp *zmq.Socket - conn *net.UDPConn - uuid_bytes []byte // Our UUID - uuid_string string - peers map[string]*peer_t // Hash of known peers, fast lookup -} - -// Now the constructor for our agent. Each interface -// has one agent object, which implements its background thread: - -func new_agent() (agent *agent_t) { - - // push output from udp into zmq socket - bcast := &net.UDPAddr{Port: PING_PORT_NUMBER, IP: net.IPv4bcast} - conn, e := net.ListenUDP("udp", bcast) - if e != nil { - panic(e) - } - go func() { - buffer := make([]byte, 1024) - udp, _ := zmq.NewSocket(zmq.PAIR) - udp.Bind("inproc://udp") - for { - if n, _, err := conn.ReadFrom(buffer); err == nil { - udp.SendBytes(buffer[:n], 0) - } - } - }() - time.Sleep(100 * time.Millisecond) - - pipe, _ := zmq.NewSocket(zmq.PAIR) - pipe.Connect("inproc://iface") - udp, _ := zmq.NewSocket(zmq.PAIR) - udp.Connect("inproc://udp") - - uuid := uuid.NewRandom() - agent = &agent_t{ - pipe: pipe, - udp: udp, - conn: conn, - uuid_bytes: []byte(uuid), - uuid_string: uuid.String(), - peers: make(map[string]*peer_t), - } - - return -} - -// Here we handle the different control messages from the front-end. - -func (agent *agent_t) control_message() (err error) { - // Get the whole message off the pipe in one go - msg, e := agent.pipe.RecvMessage(0) - if e != nil { - return e - } - command := msg[0] - - // We don't actually implement any control commands yet - // but if we did, this would be where we did it.. - switch command { - case "EXAMPLE": - default: - } - - return -} - -// This is how we handle a beacon coming into our UDP socket; -// this may be from other peers or an echo of our own broadcast -// beacon: - -func (agent *agent_t) handle_beacon() (err error) { - - msg, err := agent.udp.RecvMessage(0) - if len(msg[0]) != 16 { - return errors.New("Not a uuid") - } - - // If we got a UUID and it's not our own beacon, we have a peer - uuid := uuid.UUID(msg[0]) - if bytes.Compare(uuid, agent.uuid_bytes) != 0 { - // Find or create peer via its UUID string - uuid_string := uuid.String() - peer, ok := agent.peers[uuid_string] - if !ok { - peer = new_peer(uuid) - agent.peers[uuid_string] = peer - - // Report peer joined the network - agent.pipe.SendMessage("JOINED", uuid_string) - } - // Any activity from the peer means it's alive - peer.is_alive() - } - return -} - -// This method checks one peer item for expiry; if the peer hasn't -// sent us anything by now, it's 'dead' and we can delete it: - -func (agent *agent_t) reap_peer(peer *peer_t) { - if time.Now().After(peer.expires_at) { - // Report peer left the network - agent.pipe.SendMessage("LEFT", peer.uuid_string) - delete(agent.peers, peer.uuid_string) - } -} - -// This is the main loop for the background agent. It uses zmq_poll -// to monitor the front-end pipe (commands from the API) and the -// back-end UDP handle (beacons): - -func (iface *Intface) agent() { - // Create agent instance to pass around - agent := new_agent() - - // Send first beacon immediately - ping_at := time.Now() - - poller := zmq.NewPoller() - poller.Add(agent.pipe, zmq.POLLIN) - poller.Add(agent.udp, zmq.POLLIN) - - bcast := &net.UDPAddr{Port: PING_PORT_NUMBER, IP: net.IPv4bcast} - for { - timeout := ping_at.Add(time.Millisecond).Sub(time.Now()) - if timeout < 0 { - timeout = 0 - } - polled, err := poller.Poll(timeout) - if err != nil { - break - } - - for _, item := range polled { - switch socket := item.Socket; socket { - case agent.pipe: - // If we had activity on the pipe, go handle the control - // message. Current code never sends control messages. - agent.control_message() - - case agent.udp: - // If we had input on the UDP socket, go process that - agent.handle_beacon() - } - } - - // If we passed the 1-second mark, broadcast our beacon - now := time.Now() - if now.After(ping_at) { - agent.conn.WriteTo(agent.uuid_bytes, bcast) - ping_at = now.Add(PING_INTERVAL) - } - // Delete and report any expired peers - for _, peer := range agent.peers { - agent.reap_peer(peer) - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg/kvmsg.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg/kvmsg.go deleted file mode 100644 index ebd1a22..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg/kvmsg.go +++ /dev/null @@ -1,262 +0,0 @@ -// kvmsg class - key-value message class for example applications -package kvmsg - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "code.google.com/p/go-uuid/uuid" - - "errors" - "fmt" - "os" - "strings" -) - -// Message is formatted on wire as 4 frames: -// frame 0: key (0MQ string) -// frame 1: sequence (8 bytes, network order) -// frame 2: uuid (blob, 16 bytes) -// frame 3: properties (0MQ string) -// frame 4: body (blob) -const ( - frame_KEY = 0 - frame_SEQ = 1 - frame_UUID = 2 - frame_PROPS = 3 - frame_BODY = 4 - kvmsg_FRAMES = 5 -) - -// Structure of our class -type Kvmsg struct { - // Presence indicators for each frame - present []bool - // Corresponding 0MQ message frames, if any - frame []string - // List of properties, as name=value strings - props []string -} - -// These two helpers serialize a list of properties to and from a -// message frame: - -func (kvmsg *Kvmsg) encode_props() { - kvmsg.frame[frame_PROPS] = strings.Join(kvmsg.props, "\n") + "\n" - kvmsg.present[frame_PROPS] = true -} - -func (kvmsg *Kvmsg) decode_props() { - kvmsg.props = strings.Split(kvmsg.frame[frame_PROPS], "\n") - if ln := len(kvmsg.props); ln > 0 && kvmsg.props[ln-1] == "" { - kvmsg.props = kvmsg.props[:ln-1] - } -} - -// Constructor, takes a sequence number for the new Kvmsg instance. -func NewKvmsg(sequence int64) (kvmsg *Kvmsg) { - kvmsg = &Kvmsg{ - present: make([]bool, kvmsg_FRAMES), - frame: make([]string, kvmsg_FRAMES), - props: make([]string, 0), - } - kvmsg.SetSequence(sequence) - return -} - -// The RecvKvmsg function reads a key-value message from socket, and returns a new -// Kvmsg instance. -func RecvKvmsg(socket *zmq.Socket) (kvmsg *Kvmsg, err error) { - kvmsg = &Kvmsg{ - present: make([]bool, kvmsg_FRAMES), - frame: make([]string, kvmsg_FRAMES), - } - msg, err := socket.RecvMessage(0) - if err != nil { - return - } - //fmt.Printf("Recv from %s: %q\n", socket, msg) - for i := 0; i < kvmsg_FRAMES && i < len(msg); i++ { - kvmsg.frame[i] = msg[i] - kvmsg.present[i] = true - } - kvmsg.decode_props() - return -} - -// Send key-value message to socket; any empty frames are sent as such. -func (kvmsg *Kvmsg) Send(socket *zmq.Socket) (err error) { - //fmt.Printf("Send to %s: %q\n", socket, kvmsg.frame) - kvmsg.encode_props() - _, err = socket.SendMessage(kvmsg.frame) - return -} - -// The Dup method duplicates a kvmsg instance, returns the new instance. -func (kvmsg *Kvmsg) Dup() (dup *Kvmsg) { - dup = &Kvmsg{ - present: make([]bool, kvmsg_FRAMES), - frame: make([]string, kvmsg_FRAMES), - props: make([]string, len(kvmsg.props)), - } - copy(dup.present, kvmsg.present) - copy(dup.frame, kvmsg.frame) - copy(dup.props, kvmsg.props) - return -} - -// Return key from last read message, if any, else NULL -func (kvmsg *Kvmsg) GetKey() (key string, err error) { - if !kvmsg.present[frame_KEY] { - err = errors.New("Key not set") - return - } - key = kvmsg.frame[frame_KEY] - return -} - -func (kvmsg *Kvmsg) SetKey(key string) { - kvmsg.frame[frame_KEY] = key - kvmsg.present[frame_KEY] = true -} - -func (kvmsg *Kvmsg) GetSequence() (sequence int64, err error) { - if !kvmsg.present[frame_SEQ] { - err = errors.New("Sequence not set") - return - } - source := kvmsg.frame[frame_SEQ] - sequence = int64(source[0])<<56 + - int64(source[1])<<48 + - int64(source[2])<<40 + - int64(source[3])<<32 + - int64(source[4])<<24 + - int64(source[5])<<16 + - int64(source[6])<<8 + - int64(source[7]) - return -} - -func (kvmsg *Kvmsg) SetSequence(sequence int64) { - - source := make([]byte, 8) - source[0] = byte((sequence >> 56) & 255) - source[1] = byte((sequence >> 48) & 255) - source[2] = byte((sequence >> 40) & 255) - source[3] = byte((sequence >> 32) & 255) - source[4] = byte((sequence >> 24) & 255) - source[5] = byte((sequence >> 16) & 255) - source[6] = byte((sequence >> 8) & 255) - source[7] = byte((sequence) & 255) - - kvmsg.frame[frame_SEQ] = string(source) - kvmsg.present[frame_SEQ] = true -} - -func (kvmsg *Kvmsg) GetBody() (body string, err error) { - if !kvmsg.present[frame_BODY] { - err = errors.New("Body not set") - return - } - body = kvmsg.frame[frame_BODY] - return -} - -func (kvmsg *Kvmsg) SetBody(body string) { - kvmsg.frame[frame_BODY] = body - kvmsg.present[frame_BODY] = true -} - -// The size method returns the body size of the last-read message, if any. -func (kvmsg *Kvmsg) Size() int { - if kvmsg.present[frame_BODY] { - return len(kvmsg.frame[frame_BODY]) - } - return 0 -} - -func (kvmsg *Kvmsg) GetUuid() (uuid string, err error) { - if !kvmsg.present[frame_UUID] { - err = errors.New("Uuid not set") - return - } - uuid = kvmsg.frame[frame_UUID] - return -} - -// Sets the UUID to a random generated value -func (kvmsg *Kvmsg) SetUuid() { - kvmsg.frame[frame_UUID] = string(uuid.NewRandom()) // raw 16 bytes - kvmsg.present[frame_UUID] = true - -} - -// Get message property, return error if no such property is defined. -func (kvmsg *Kvmsg) GetProp(name string) (value string, err error) { - if !kvmsg.present[frame_PROPS] { - err = errors.New("No properties set") - return - } - f := name + "=" - for _, prop := range kvmsg.props { - if strings.HasPrefix(prop, f) { - value = prop[len(f):] - return - } - } - err = errors.New("Property not set") - return -} - -// Set message property. Property name cannot contain '='. -func (kvmsg *Kvmsg) SetProp(name, value string) (err error) { - if strings.Index(name, "=") >= 0 { - err = errors.New("No '=' allowed in property name") - return - } - p := name + "=" - for i, prop := range kvmsg.props { - if strings.HasPrefix(prop, p) { - kvmsg.props = append(kvmsg.props[:i], kvmsg.props[i+1:]...) - break - } - } - kvmsg.props = append(kvmsg.props, name+"="+value) - kvmsg.present[frame_PROPS] = true - return -} - -// The store method stores the key-value message into a hash map, unless -// the key is nil. -func (kvmsg *Kvmsg) Store(kvmap map[string]*Kvmsg) { - if kvmsg.present[frame_KEY] { - if kvmsg.present[frame_BODY] && kvmsg.frame[frame_BODY] != "" { - kvmap[kvmsg.frame[frame_KEY]] = kvmsg - } else { - delete(kvmap, kvmsg.frame[frame_KEY]) - } - } -} - -// The dump method extends the kvsimple implementation with support for -// message properties. -func (kvmsg *Kvmsg) Dump() { - size := kvmsg.Size() - body, _ := kvmsg.GetBody() - seq, _ := kvmsg.GetSequence() - key, _ := kvmsg.GetKey() - fmt.Fprintf(os.Stderr, "[seq:%v][key:%v][size:%v] ", seq, key, size) - p := "[" - for _, prop := range kvmsg.props { - fmt.Fprint(os.Stderr, p, prop) - p = ";" - } - if p == ";" { - fmt.Fprint(os.Stderr, "]") - } - for char_nbr := 0; char_nbr < size; char_nbr++ { - fmt.Fprintf(os.Stderr, "%02X", body[char_nbr]) - } - fmt.Fprintln(os.Stderr) -} - -// The test function is in kvmsg_test.go diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg/kvmsg_test.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg/kvmsg_test.go deleted file mode 100644 index 59b9fba..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvmsg/kvmsg_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package kvmsg - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "os" - "testing" -) - -// The test is the same as in kvsimple with added support -// for the uuid and property features of kvmsg - -func TestKvmsg(t *testing.T) { - - // Prepare our context and sockets - output, err := zmq.NewSocket(zmq.DEALER) - if err != nil { - t.Error(err) - } - - err = output.Bind("ipc://kvmsg_selftest.ipc") - if err != nil { - t.Error(err) - } - - input, err := zmq.NewSocket(zmq.DEALER) - if err != nil { - t.Error(err) - } - - err = input.Connect("ipc://kvmsg_selftest.ipc") - if err != nil { - t.Error(err) - } - - kvmap := make(map[string]*Kvmsg) - - // Test send and receive of simple message - kvmsg := NewKvmsg(1) - kvmsg.SetKey("key") - kvmsg.SetUuid() - kvmsg.SetBody("body") - kvmsg.Dump() - err = kvmsg.Send(output) - - kvmsg.Store(kvmap) - if err != nil { - t.Error(err) - } - - kvmsg, err = RecvKvmsg(input) - if err != nil { - t.Error(err) - } - kvmsg.Dump() - key, err := kvmsg.GetKey() - if err != nil { - t.Error(err) - } - if key != "key" { - t.Error("Expected \"key\", got \"" + key + "\"") - } - kvmsg.Store(kvmap) - - // Test send and receive of message with properties - kvmsg = NewKvmsg(2) - err = kvmsg.SetProp("prop1", "value1") - if err != nil { - t.Error(err) - } - kvmsg.SetProp("prop2", "value1") - kvmsg.SetProp("prop2", "value2") - kvmsg.SetKey("key") - kvmsg.SetUuid() - kvmsg.SetBody("body") - if val, err := kvmsg.GetProp("prop2"); err != nil || val != "value2" { - if err != nil { - t.Error(err) - } - t.Error("Expected \"prop2\" = \"value2\", got \"" + val + "\"") - } - kvmsg.Dump() - err = kvmsg.Send(output) - - kvmsg, err = RecvKvmsg(input) - if err != nil { - t.Error(err) - } - kvmsg.Dump() - key, err = kvmsg.GetKey() - if err != nil { - t.Error(err) - } - if key != "key" { - t.Error("Expected \"key\", got \"" + key + "\"") - } - prop, err := kvmsg.GetProp("prop2") - if err != nil { - t.Error(err) - } - if prop != "value2" { - t.Error("Expected property \"value2\", got \"" + key + "\"") - } - - input.Close() - output.Close() - os.Remove("kvmsg_selftest.ipc") -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple/kvsimple.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple/kvsimple.go deleted file mode 100644 index 3305070..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple/kvsimple.go +++ /dev/null @@ -1,157 +0,0 @@ -// kvsimple - simple key-value message class for example applications. -// -// This is a very much unlike typical Go. -package kvsimple - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "errors" - "fmt" - "os" -) - -const ( - frame_KEY = 0 - frame_SEQ = 1 - frame_BODY = 2 - kvmsg_FRAMES = 3 -) - -// The Kvmsg type holds a single key-value message consisting of a -// list of 0 or more frames. -type Kvmsg struct { - // Presence indicators for each frame - present []bool - // Corresponding 0MQ message frames, if any - frame []string -} - -// Constructor, takes a sequence number for the new Kvmsg instance. -func NewKvmsg(sequence int64) (kvmsg *Kvmsg) { - kvmsg = &Kvmsg{ - present: make([]bool, kvmsg_FRAMES), - frame: make([]string, kvmsg_FRAMES), - } - kvmsg.SetSequence(sequence) - return -} - -// The RecvKvmsg function reads a key-value message from socket, and returns a new -// Kvmsg instance. -func RecvKvmsg(socket *zmq.Socket) (kvmsg *Kvmsg, err error) { - kvmsg = &Kvmsg{ - present: make([]bool, kvmsg_FRAMES), - frame: make([]string, kvmsg_FRAMES), - } - msg, err := socket.RecvMessage(0) - if err != nil { - return - } - //fmt.Printf("Recv from %s: %q\n", socket, msg) - for i := 0; i < kvmsg_FRAMES && i < len(msg); i++ { - kvmsg.frame[i] = msg[i] - kvmsg.present[i] = true - } - return -} - -// The send method sends a multi-frame key-value message to a socket. -func (kvmsg *Kvmsg) Send(socket *zmq.Socket) (err error) { - //fmt.Printf("Send to %s: %q\n", socket, kvmsg.frame) - _, err = socket.SendMessage(kvmsg.frame) - return -} - -func (kvmsg *Kvmsg) GetKey() (key string, err error) { - if !kvmsg.present[frame_KEY] { - err = errors.New("Key not set") - return - } - key = kvmsg.frame[frame_KEY] - return -} - -func (kvmsg *Kvmsg) SetKey(key string) { - kvmsg.frame[frame_KEY] = key - kvmsg.present[frame_KEY] = true -} - -func (kvmsg *Kvmsg) GetSequence() (sequence int64, err error) { - if !kvmsg.present[frame_SEQ] { - err = errors.New("Sequence not set") - return - } - source := kvmsg.frame[frame_SEQ] - sequence = int64(source[0])<<56 + - int64(source[1])<<48 + - int64(source[2])<<40 + - int64(source[3])<<32 + - int64(source[4])<<24 + - int64(source[5])<<16 + - int64(source[6])<<8 + - int64(source[7]) - return -} - -func (kvmsg *Kvmsg) SetSequence(sequence int64) { - - source := make([]byte, 8) - source[0] = byte((sequence >> 56) & 255) - source[1] = byte((sequence >> 48) & 255) - source[2] = byte((sequence >> 40) & 255) - source[3] = byte((sequence >> 32) & 255) - source[4] = byte((sequence >> 24) & 255) - source[5] = byte((sequence >> 16) & 255) - source[6] = byte((sequence >> 8) & 255) - source[7] = byte((sequence) & 255) - - kvmsg.frame[frame_SEQ] = string(source) - kvmsg.present[frame_SEQ] = true -} - -func (kvmsg *Kvmsg) GetBody() (body string, err error) { - if !kvmsg.present[frame_BODY] { - err = errors.New("Body not set") - return - } - body = kvmsg.frame[frame_BODY] - return -} - -func (kvmsg *Kvmsg) SetBody(body string) { - kvmsg.frame[frame_BODY] = body - kvmsg.present[frame_BODY] = true -} - -// The size method returns the body size of the last-read message, if any. -func (kvmsg *Kvmsg) Size() int { - if kvmsg.present[frame_BODY] { - return len(kvmsg.frame[frame_BODY]) - } - return 0 -} - -// The store method stores the key-value message into a hash map, unless -// the key is nil. -func (kvmsg *Kvmsg) Store(kvmap map[string]*Kvmsg) { - if kvmsg.present[frame_KEY] { - kvmap[kvmsg.frame[frame_KEY]] = kvmsg - } -} - -// The dump method prints the key-value message to stderr, -// for debugging and tracing. -func (kvmsg *Kvmsg) Dump() { - size := kvmsg.Size() - body, _ := kvmsg.GetBody() - seq, _ := kvmsg.GetSequence() - key, _ := kvmsg.GetKey() - fmt.Fprintf(os.Stderr, "[seq:%v][key:%v][size:%v]", seq, key, size) - for char_nbr := 0; char_nbr < size; char_nbr++ { - fmt.Fprintf(os.Stderr, "%02X", body[char_nbr]) - } - fmt.Fprintln(os.Stderr) -} - -// The test function is in kvsimple_test.go diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple/kvsimple_test.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple/kvsimple_test.go deleted file mode 100644 index e03ed85..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/kvsimple/kvsimple_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package kvsimple - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "os" - "testing" -) - -func TestKvmsg(t *testing.T) { - - // Prepare our context and sockets - output, err := zmq.NewSocket(zmq.DEALER) - if err != nil { - t.Error(err) - } - - err = output.Bind("ipc://kvmsg_selftest.ipc") - if err != nil { - t.Error(err) - } - - input, err := zmq.NewSocket(zmq.DEALER) - if err != nil { - t.Error(err) - } - - err = input.Connect("ipc://kvmsg_selftest.ipc") - if err != nil { - t.Error(err) - } - - kvmap := make(map[string]*Kvmsg) - - // Test send and receive of simple message - kvmsg := NewKvmsg(1) - kvmsg.SetKey("key") - kvmsg.SetBody("body") - kvmsg.Dump() - err = kvmsg.Send(output) - - kvmsg.Store(kvmap) - if err != nil { - t.Error(err) - } - - kvmsg, err = RecvKvmsg(input) - if err != nil { - t.Error(err) - } - kvmsg.Dump() - key, err := kvmsg.GetKey() - if err != nil { - t.Error(err) - } - if key != "key" { - t.Error("Expected \"key\", got \"" + key + "\"") - } - kvmsg.Store(kvmap) - - input.Close() - output.Close() - os.Remove("kvmsg_selftest.ipc") -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker.go deleted file mode 100644 index f1c642e..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker.go +++ /dev/null @@ -1,188 +0,0 @@ -// -// Load-balancing broker. -// Clients and workers are shown here in-process -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - //"math/rand" - "time" -) - -const ( - NBR_CLIENTS = 10 - NBR_WORKERS = 3 -) - -// Basic request-reply client using REQ socket -// Since Go Send and Recv can handle 0MQ binary identities we -// don't need printable text identity to allow routing. - -func client_task() { - client, _ := zmq.NewSocket(zmq.REQ) - defer client.Close() - // set_id(client) // Set a printable identity - client.Connect("ipc://frontend.ipc") - - // Send request, get reply - client.Send("HELLO", 0) - reply, _ := client.Recv(0) - fmt.Println("Client:", reply) -} - -// While this example runs in a single process, that is just to make -// it easier to start and stop the example. -// This is the worker task, using a REQ socket to do load-balancing. -// Since Go Send and Recv can handle 0MQ binary identities we -// don't need printable text identity to allow routing. - -func worker_task() { - worker, _ := zmq.NewSocket(zmq.REQ) - defer worker.Close() - // set_id(worker) - worker.Connect("ipc://backend.ipc") - - // Tell broker we're ready for work - worker.Send("READY", 0) - - for { - // Read and save all frames until we get an empty frame - // In this example there is only 1 but it could be more - identity, _ := worker.Recv(0) - empty, _ := worker.Recv(0) - if empty != "" { - panic(fmt.Sprintf("empty is not \"\": %q", empty)) - } - - // Get request, send reply - request, _ := worker.Recv(0) - fmt.Println("Worker:", request) - - worker.Send(identity, zmq.SNDMORE) - worker.Send("", zmq.SNDMORE) - worker.Send("OK", 0) - } -} - -// This is the main task. It starts the clients and workers, and then -// routes requests between the two layers. Workers signal READY when -// they start; after that we treat them as ready when they reply with -// a response back to a client. The load-balancing data structure is -// just a queue of next available workers. - -func main() { - // Prepare our sockets - frontend, _ := zmq.NewSocket(zmq.ROUTER) - backend, _ := zmq.NewSocket(zmq.ROUTER) - defer frontend.Close() - defer backend.Close() - frontend.Bind("ipc://frontend.ipc") - backend.Bind("ipc://backend.ipc") - - client_nbr := 0 - for ; client_nbr < NBR_CLIENTS; client_nbr++ { - go client_task() - } - for worker_nbr := 0; worker_nbr < NBR_WORKERS; worker_nbr++ { - go worker_task() - } - - // Here is the main loop for the least-recently-used queue. It has two - // sockets; a frontend for clients and a backend for workers. It polls - // the backend in all cases, and polls the frontend only when there are - // one or more workers ready. This is a neat way to use 0MQ's own queues - // to hold messages we're not ready to process yet. When we get a client - // reply, we pop the next available worker, and send the request to it, - // including the originating client identity. When a worker replies, we - // re-queue that worker, and we forward the reply to the original client, - // using the reply envelope. - - // Queue of available workers - worker_queue := make([]string, 0, 10) - - poller1 := zmq.NewPoller() - poller1.Add(backend, zmq.POLLIN) - poller2 := zmq.NewPoller() - poller2.Add(backend, zmq.POLLIN) - poller2.Add(frontend, zmq.POLLIN) - - for client_nbr > 0 { - // Poll frontend only if we have available workers - var sockets []zmq.Polled - if len(worker_queue) > 0 { - sockets, _ = poller2.Poll(-1) - } else { - sockets, _ = poller1.Poll(-1) - } - for _, socket := range sockets { - switch socket.Socket { - case backend: - - // Handle worker activity on backend - // Queue worker identity for load-balancing - worker_id, _ := backend.Recv(0) - if !(len(worker_queue) < NBR_WORKERS) { - panic("!(len(worker_queue) < NBR_WORKERS)") - } - worker_queue = append(worker_queue, worker_id) - - // Second frame is empty - empty, _ := backend.Recv(0) - if empty != "" { - panic(fmt.Sprintf("empty is not \"\": %q", empty)) - } - - // Third frame is READY or else a client reply identity - client_id, _ := backend.Recv(0) - - // If client reply, send rest back to frontend - if client_id != "READY" { - empty, _ := backend.Recv(0) - if empty != "" { - panic(fmt.Sprintf("empty is not \"\": %q", empty)) - } - reply, _ := backend.Recv(0) - frontend.Send(client_id, zmq.SNDMORE) - frontend.Send("", zmq.SNDMORE) - frontend.Send(reply, 0) - client_nbr-- - } - - case frontend: - // Here is how we handle a client request: - - // Now get next client request, route to last-used worker - // Client request is [identity][empty][request] - client_id, _ := frontend.Recv(0) - empty, _ := frontend.Recv(0) - if empty != "" { - panic(fmt.Sprintf("empty is not \"\": %q", empty)) - } - request, _ := frontend.Recv(0) - - backend.Send(worker_queue[0], zmq.SNDMORE) - backend.Send("", zmq.SNDMORE) - backend.Send(client_id, zmq.SNDMORE) - backend.Send("", zmq.SNDMORE) - backend.Send(request, 0) - - // Dequeue and drop the next worker identity - worker_queue = worker_queue[1:] - - } - } - } - - time.Sleep(100 * time.Millisecond) -} - -/* -func set_id(soc *zmq.Socket) { - identity := fmt.Sprintf("%04X-%04X", rand.Intn(0x10000), rand.Intn(0x10000)) - soc.SetIdentity(identity) -} -*/ diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker2.go deleted file mode 100644 index 5e1ed8b..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker2.go +++ /dev/null @@ -1,147 +0,0 @@ -// -// Load-balancing broker. -// Demonstrates use of higher level functions. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "strings" - "time" -) - -const ( - NBR_CLIENTS = 10 - NBR_WORKERS = 3 - WORKER_READY = "\001" // Signals worker is ready -) - -// Basic request-reply client using REQ socket -// -func client_task() { - client, _ := zmq.NewSocket(zmq.REQ) - defer client.Close() - client.Connect("ipc://frontend.ipc") - - // Send request, get reply - for { - client.SendMessage("HELLO") - reply, _ := client.RecvMessage(0) - if len(reply) == 0 { - break - } - fmt.Println("Client:", strings.Join(reply, "\n\t")) - time.Sleep(time.Second) - } -} - -// Worker using REQ socket to do load-balancing -// -func worker_task() { - worker, _ := zmq.NewSocket(zmq.REQ) - defer worker.Close() - worker.Connect("ipc://backend.ipc") - - // Tell broker we're ready for work - worker.SendMessage(WORKER_READY) - - // Process messages as they arrive - for { - msg, e := worker.RecvMessage(0) - if e != nil { - break // Interrupted ?? - } - msg[len(msg)-1] = "OK" - worker.SendMessage(msg) - } -} - -// Now we come to the main task. This has the identical functionality to -// the previous lbbroker example but uses higher level functions to read -// and send messages: - -func main() { - // Prepare our sockets - frontend, _ := zmq.NewSocket(zmq.ROUTER) - backend, _ := zmq.NewSocket(zmq.ROUTER) - defer frontend.Close() - defer backend.Close() - frontend.Bind("ipc://frontend.ipc") - backend.Bind("ipc://backend.ipc") - - for client_nbr := 0; client_nbr < NBR_CLIENTS; client_nbr++ { - go client_task() - } - for worker_nbr := 0; worker_nbr < NBR_WORKERS; worker_nbr++ { - go worker_task() - } - - // Queue of available workers - workers := make([]string, 0, 10) - - poller1 := zmq.NewPoller() - poller1.Add(backend, zmq.POLLIN) - poller2 := zmq.NewPoller() - poller2.Add(backend, zmq.POLLIN) - poller2.Add(frontend, zmq.POLLIN) - -LOOP: - for { - // Poll frontend only if we have available workers - var sockets []zmq.Polled - var err error - if len(workers) > 0 { - sockets, err = poller2.Poll(-1) - } else { - sockets, err = poller1.Poll(-1) - } - if err != nil { - break // Interrupted - } - for _, socket := range sockets { - switch socket.Socket { - case backend: - // Handle worker activity on backend - - // Use worker identity for load-balancing - msg, err := backend.RecvMessage(0) - if err != nil { - break LOOP // Interrupted - } - identity, msg := unwrap(msg) - workers = append(workers, identity) - - // Forward message to client if it's not a READY - if msg[0] != WORKER_READY { - frontend.SendMessage(msg) - } - - case frontend: - // Get client request, route to first available worker - msg, err := frontend.RecvMessage(0) - if err == nil { - backend.SendMessage(workers[0], "", msg) - workers = workers[1:] - } - } - } - } - - time.Sleep(100 * time.Millisecond) -} - -// Pops frame off front of message and returns it as 'head' -// If next frame is empty, pops that empty frame. -// Return remaining frames of message as 'tail' -func unwrap(msg []string) (head string, tail []string) { - head = msg[0] - if len(msg) > 1 && msg[1] == "" { - tail = msg[2:] - } else { - tail = msg[1:] - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker3.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker3.go deleted file mode 100644 index 21a1b73..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lbbroker3.go +++ /dev/null @@ -1,157 +0,0 @@ -// -// Load-balancing broker. -// Demonstrates use of Reactor, and other higher level functions. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "strings" - "time" -) - -const ( - NBR_CLIENTS = 10 - NBR_WORKERS = 3 - WORKER_READY = "\001" // Signals worker is ready -) - -// Basic request-reply client using REQ socket -// -func client_task() { - client, _ := zmq.NewSocket(zmq.REQ) - defer client.Close() - client.Connect("ipc://frontend.ipc") - - // Send request, get reply - for { - client.SendMessage("HELLO") - reply, _ := client.RecvMessage(0) - if len(reply) == 0 { - break - } - fmt.Println("Client:", strings.Join(reply, "\n\t")) - time.Sleep(time.Second) - } -} - -// Worker using REQ socket to do load-balancing -// -func worker_task() { - worker, _ := zmq.NewSocket(zmq.REQ) - defer worker.Close() - worker.Connect("ipc://backend.ipc") - - // Tell broker we're ready for work - worker.SendMessage(WORKER_READY) - - // Process messages as they arrive - for { - msg, e := worker.RecvMessage(0) - if e != nil { - break // Interrupted - } - msg[len(msg)-1] = "OK" - worker.SendMessage(msg) - } -} - -// Our load-balancer structure, passed to reactor handlers -type lbbroker_t struct { - frontend *zmq.Socket // Listen to clients - backend *zmq.Socket // Listen to workers - workers []string // List of ready workers - reactor *zmq.Reactor -} - -// In the reactor design, each time a message arrives on a socket, the -// reactor passes it to a handler function. We have two handlers; one -// for the frontend, one for the backend: - -// Handle input from client, on frontend -func handle_frontend(lbbroker *lbbroker_t) error { - - // Get client request, route to first available worker - msg, err := lbbroker.frontend.RecvMessage(0) - if err != nil { - return err - } - lbbroker.backend.SendMessage(lbbroker.workers[0], "", msg) - lbbroker.workers = lbbroker.workers[1:] - - // Cancel reader on frontend if we went from 1 to 0 workers - if len(lbbroker.workers) == 0 { - lbbroker.reactor.RemoveSocket(lbbroker.frontend) - } - return nil -} - -// Handle input from worker, on backend -func handle_backend(lbbroker *lbbroker_t) error { - // Use worker identity for load-balancing - msg, err := lbbroker.backend.RecvMessage(0) - if err != nil { - return err - } - identity, msg := unwrap(msg) - lbbroker.workers = append(lbbroker.workers, identity) - - // Enable reader on frontend if we went from 0 to 1 workers - if len(lbbroker.workers) == 1 { - lbbroker.reactor.AddSocket(lbbroker.frontend, zmq.POLLIN, - func(e zmq.State) error { return handle_frontend(lbbroker) }) - } - - // Forward message to client if it's not a READY - if msg[0] != WORKER_READY { - lbbroker.frontend.SendMessage(msg) - } - - return nil -} - -// Now we come to the main task. This has the identical functionality to -// the previous lbbroker example but uses higher level functions to read -// and send messages: - -func main() { - lbbroker := &lbbroker_t{} - lbbroker.frontend, _ = zmq.NewSocket(zmq.ROUTER) - lbbroker.backend, _ = zmq.NewSocket(zmq.ROUTER) - defer lbbroker.frontend.Close() - defer lbbroker.backend.Close() - lbbroker.frontend.Bind("ipc://frontend.ipc") - lbbroker.backend.Bind("ipc://backend.ipc") - - for client_nbr := 0; client_nbr < NBR_CLIENTS; client_nbr++ { - go client_task() - } - for worker_nbr := 0; worker_nbr < NBR_WORKERS; worker_nbr++ { - go worker_task() - } - - // Queue of available workers - lbbroker.workers = make([]string, 0, 10) - - // Prepare reactor and fire it up - lbbroker.reactor = zmq.NewReactor() - lbbroker.reactor.AddSocket(lbbroker.backend, zmq.POLLIN, - func(e zmq.State) error { return handle_backend(lbbroker) }) - lbbroker.reactor.Run(-1) -} - -// Pops frame off front of message and returns it as 'head' -// If next frame is empty, pops that empty frame. -// Return remaining frames of message as 'tail' -func unwrap(msg []string) (head string, tail []string) { - head = msg[0] - if len(msg) > 1 && msg[1] == "" { - tail = msg[2:] - } else { - tail = msg[1:] - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lpclient.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lpclient.go deleted file mode 100644 index 417b23b..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lpclient.go +++ /dev/null @@ -1,88 +0,0 @@ -// -// Lazy Pirate client. -// Use zmq_poll to do a safe request-reply -// To run, start lpserver and then randomly kill/restart it -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "strconv" - "time" -) - -const ( - REQUEST_TIMEOUT = 2500 * time.Millisecond // msecs, (> 1000!) - REQUEST_RETRIES = 3 // Before we abandon - SERVER_ENDPOINT = "tcp://localhost:5555" -) - -func main() { - fmt.Println("I: connecting to server...") - client, err := zmq.NewSocket(zmq.REQ) - if err != nil { - panic(err) - } - client.Connect(SERVER_ENDPOINT) - - poller := zmq.NewPoller() - poller.Add(client, zmq.POLLIN) - - sequence := 0 - retries_left := REQUEST_RETRIES - for retries_left > 0 { - // We send a request, then we work to get a reply - sequence++ - client.SendMessage(sequence) - - for expect_reply := true; expect_reply; { - // Poll socket for a reply, with timeout - sockets, err := poller.Poll(REQUEST_TIMEOUT) - if err != nil { - break // Interrupted - } - - // Here we process a server reply and exit our loop if the - // reply is valid. If we didn't a reply we close the client - // socket and resend the request. We try a number of times - // before finally abandoning: - - if len(sockets) > 0 { - // We got a reply from the server, must match sequence - reply, err := client.RecvMessage(0) - if err != nil { - break // Interrupted - } - seq, _ := strconv.Atoi(reply[0]) - if seq == sequence { - fmt.Printf("I: server replied OK (%s)\n", reply[0]) - retries_left = REQUEST_RETRIES - expect_reply = false - } else { - fmt.Printf("E: malformed reply from server: %s\n", reply) - } - } else { - retries_left-- - if retries_left == 0 { - fmt.Println("E: server seems to be offline, abandoning") - break - } else { - fmt.Println("W: no response from server, retrying...") - // Old socket is confused; close it and open a new one - client.Close() - client, _ = zmq.NewSocket(zmq.REQ) - client.Connect(SERVER_ENDPOINT) - // Recreate poller for new client - poller = zmq.NewPoller() - poller.Add(client, zmq.POLLIN) - // Send request again, on new socket - client.SendMessage(sequence) - } - } - } - } - client.Close() -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lpserver.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lpserver.go deleted file mode 100644 index b1e2e87..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lpserver.go +++ /dev/null @@ -1,42 +0,0 @@ -// -// Lazy Pirate server. -// Binds REQ socket to tcp://*:5555 -// Like hwserver except: -// - echoes request as-is -// - randomly runs slowly, or exits to simulate a crash. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "time" -) - -func main() { - rand.Seed(time.Now().UnixNano()) - - server, _ := zmq.NewSocket(zmq.REP) - defer server.Close() - server.Bind("tcp://*:5555") - - for cycles := 0; true; { - request, _ := server.RecvMessage(0) - cycles++ - - // Simulate various problems, after a few cycles - if cycles > 3 && rand.Intn(3) == 0 { - fmt.Println("I: simulating a crash") - break - } else if cycles > 3 && rand.Intn(3) == 0 { - fmt.Println("I: simulating CPU overload") - time.Sleep(2 * time.Second) - } - fmt.Printf("I: normal request (%s)\n", request) - time.Sleep(time.Second) // Do some heavy work - server.SendMessage(request) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lvcache.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lvcache.go deleted file mode 100644 index c21e690..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/lvcache.go +++ /dev/null @@ -1,69 +0,0 @@ -// -// Last value cache -// Uses XPUB subscription messages to re-send data -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "time" -) - -func main() { - frontend, _ := zmq.NewSocket(zmq.SUB) - frontend.Bind("tcp://*:5557") - backend, _ := zmq.NewSocket(zmq.XPUB) - backend.Bind("tcp://*:5558") - - // Subscribe to every single topic from publisher - frontend.SetSubscribe("") - - // Store last instance of each topic in a cache - cache := make(map[string]string) - - // We route topic updates from frontend to backend, and - // we handle subscriptions by sending whatever we cached, - // if anything: - poller := zmq.NewPoller() - poller.Add(frontend, zmq.POLLIN) - poller.Add(backend, zmq.POLLIN) -LOOP: - for { - polled, err := poller.Poll(1000 * time.Millisecond) - if err != nil { - break // Interrupted - } - - for _, item := range polled { - switch socket := item.Socket; socket { - case frontend: - // Any new topic data we cache and then forward - msg, err := frontend.RecvMessage(0) - if err != nil { - break LOOP - } - cache[msg[0]] = msg[1] - backend.SendMessage(msg) - case backend: - // When we get a new subscription we pull data from the cache: - msg, err := backend.RecvMessage(0) - if err != nil { - break LOOP - } - frame := msg[0] - // Event is one byte 0=unsub or 1=sub, followed by topic - if frame[0] == 1 { - topic := frame[1:] - fmt.Println("Sending cached topic", topic) - previous, ok := cache[topic] - if ok { - backend.SendMessage(topic, previous) - } - } - } - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/const.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/const.go deleted file mode 100644 index 05fd08a..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/const.go +++ /dev/null @@ -1,30 +0,0 @@ -// Majordomo Protocol Client and Worker API. -// Implements the MDP/Worker spec at http://rfc.zeromq.org/spec:7. -package mdapi - -const ( - // This is the version of MDP/Client we implement - MDPC_CLIENT = "MDPC01" - - // This is the version of MDP/Worker we implement - MDPW_WORKER = "MDPW01" -) - -const ( - // MDP/Server commands, as strings - MDPW_READY = string(iota + 1) - MDPW_REQUEST - MDPW_REPLY - MDPW_HEARTBEAT - MDPW_DISCONNECT -) - -var ( - MDPS_COMMANDS = map[string]string{ - MDPW_READY: "READY", - MDPW_REQUEST: "REQUEST", - MDPW_REPLY: "REPLY", - MDPW_HEARTBEAT: "HEARTBEAT", - MDPW_DISCONNECT: "DISCONNECT", - } -) diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdcliapi.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdcliapi.go deleted file mode 100644 index 36e8ee7..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdcliapi.go +++ /dev/null @@ -1,173 +0,0 @@ -// Majordomo Protocol Client API. -// Implements the MDP/Worker spec at http://rfc.zeromq.org/spec:7. - -package mdapi - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "errors" - "log" - "runtime" - "time" -) - -// Structure of our class -// We access these properties only via class methods - -// Majordomo Protocol Client API. -type Mdcli struct { - broker string - client *zmq.Socket // Socket to broker - verbose bool // Print activity to stdout - timeout time.Duration // Request timeout - retries int // Request retries - poller *zmq.Poller -} - -// --------------------------------------------------------------------- - -// Connect or reconnect to broker. -func (mdcli *Mdcli) ConnectToBroker() (err error) { - if mdcli.client != nil { - mdcli.client.Close() - mdcli.client = nil - } - mdcli.client, err = zmq.NewSocket(zmq.REQ) - if err != nil { - if mdcli.verbose { - log.Println("E: ConnectToBroker() creating socket failed") - } - return - } - mdcli.poller = zmq.NewPoller() - mdcli.poller.Add(mdcli.client, zmq.POLLIN) - - if mdcli.verbose { - log.Printf("I: connecting to broker at %s...", mdcli.broker) - } - err = mdcli.client.Connect(mdcli.broker) - if err != nil && mdcli.verbose { - log.Println("E: ConnectToBroker() failed to connect to broker", mdcli.broker) - } - - return -} - -// Here we have the constructor and destructor for our mdcli class: - -// --------------------------------------------------------------------- -// Constructor - -func NewMdcli(broker string, verbose bool) (mdcli *Mdcli, err error) { - - mdcli = &Mdcli{ - broker: broker, - verbose: verbose, - timeout: time.Duration(2500 * time.Millisecond), - retries: 3, // Before we abandon - } - err = mdcli.ConnectToBroker() - runtime.SetFinalizer(mdcli, (*Mdcli).Close) - return -} - -// --------------------------------------------------------------------- -// Destructor - -func (mdcli *Mdcli) Close() (err error) { - if mdcli.client != nil { - err = mdcli.client.Close() - mdcli.client = nil - } - return -} - -// These are the class methods. We can set the request timeout and number -// of retry attempts, before sending requests: - -// --------------------------------------------------------------------- - -// Set request timeout. -func (mdcli *Mdcli) SetTimeout(timeout time.Duration) { - mdcli.timeout = timeout -} - -// --------------------------------------------------------------------- - -// Set request retries. -func (mdcli *Mdcli) SetRetries(retries int) { - mdcli.retries = retries -} - -// Here is the send method. It sends a request to the broker and gets a -// reply even if it has to retry several times. It returns the reply -// message, or error if there was no reply after multiple attempts: -func (mdcli *Mdcli) Send(service string, request ...string) (reply []string, err error) { - // Prefix request with protocol frames - // Frame 1: "MDPCxy" (six bytes, MDP/Client x.y) - // Frame 2: Service name (printable string) - - req := make([]string, 2, len(request)+2) - req = append(req, request...) - req[1] = service - req[0] = MDPC_CLIENT - if mdcli.verbose { - log.Printf("I: send request to '%s' service: %q\n", service, req) - } - for retries_left := mdcli.retries; retries_left > 0; retries_left-- { - _, err = mdcli.client.SendMessage(req) - if err != nil { - break - } - - // On any blocking call, libzmq will return -1 if there was - // an error; we could in theory check for different error codes - // but in practice it's OK to assume it was EINTR (Ctrl-C): - - var polled []zmq.Polled - polled, err = mdcli.poller.Poll(mdcli.timeout) - if err != nil { - break // Interrupted - } - - // If we got a reply, process it - if len(polled) > 0 { - var msg []string - msg, err = mdcli.client.RecvMessage(0) - if err != nil { - break - } - if mdcli.verbose { - log.Printf("I: received reply: %q\n", msg) - } - // We would handle malformed replies better in real code - if len(msg) < 3 { - panic("len(msg) < 3") - } - - if msg[0] != MDPC_CLIENT { - panic("msg[0] != MDPC_CLIENT") - } - - if msg[1] != service { - panic("msg[1] != service") - } - - reply = msg[2:] - return // Success - } else { - if mdcli.verbose { - log.Println("W: no reply, reconnecting...") - } - mdcli.ConnectToBroker() - } - } - if err == nil { - err = errors.New("permanent error") - } - if mdcli.verbose { - log.Println("W: permanent error, abandoning") - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdcliapi2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdcliapi2.go deleted file mode 100644 index 0a256fd..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdcliapi2.go +++ /dev/null @@ -1,171 +0,0 @@ -// Majordomo Protocol Client API. -// Implements the MDP/Worker spec at http://rfc.zeromq.org/spec:7. - -package mdapi - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "errors" - "log" - "runtime" - "time" -) - -var ( - errPermanent = errors.New("permanent error, abandoning request") -) - -// Structure of our class -// We access these properties only via class methods - -// Majordomo Protocol Client API. -type Mdcli2 struct { - broker string - client *zmq.Socket // Socket to broker - verbose bool // Print activity to stdout - timeout time.Duration // Request timeout - poller *zmq.Poller -} - -// --------------------------------------------------------------------- - -// Connect or reconnect to broker. In this asynchronous class we use a -// DEALER socket instead of a REQ socket; this lets us send any number -// of requests without waiting for a reply. -func (mdcli2 *Mdcli2) ConnectToBroker() (err error) { - if mdcli2.client != nil { - mdcli2.client.Close() - mdcli2.client = nil - } - mdcli2.client, err = zmq.NewSocket(zmq.DEALER) - if err != nil { - if mdcli2.verbose { - log.Println("E: ConnectToBroker() creating socket failed") - } - return - } - mdcli2.poller = zmq.NewPoller() - mdcli2.poller.Add(mdcli2.client, zmq.POLLIN) - - if mdcli2.verbose { - log.Printf("I: connecting to broker at %s...", mdcli2.broker) - } - err = mdcli2.client.Connect(mdcli2.broker) - if err != nil && mdcli2.verbose { - log.Println("E: ConnectToBroker() failed to connect to broker", mdcli2.broker) - } - - return -} - -// Here we have the constructor and destructor for our mdcli2 class: - -// The constructor and destructor are the same as in mdcliapi, except -// we don't do retries, so there's no retries property. -// --------------------------------------------------------------------- -// Constructor - -func NewMdcli2(broker string, verbose bool) (mdcli2 *Mdcli2, err error) { - - mdcli2 = &Mdcli2{ - broker: broker, - verbose: verbose, - timeout: time.Duration(2500 * time.Millisecond), - } - err = mdcli2.ConnectToBroker() - runtime.SetFinalizer(mdcli2, (*Mdcli2).Close) - return -} - -// --------------------------------------------------------------------- -// Destructor - -func (mdcli2 *Mdcli2) Close() (err error) { - if mdcli2.client != nil { - err = mdcli2.client.Close() - mdcli2.client = nil - } - return -} - -// --------------------------------------------------------------------- - -// Set request timeout. -func (mdcli2 *Mdcli2) SetTimeout(timeout time.Duration) { - mdcli2.timeout = timeout -} - -// The send method now just sends one message, without waiting for a -// reply. Since we're using a DEALER socket we have to send an empty -// frame at the start, to create the same envelope that the REQ socket -// would normally make for us: -func (mdcli2 *Mdcli2) Send(service string, request ...string) (err error) { - // Prefix request with protocol frames - // Frame 0: empty (REQ emulation) - // Frame 1: "MDPCxy" (six bytes, MDP/Client x.y) - // Frame 2: Service name (printable string) - - req := make([]string, 3, len(request)+3) - req = append(req, request...) - req[2] = service - req[1] = MDPC_CLIENT - req[0] = "" - if mdcli2.verbose { - log.Printf("I: send request to '%s' service: %q\n", service, req) - } - _, err = mdcli2.client.SendMessage(req) - return -} - -// The recv method waits for a reply message and returns that to the -// caller. -// --------------------------------------------------------------------- -// Returns the reply message or NULL if there was no reply. Does not -// attempt to recover from a broker failure, this is not possible -// without storing all unanswered requests and resending them all... - -func (mdcli2 *Mdcli2) Recv() (msg []string, err error) { - - msg = []string{} - - // Poll socket for a reply, with timeout - polled, err := mdcli2.poller.Poll(mdcli2.timeout) - if err != nil { - return // Interrupted - } - - // If we got a reply, process it - if len(polled) > 0 { - msg, err = mdcli2.client.RecvMessage(0) - if err != nil { - log.Println("W: interrupt received, killing client...") - return - } - - if mdcli2.verbose { - log.Printf("I: received reply: %q\n", msg) - } - // Don't try to handle errors, just assert noisily - if len(msg) < 4 { - panic("len(msg) < 4") - } - - if msg[0] != "" { - panic("msg[0] != \"\"") - } - - if msg[1] != MDPC_CLIENT { - panic("msg[1] != MDPC_CLIENT") - } - - msg = msg[3:] - return // Success - } - - err = errPermanent - if mdcli2.verbose { - log.Println(err) - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdwrkapi.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdwrkapi.go deleted file mode 100644 index aea5947..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi/mdwrkapi.go +++ /dev/null @@ -1,248 +0,0 @@ -// Majordomo Protocol Worker API. -// Implements the MDP/Worker spec at http://rfc.zeromq.org/spec:7. - -package mdapi - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "log" - "runtime" - "time" -) - -const ( - heartbeat_liveness = 3 // 3-5 is reasonable -) - -// This is the structure of a worker API instance. We use a pseudo-OO -// approach in a lot of the C examples, as well as the CZMQ binding: - -// Structure of our class -// We access these properties only via class methods - -// Majordomo Protocol Worker API. -type Mdwrk struct { - broker string - service string - worker *zmq.Socket // Socket to broker - poller *zmq.Poller - verbose bool // Print activity to stdout - - // Heartbeat management - heartbeat_at time.Time // When to send HEARTBEAT - liveness int // How many attempts left - heartbeat time.Duration // Heartbeat delay, msecs - reconnect time.Duration // Reconnect delay, msecs - - expect_reply bool // False only at start - reply_to string // Return identity, if any -} - -// We have two utility functions; to send a message to the broker and -// to (re-)connect to the broker: - -// --------------------------------------------------------------------- - -// Send message to broker. -func (mdwrk *Mdwrk) SendToBroker(command string, option string, msg []string) (err error) { - - n := 3 - if option != "" { - n++ - } - m := make([]string, n, n+len(msg)) - m = append(m, msg...) - - // Stack protocol envelope to start of message - if option != "" { - m[3] = option - } - m[2] = command - m[1] = MDPW_WORKER - m[0] = "" - - if mdwrk.verbose { - log.Printf("I: sending %s to broker %q\n", MDPS_COMMANDS[command], m) - } - _, err = mdwrk.worker.SendMessage(m) - return -} - -// --------------------------------------------------------------------- - -// Connect or reconnect to broker. -func (mdwrk *Mdwrk) ConnectToBroker() (err error) { - if mdwrk.worker != nil { - mdwrk.worker.Close() - mdwrk.worker = nil - } - mdwrk.worker, err = zmq.NewSocket(zmq.DEALER) - err = mdwrk.worker.Connect(mdwrk.broker) - if mdwrk.verbose { - log.Printf("I: connecting to broker at %s...\n", mdwrk.broker) - } - mdwrk.poller = zmq.NewPoller() - mdwrk.poller.Add(mdwrk.worker, zmq.POLLIN) - - // Register service with broker - err = mdwrk.SendToBroker(MDPW_READY, mdwrk.service, []string{}) - - // If liveness hits zero, queue is considered disconnected - mdwrk.liveness = heartbeat_liveness - mdwrk.heartbeat_at = time.Now().Add(mdwrk.heartbeat) - - return -} - -// Here we have the constructor and destructor for our mdwrk class: - -// --------------------------------------------------------------------- -// Constructor - -func NewMdwrk(broker, service string, verbose bool) (mdwrk *Mdwrk, err error) { - - mdwrk = &Mdwrk{ - broker: broker, - service: service, - verbose: verbose, - heartbeat: 2500 * time.Millisecond, - reconnect: 2500 * time.Millisecond, - } - - err = mdwrk.ConnectToBroker() - - runtime.SetFinalizer(mdwrk, (*Mdwrk).Close) - - return -} - -// --------------------------------------------------------------------- -// Destructor - -func (mdwrk *Mdwrk) Close() { - if mdwrk.worker != nil { - mdwrk.worker.Close() - mdwrk.worker = nil - } -} - -// We provide two methods to configure the worker API. You can set the -// heartbeat interval and retries to match the expected network performance. - -// --------------------------------------------------------------------- - -// Set heartbeat delay. -func (mdwrk *Mdwrk) SetHeartbeat(heartbeat time.Duration) { - mdwrk.heartbeat = heartbeat -} - -// --------------------------------------------------------------------- - -// Set reconnect delay. -func (mdwrk *Mdwrk) SetReconnect(reconnect time.Duration) { - mdwrk.reconnect = reconnect -} - -// This is the recv method; it's a little misnamed since it first sends -// any reply and then waits for a new request. If you have a better name -// for this, let me know: - -// --------------------------------------------------------------------- - -// Send reply, if any, to broker and wait for next request. -func (mdwrk *Mdwrk) Recv(reply []string) (msg []string, err error) { - // Format and send the reply if we were provided one - if len(reply) == 0 && mdwrk.expect_reply { - panic("No reply, expected") - } - if len(reply) > 0 { - if mdwrk.reply_to == "" { - panic("mdwrk.reply_to == \"\"") - } - m := make([]string, 2, 2+len(reply)) - m = append(m, reply...) - m[0] = mdwrk.reply_to - m[1] = "" - err = mdwrk.SendToBroker(MDPW_REPLY, "", m) - } - mdwrk.expect_reply = true - - for { - var polled []zmq.Polled - polled, err = mdwrk.poller.Poll(mdwrk.heartbeat) - if err != nil { - break // Interrupted - } - - if len(polled) > 0 { - msg, err = mdwrk.worker.RecvMessage(0) - if err != nil { - break // Interrupted - } - if mdwrk.verbose { - log.Printf("I: received message from broker: %q\n", msg) - } - mdwrk.liveness = heartbeat_liveness - - // Don't try to handle errors, just assert noisily - if len(msg) < 3 { - panic("len(msg) < 3") - } - - if msg[0] != "" { - panic("msg[0] != \"\"") - } - - if msg[1] != MDPW_WORKER { - panic("msg[1] != MDPW_WORKER") - } - - command := msg[2] - msg = msg[3:] - switch command { - case MDPW_REQUEST: - // We should pop and save as many addresses as there are - // up to a null part, but for now, just save one... - mdwrk.reply_to, msg = unwrap(msg) - // Here is where we actually have a message to process; we - // return it to the caller application: - return // We have a request to process - case MDPW_HEARTBEAT: - // Do nothing for heartbeats - case MDPW_DISCONNECT: - mdwrk.ConnectToBroker() - default: - log.Printf("E: invalid input message %q\n", msg) - } - } else { - mdwrk.liveness-- - if mdwrk.liveness == 0 { - if mdwrk.verbose { - log.Println("W: disconnected from broker - retrying...") - } - time.Sleep(mdwrk.reconnect) - mdwrk.ConnectToBroker() - } - } - // Send HEARTBEAT if it's time - if time.Now().After(mdwrk.heartbeat_at) { - mdwrk.SendToBroker(MDPW_HEARTBEAT, "", []string{}) - mdwrk.heartbeat_at = time.Now().Add(mdwrk.heartbeat) - } - } - return -} - -// Pops frame off front of message and returns it as 'head' -// If next frame is empty, pops that empty frame. -// Return remaining frames of message as 'tail' -func unwrap(msg []string) (head string, tail []string) { - head = msg[0] - if len(msg) > 1 && msg[1] == "" { - tail = msg[2:] - } else { - tail = msg[1:] - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdbroker.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdbroker.go deleted file mode 100644 index 3c70431..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdbroker.go +++ /dev/null @@ -1,426 +0,0 @@ -// -// Majordomo Protocol broker. -// A minimal Go implementation of the Majordomo Protocol as defined in -// http://rfc.zeromq.org/spec:7 and http://rfc.zeromq.org/spec:8. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi" - - "fmt" - "log" - "os" - "runtime" - "time" -) - -const ( - // We'd normally pull these from config data - - HEARTBEAT_LIVENESS = 3 // 3-5 is reasonable - HEARTBEAT_INTERVAL = 2500 * time.Millisecond // msecs - HEARTBEAT_EXPIRY = HEARTBEAT_INTERVAL * HEARTBEAT_LIVENESS -) - -// The broker class defines a single broker instance: - -type Broker struct { - socket *zmq.Socket // Socket for clients & workers - verbose bool // Print activity to stdout - endpoint string // Broker binds to this endpoint - services map[string]*Service // Hash of known services - workers map[string]*Worker // Hash of known workers - waiting []*Worker // List of waiting workers - heartbeat_at time.Time // When to send HEARTBEAT -} - -// The service class defines a single service instance: - -type Service struct { - broker *Broker // Broker instance - name string // Service name - requests [][]string // List of client requests - waiting []*Worker // List of waiting workers -} - -// The worker class defines a single worker, idle or active: - -type Worker struct { - broker *Broker // Broker instance - id_string string // Identity of worker as string - identity string // Identity frame for routing - service *Service // Owning service, if known - expiry time.Time // Expires at unless heartbeat -} - -// Here are the constructor and destructor for the broker: - -func NewBroker(verbose bool) (broker *Broker, err error) { - - // Initialize broker state - broker = &Broker{ - verbose: verbose, - services: make(map[string]*Service), - workers: make(map[string]*Worker), - waiting: make([]*Worker, 0), - heartbeat_at: time.Now().Add(HEARTBEAT_INTERVAL), - } - broker.socket, err = zmq.NewSocket(zmq.ROUTER) - - broker.socket.SetRcvhwm(500000) // or example mdclient2 won't work - - runtime.SetFinalizer(broker, (*Broker).Close) - return -} - -func (broker *Broker) Close() (err error) { - if broker.socket != nil { - err = broker.socket.Close() - broker.socket = nil - } - return -} - -// The bind method binds the broker instance to an endpoint. We can call -// this multiple times. Note that MDP uses a single socket for both clients -// and workers: - -func (broker *Broker) Bind(endpoint string) (err error) { - err = broker.socket.Bind(endpoint) - if err != nil { - log.Println("E: MDP broker/0.2.0 failed to bind at", endpoint) - return - } - log.Println("I: MDP broker/0.2.0 is active at", endpoint) - return -} - -// The WorkerMsg method processes one READY, REPLY, HEARTBEAT or -// DISCONNECT message sent to the broker by a worker: - -func (broker *Broker) WorkerMsg(sender string, msg []string) { - // At least, command - if len(msg) == 0 { - panic("len(msg) == 0") - } - - command, msg := popStr(msg) - id_string := fmt.Sprintf("%q", sender) - _, worker_ready := broker.workers[id_string] - worker := broker.WorkerRequire(sender) - - switch command { - case mdapi.MDPW_READY: - if worker_ready { // Not first command in session - worker.Delete(true) - } else if len(sender) >= 4 /* Reserved service name */ && sender[:4] == "mmi." { - worker.Delete(true) - } else { - // Attach worker to service and mark as idle - worker.service = broker.ServiceRequire(msg[0]) - worker.Waiting() - } - case mdapi.MDPW_REPLY: - if worker_ready { - // Remove & save client return envelope and insert the - // protocol header and service name, then rewrap envelope. - client, msg := unwrap(msg) - broker.socket.SendMessage(client, "", mdapi.MDPC_CLIENT, worker.service.name, msg) - worker.Waiting() - } else { - worker.Delete(true) - } - case mdapi.MDPW_HEARTBEAT: - if worker_ready { - worker.expiry = time.Now().Add(HEARTBEAT_EXPIRY) - } else { - worker.Delete(true) - } - case mdapi.MDPW_DISCONNECT: - worker.Delete(false) - default: - log.Printf("E: invalid input message %q\n", msg) - } -} - -// Process a request coming from a client. We implement MMI requests -// directly here (at present, we implement only the mmi.service request): - -func (broker *Broker) ClientMsg(sender string, msg []string) { - // Service name + body - if len(msg) < 2 { - panic("len(msg) < 2") - } - - service_frame, msg := popStr(msg) - service := broker.ServiceRequire(service_frame) - - // Set reply return identity to client sender - m := []string{sender, ""} - msg = append(m, msg...) - - // If we got a MMI service request, process that internally - if len(service_frame) >= 4 && service_frame[:4] == "mmi." { - var return_code string - if service_frame == "mmi.service" { - name := msg[len(msg)-1] - service, ok := broker.services[name] - if ok && len(service.waiting) > 0 { - return_code = "200" - } else { - return_code = "404" - } - } else { - return_code = "501" - } - - msg[len(msg)-1] = return_code - - // Remove & save client return envelope and insert the - // protocol header and service name, then rewrap envelope. - client, msg := unwrap(msg) - broker.socket.SendMessage(client, "", mdapi.MDPC_CLIENT, service_frame, msg) - } else { - // Else dispatch the message to the requested service - service.Dispatch(msg) - } -} - -// The purge method deletes any idle workers that haven't pinged us in a -// while. We hold workers from oldest to most recent, so we can stop -// scanning whenever we find a live worker. This means we'll mainly stop -// at the first worker, which is essential when we have large numbers of -// workers (since we call this method in our critical path): - -func (broker *Broker) Purge() { - now := time.Now() - for len(broker.waiting) > 0 { - if broker.waiting[0].expiry.After(now) { - break // Worker is alive, we're done here - } - if broker.verbose { - log.Println("I: deleting expired worker:", broker.waiting[0].id_string) - } - broker.waiting[0].Delete(false) - } -} - -// Here is the implementation of the methods that work on a service: - -// Lazy constructor that locates a service by name, or creates a new -// service if there is no service already with that name. - -func (broker *Broker) ServiceRequire(service_frame string) (service *Service) { - name := service_frame - service, ok := broker.services[name] - if !ok { - service = &Service{ - broker: broker, - name: name, - requests: make([][]string, 0), - waiting: make([]*Worker, 0), - } - broker.services[name] = service - if broker.verbose { - log.Println("I: added service:", name) - } - } - return -} - -// The dispatch method sends requests to waiting workers: - -func (service *Service) Dispatch(msg []string) { - - if len(msg) > 0 { - // Queue message if any - service.requests = append(service.requests, msg) - } - - service.broker.Purge() - for len(service.waiting) > 0 && len(service.requests) > 0 { - var worker *Worker - worker, service.waiting = popWorker(service.waiting) - service.broker.waiting = delWorker(service.broker.waiting, worker) - msg, service.requests = popMsg(service.requests) - worker.Send(mdapi.MDPW_REQUEST, "", msg) - } -} - -// Here is the implementation of the methods that work on a worker: - -// Lazy constructor that locates a worker by identity, or creates a new -// worker if there is no worker already with that identity. - -func (broker *Broker) WorkerRequire(identity string) (worker *Worker) { - - // broker.workers is keyed off worker identity - id_string := fmt.Sprintf("%q", identity) - worker, ok := broker.workers[id_string] - if !ok { - worker = &Worker{ - broker: broker, - id_string: id_string, - identity: identity, - } - broker.workers[id_string] = worker - if broker.verbose { - log.Printf("I: registering new worker: %s\n", id_string) - } - } - return -} - -// The delete method deletes the current worker. - -func (worker *Worker) Delete(disconnect bool) { - if disconnect { - worker.Send(mdapi.MDPW_DISCONNECT, "", []string{}) - } - - if worker.service != nil { - worker.service.waiting = delWorker(worker.service.waiting, worker) - } - worker.broker.waiting = delWorker(worker.broker.waiting, worker) - delete(worker.broker.workers, worker.id_string) -} - -// The send method formats and sends a command to a worker. The caller may -// also provide a command option, and a message payload: - -func (worker *Worker) Send(command, option string, msg []string) (err error) { - n := 4 - if option != "" { - n++ - } - m := make([]string, n, n+len(msg)) - m = append(m, msg...) - - // Stack protocol envelope to start of message - if option != "" { - m[4] = option - } - m[3] = command - m[2] = mdapi.MDPW_WORKER - - // Stack routing envelope to start of message - m[1] = "" - m[0] = worker.identity - - if worker.broker.verbose { - log.Printf("I: sending %s to worker %q\n", mdapi.MDPS_COMMANDS[command], m) - } - _, err = worker.broker.socket.SendMessage(m) - return -} - -// This worker is now waiting for work - -func (worker *Worker) Waiting() { - // Queue to broker and service waiting lists - worker.broker.waiting = append(worker.broker.waiting, worker) - worker.service.waiting = append(worker.service.waiting, worker) - worker.expiry = time.Now().Add(HEARTBEAT_EXPIRY) - worker.service.Dispatch([]string{}) -} - -// Finally here is the main task. We create a new broker instance and -// then processes messages on the broker socket: - -func main() { - verbose := false - if len(os.Args) > 1 && os.Args[1] == "-v" { - verbose = true - } - - broker, _ := NewBroker(verbose) - broker.Bind("tcp://*:5555") - - poller := zmq.NewPoller() - poller.Add(broker.socket, zmq.POLLIN) - - // Get and process messages forever or until interrupted - for { - polled, err := poller.Poll(HEARTBEAT_INTERVAL) - if err != nil { - break // Interrupted - } - - // Process next input message, if any - if len(polled) > 0 { - msg, err := broker.socket.RecvMessage(0) - if err != nil { - break // Interrupted - } - if broker.verbose { - log.Printf("I: received message: %q\n", msg) - } - sender, msg := popStr(msg) - _, msg = popStr(msg) - header, msg := popStr(msg) - - switch header { - case mdapi.MDPC_CLIENT: - broker.ClientMsg(sender, msg) - case mdapi.MDPW_WORKER: - broker.WorkerMsg(sender, msg) - default: - log.Printf("E: invalid message: %q\n", msg) - } - } - // Disconnect and delete any expired workers - // Send heartbeats to idle workers if needed - if time.Now().After(broker.heartbeat_at) { - broker.Purge() - for _, worker := range broker.waiting { - worker.Send(mdapi.MDPW_HEARTBEAT, "", []string{}) - } - broker.heartbeat_at = time.Now().Add(HEARTBEAT_INTERVAL) - } - } - log.Println("W: interrupt received, shutting down...") -} - -// Pops frame off front of message and returns it as 'head' -// If next frame is empty, pops that empty frame. -// Return remaining frames of message as 'tail' -func unwrap(msg []string) (head string, tail []string) { - head = msg[0] - if len(msg) > 1 && msg[1] == "" { - tail = msg[2:] - } else { - tail = msg[1:] - } - return -} - -func popStr(ss []string) (s string, ss2 []string) { - s = ss[0] - ss2 = ss[1:] - return -} - -func popMsg(msgs [][]string) (msg []string, msgs2 [][]string) { - msg = msgs[0] - msgs2 = msgs[1:] - return -} - -func popWorker(workers []*Worker) (worker *Worker, workers2 []*Worker) { - worker = workers[0] - workers2 = workers[1:] - return -} - -func delWorker(workers []*Worker, worker *Worker) []*Worker { - for i := 0; i < len(workers); i++ { - if workers[i] == worker { - workers = append(workers[:i], workers[i+1:]...) - i-- - } - } - return workers -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdclient.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdclient.go deleted file mode 100644 index 56617cd..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdclient.go +++ /dev/null @@ -1,32 +0,0 @@ -// -// Majordomo Protocol client example. -// Uses the mdcli API to hide all MDP aspects -// - -package main - -import ( - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi" - - "fmt" - "log" - "os" -) - -func main() { - var verbose bool - if len(os.Args) > 1 && os.Args[1] == "-v" { - verbose = true - } - session, _ := mdapi.NewMdcli("tcp://localhost:5555", verbose) - - count := 0 - for ; count < 100000; count++ { - _, err := session.Send("echo", "Hello world") - if err != nil { - log.Println(err) - break // Interrupt or failure - } - } - fmt.Printf("%d requests/replies processed\n", count) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdclient2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdclient2.go deleted file mode 100644 index 88fc47c..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdclient2.go +++ /dev/null @@ -1,39 +0,0 @@ -// -// Majordomo Protocol client example - asynchronous. -// Uses the mdcli API to hide all MDP aspects -// - -package main - -import ( - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi" - - "fmt" - "log" - "os" -) - -func main() { - var verbose bool - if len(os.Args) > 1 && os.Args[1] == "-v" { - verbose = true - } - session, _ := mdapi.NewMdcli2("tcp://localhost:5555", verbose) - - var count int - for count = 0; count < 100000; count++ { - err := session.Send("echo", "Hello world") - if err != nil { - log.Println("Send:", err) - break - } - } - for count = 0; count < 100000; count++ { - _, err := session.Recv() - if err != nil { - log.Println("Recv:", err) - break - } - } - fmt.Printf("%d replies received\n", count) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdworker.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdworker.go deleted file mode 100644 index b6d06ba..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdworker.go +++ /dev/null @@ -1,32 +0,0 @@ -// -// Majordomo Protocol worker example. -// Uses the mdwrk API to hide all MDP aspects -// - -package main - -import ( - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi" - - "log" - "os" -) - -func main() { - var verbose bool - if len(os.Args) > 1 && os.Args[1] == "-v" { - verbose = true - } - session, _ := mdapi.NewMdwrk("tcp://localhost:5555", "echo", verbose) - - var err error - var request, reply []string - for { - request, err = session.Recv(reply) - if err != nil { - break // Worker was interrupted - } - reply = request // Echo is complex... :-) - } - log.Println(err) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mmiecho.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mmiecho.go deleted file mode 100644 index e577069..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mmiecho.go +++ /dev/null @@ -1,32 +0,0 @@ -// -// MMI echo query example. -// - -package main - -import ( - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi" - - "fmt" - "os" -) - -func main() { - var verbose bool - if len(os.Args) > 1 && os.Args[1] == "-v" { - verbose = true - } - session, _ := mdapi.NewMdcli("tcp://localhost:5555", verbose) - - // This is the service we want to look up - request := "echo" - - // This is the service we send our request to - reply, err := session.Send("mmi.service", request) - - if err == nil { - fmt.Println("Lookup echo service:", reply[0]) - } else { - fmt.Println("E: no response from broker, make sure it's running") - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/msgqueue.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/msgqueue.go deleted file mode 100644 index d0a59ce..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/msgqueue.go +++ /dev/null @@ -1,36 +0,0 @@ -// -// Simple message queuing broker. -// Same as request-reply broker but using QUEUE device -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "log" -) - -func main() { - var err error - - // Socket facing clients - frontend, _ := zmq.NewSocket(zmq.ROUTER) - defer frontend.Close() - err = frontend.Bind("tcp://*:5559") - if err != nil { - log.Fatalln("Binding frontend:", err) - } - - // Socket facing services - backend, _ := zmq.NewSocket(zmq.DEALER) - defer backend.Close() - err = backend.Bind("tcp://*:5560") - if err != nil { - log.Fatalln("Binding backend:", err) - } - - // Start the proxy - err = zmq.Proxy(frontend, backend, nil) - log.Fatalln("Proxy interrupted:", err) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mspoller.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mspoller.go deleted file mode 100644 index a38c030..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mspoller.go +++ /dev/null @@ -1,47 +0,0 @@ -// -// Reading from multiple sockets. -// This version uses zmq.Poll() -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" -) - -func main() { - - // Connect to task ventilator - receiver, _ := zmq.NewSocket(zmq.PULL) - defer receiver.Close() - receiver.Connect("tcp://localhost:5557") - - // Connect to weather server - subscriber, _ := zmq.NewSocket(zmq.SUB) - defer subscriber.Close() - subscriber.Connect("tcp://localhost:5556") - subscriber.SetSubscribe("10001 ") - - // Initialize poll set - poller := zmq.NewPoller() - poller.Add(receiver, zmq.POLLIN) - poller.Add(subscriber, zmq.POLLIN) - // Process messages from both sockets - for { - sockets, _ := poller.Poll(-1) - for _, socket := range sockets { - switch s := socket.Socket; s { - case receiver: - task, _ := s.Recv(0) - // Process task - fmt.Println("Got task:", task) - case subscriber: - update, _ := s.Recv(0) - // Process weather update - fmt.Println("Got weather update:", update) - } - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/msreader.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/msreader.go deleted file mode 100644 index f54847d..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/msreader.go +++ /dev/null @@ -1,55 +0,0 @@ -// -// Reading from multiple sockets. -// This version uses a simple recv loop -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "time" -) - -func main() { - - // Connect to task ventilator - receiver, _ := zmq.NewSocket(zmq.PULL) - defer receiver.Close() - receiver.Connect("tcp://localhost:5557") - - // Connect to weather server - subscriber, _ := zmq.NewSocket(zmq.SUB) - defer subscriber.Close() - subscriber.Connect("tcp://localhost:5556") - subscriber.SetSubscribe("10001 ") - - // Process messages from both sockets - // We prioritize traffic from the task ventilator - for { - - // Process any waiting tasks - for { - task, err := receiver.Recv(zmq.DONTWAIT) - if err != nil { - break - } - // process task - fmt.Println("Got task:", task) - } - - // Process any waiting weather updates - for { - udate, err := subscriber.Recv(zmq.DONTWAIT) - if err != nil { - break - } - // process weather update - fmt.Println("Got weather update:", udate) - } - - // No activity, so sleep for 1 msec - time.Sleep(time.Millisecond) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mtrelay.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mtrelay.go deleted file mode 100644 index fd13462..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mtrelay.go +++ /dev/null @@ -1,52 +0,0 @@ -// -// Multithreaded relay. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" -) - -func step1() { - // Connect to step2 and tell it we're ready - xmitter, _ := zmq.NewSocket(zmq.PAIR) - defer xmitter.Close() - xmitter.Connect("inproc://step2") - fmt.Println("Step 1 ready, signaling step 2") - xmitter.Send("READY", 0) -} - -func step2() { - // Bind inproc socket before starting step1 - receiver, _ := zmq.NewSocket(zmq.PAIR) - defer receiver.Close() - receiver.Bind("inproc://step2") - go step1() - - // Wait for signal and pass it on - receiver.Recv(0) - - // Connect to step3 and tell it we're ready - xmitter, _ := zmq.NewSocket(zmq.PAIR) - defer xmitter.Close() - xmitter.Connect("inproc://step3") - fmt.Println("Step 2 ready, signaling step 3") - xmitter.Send("READY", 0) -} - -func main() { - - // Bind inproc socket before starting step2 - receiver, _ := zmq.NewSocket(zmq.PAIR) - defer receiver.Close() - receiver.Bind("inproc://step3") - go step2() - - // Wait for signal - receiver.Recv(0) - - fmt.Println("Test successful!") -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mtserver.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mtserver.go deleted file mode 100644 index 53cccdb..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mtserver.go +++ /dev/null @@ -1,54 +0,0 @@ -// -// Multithreaded Hello World server. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" - "time" -) - -func worker_routine() { - // Socket to talk to dispatcher - receiver, _ := zmq.NewSocket(zmq.REP) - defer receiver.Close() - receiver.Connect("inproc://workers") - - for { - msg, e := receiver.Recv(0) - if e != nil { - break - } - fmt.Println("Received request: [" + msg + "]") - - // Do some 'work' - time.Sleep(time.Second) - - // Send reply back to client - receiver.Send("World", 0) - } -} - -func main() { - // Socket to talk to clients - clients, _ := zmq.NewSocket(zmq.ROUTER) - defer clients.Close() - clients.Bind("tcp://*:5555") - - // Socket to talk to workers - workers, _ := zmq.NewSocket(zmq.DEALER) - defer workers.Close() - workers.Bind("inproc://workers") - - // Launch pool of worker goroutines - for thread_nbr := 0; thread_nbr < 5; thread_nbr++ { - go worker_routine() - } - // Connect work threads to client threads via a queue proxy - err := zmq.Proxy(clients, workers, nil) - log.Fatalln("Proxy interrupted:", err) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/pathopub.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/pathopub.go deleted file mode 100644 index 91810ca..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/pathopub.go +++ /dev/null @@ -1,44 +0,0 @@ -// -// Pathological publisher -// Sends out 1,000 topics and then one random update per second -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "os" - "time" -) - -func main() { - publisher, _ := zmq.NewSocket(zmq.PUB) - if len(os.Args) == 2 { - publisher.Connect(os.Args[1]) - } else { - publisher.Bind("tcp://*:5556") - } - - // Ensure subscriber connection has time to complete - time.Sleep(time.Second) - - // Send out all 1,000 topic messages - for topic_nbr := 0; topic_nbr < 1000; topic_nbr++ { - _, err := publisher.SendMessage(fmt.Sprintf("%03d", topic_nbr), "Save Roger") - if err != nil { - fmt.Println(err) - } - } - // Send one random update per second - rand.Seed(time.Now().UnixNano()) - for { - time.Sleep(time.Second) - _, err := publisher.SendMessage(fmt.Sprintf("%03d", rand.Intn(1000)), "Off with his head!") - if err != nil { - fmt.Println(err) - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/pathosub.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/pathosub.go deleted file mode 100644 index 15e5b68..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/pathosub.go +++ /dev/null @@ -1,41 +0,0 @@ -// -// Pathological subscriber -// Subscribes to one random topic and prints received messages -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "os" - "time" -) - -func main() { - subscriber, _ := zmq.NewSocket(zmq.SUB) - if len(os.Args) == 2 { - subscriber.Connect(os.Args[1]) - } else { - subscriber.Connect("tcp://localhost:5556") - } - - rand.Seed(time.Now().UnixNano()) - subscription := fmt.Sprintf("%03d", rand.Intn(1000)) - subscriber.SetSubscribe(subscription) - - for { - msg, err := subscriber.RecvMessage(0) - if err != nil { - break - } - topic := msg[0] - data := msg[1] - if topic != subscription { - panic("topic != subscription") - } - fmt.Println(data) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering1.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering1.go deleted file mode 100644 index c99ced8..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering1.go +++ /dev/null @@ -1,66 +0,0 @@ -// -// Broker peering simulation (part 1). -// Prototypes the state flow -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "os" - "time" -) - -func main() { - // First argument is this broker's name - // Other arguments are our peers' names - // - if len(os.Args) < 2 { - fmt.Println("syntax: peering1 me {you}...") - os.Exit(1) - } - self := os.Args[1] - fmt.Printf("I: preparing broker at %s...\n", self) - rand.Seed(time.Now().UnixNano()) - - // Bind state backend to endpoint - statebe, _ := zmq.NewSocket(zmq.PUB) - defer statebe.Close() - statebe.Bind("ipc://" + self + "-state.ipc") - - // Connect statefe to all peers - statefe, _ := zmq.NewSocket(zmq.SUB) - defer statefe.Close() - statefe.SetSubscribe("") - for _, peer := range os.Args[2:] { - fmt.Printf("I: connecting to state backend at '%s'\n", peer) - statefe.Connect("ipc://" + peer + "-state.ipc") - } - - // The main loop sends out status messages to peers, and collects - // status messages back from peers. The zmq_poll timeout defines - // our own heartbeat: - - poller := zmq.NewPoller() - poller.Add(statefe, zmq.POLLIN) - for { - // Poll for activity, or 1 second timeout - sockets, err := poller.Poll(time.Second) - if err != nil { - break - } - - // Handle incoming status messages - if len(sockets) == 1 { - msg, _ := statefe.RecvMessage(0) - peer_name := msg[0] - available := msg[1] - fmt.Printf("%s - %s workers free\n", peer_name, available) - } else { - statebe.SendMessage(self, rand.Intn(10)) - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering2.go deleted file mode 100644 index e8fb84c..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering2.go +++ /dev/null @@ -1,264 +0,0 @@ -// -// Broker peering simulation (part 2). -// Prototypes the request-reply flow -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" - "math/rand" - "os" - "time" -) - -const ( - NBR_CLIENTS = 10 - NBR_WORKERS = 3 - WORKER_READY = "**READY**" // Signals worker is ready -) - -var ( - peers = make(map[string]bool) -) - -// The client task does a request-reply dialog using a standard -// synchronous REQ socket: - -func client_task(name string, i int) { - clientname := fmt.Sprintf("Client-%s-%d", name, i) - - client, _ := zmq.NewSocket(zmq.REQ) - defer client.Close() - client.SetIdentity(clientname) - client.Connect("ipc://" + name + "-localfe.ipc") - - for { - // Send request, get reply - client.Send("HELLO from "+clientname, 0) - reply, err := client.Recv(0) - if err != nil { - fmt.Println("client_task interrupted", name) - break // Interrupted - } - fmt.Printf("%s: %s\n", clientname, reply) - time.Sleep(time.Duration(500+rand.Intn(1000)) * time.Millisecond) - } -} - -// The worker task plugs into the load-balancer using a REQ -// socket: - -func worker_task(name string, i int) { - workername := fmt.Sprintf("Worker-%s-%d", name, i) - - worker, _ := zmq.NewSocket(zmq.REQ) - defer worker.Close() - worker.SetIdentity(workername) - worker.Connect("ipc://" + name + "-localbe.ipc") - - // Tell broker we're ready for work - worker.SendMessage(WORKER_READY) - - // Process messages as they arrive - for { - msg, err := worker.RecvMessage(0) - if err != nil { - fmt.Println("worker_task interrupted", name) - break // Interrupted - } - - i := len(msg) - 1 - fmt.Printf("%s: %s\n", workername, msg[i]) - worker.SendMessage(msg[:i], "OK from "+workername) - } -} - -// The main task begins by setting-up its frontend and backend sockets -// and then starting its client and worker tasks: - -func main() { - // First argument is this broker's name - // Other arguments are our peers' names - // - if len(os.Args) < 2 { - fmt.Println("syntax: peering2 me {you}...") - os.Exit(1) - } - for _, peer := range os.Args[2:] { - peers[peer] = true - } - - self := os.Args[1] - fmt.Println("I: preparing broker at", self) - rand.Seed(time.Now().UnixNano()) - - // Bind cloud frontend to endpoint - cloudfe, _ := zmq.NewSocket(zmq.ROUTER) - defer cloudfe.Close() - cloudfe.SetIdentity(self) - cloudfe.Bind("ipc://" + self + "-cloud.ipc") - - // Connect cloud backend to all peers - cloudbe, _ := zmq.NewSocket(zmq.ROUTER) - defer cloudbe.Close() - cloudbe.SetIdentity(self) - for _, peer := range os.Args[2:] { - fmt.Println("I: connecting to cloud frontend at", peer) - cloudbe.Connect("ipc://" + peer + "-cloud.ipc") - } - // Prepare local frontend and backend - localfe, _ := zmq.NewSocket(zmq.ROUTER) - defer localfe.Close() - localfe.Bind("ipc://" + self + "-localfe.ipc") - localbe, _ := zmq.NewSocket(zmq.ROUTER) - defer localbe.Close() - localbe.Bind("ipc://" + self + "-localbe.ipc") - - // Get user to tell us when we can start... - fmt.Print("Press Enter when all brokers are started: ") - var line string - fmt.Scanln(&line) - - // Start local workers - for worker_nbr := 0; worker_nbr < NBR_WORKERS; worker_nbr++ { - go worker_task(self, worker_nbr) - } - - // Start local clients - for client_nbr := 0; client_nbr < NBR_CLIENTS; client_nbr++ { - go client_task(self, client_nbr) - } - - // Here we handle the request-reply flow. We're using load-balancing - // to poll workers at all times, and clients only when there are one or - // more workers available. - - // Least recently used queue of available workers - workers := make([]string, 0) - - backends := zmq.NewPoller() - backends.Add(localbe, zmq.POLLIN) - backends.Add(cloudbe, zmq.POLLIN) - frontends := zmq.NewPoller() - frontends.Add(localfe, zmq.POLLIN) - frontends.Add(cloudfe, zmq.POLLIN) - - msg := []string{} - number_of_peers := len(os.Args) - 2 - - for { - // First, route any waiting replies from workers - // If we have no workers anyhow, wait indefinitely - timeout := time.Second - if len(workers) == 0 { - timeout = -1 - } - sockets, err := backends.Poll(timeout) - if err != nil { - log.Println(err) - break // Interrupted - } - - msg = msg[:] - if socketInPolled(localbe, sockets) { - // Handle reply from local worker - msg, err = localbe.RecvMessage(0) - if err != nil { - log.Println(err) - break // Interrupted - } - var identity string - identity, msg = unwrap(msg) - workers = append(workers, identity) - - // If it's READY, don't route the message any further - if msg[0] == WORKER_READY { - msg = msg[0:0] - } - } else if socketInPolled(cloudbe, sockets) { - // Or handle reply from peer broker - msg, err = cloudbe.RecvMessage(0) - if err != nil { - log.Println(err) - break // Interrupted - } - - // We don't use peer broker identity for anything - _, msg = unwrap(msg) - } - - if len(msg) > 0 { - // Route reply to cloud if it's addressed to a broker - if peers[msg[0]] { - cloudfe.SendMessage(msg) - } else { - localfe.SendMessage(msg) - } - } - - // Now we route as many client requests as we have worker capacity - // for. We may reroute requests from our local frontend, but not from - // the cloud frontend. We reroute randomly now, just to test things - // out. In the next version we'll do this properly by calculating - // cloud capacity: - - for len(workers) > 0 { - sockets, err := frontends.Poll(0) - if err != nil { - log.Println(err) - break // Interrupted - } - var reroutable bool - // We'll do peer brokers first, to prevent starvation - if socketInPolled(cloudfe, sockets) { - msg, _ = cloudfe.RecvMessage(0) - reroutable = false - } else if socketInPolled(localfe, sockets) { - msg, _ = localfe.RecvMessage(0) - reroutable = true - } else { - break // No work, go back to backends - } - - // If reroutable, send to cloud 20% of the time - // Here we'd normally use cloud status information - // - if reroutable && number_of_peers > 0 && rand.Intn(5) == 0 { - // Route to random broker peer - random_peer := os.Args[2+rand.Intn(number_of_peers)] - cloudbe.SendMessage(random_peer, "", msg) - } else { - localbe.SendMessage(workers[0], "", msg) - workers = workers[1:] - } - } - } - fmt.Println("Exit") -} - -// Pops frame off front of message and returns it as 'head' -// If next frame is empty, pops that empty frame. -// Return remaining frames of message as 'tail' -func unwrap(msg []string) (head string, tail []string) { - head = msg[0] - if len(msg) > 1 && msg[1] == "" { - tail = msg[2:] - } else { - tail = msg[1:] - } - return -} - -// Returns true if *Socket is in []Polled -func socketInPolled(s *zmq.Socket, p []zmq.Polled) bool { - for _, pp := range p { - if pp.Socket == s { - return true - } - } - return false -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering3.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering3.go deleted file mode 100644 index 7f21ba0..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/peering3.go +++ /dev/null @@ -1,335 +0,0 @@ -// -// Broker peering simulation (part 3). -// Prototypes the full flow of status and tasks -// - -/* - -One of the differences between peering2 and peering3 is that -peering2 always uses Poll() and then uses a helper function socketInPolled() -to check if a specific socket returned a result, while peering3 uses PollAll() -and checks the event state of the socket in a specific index in the list. - -*/ - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "os" - "strconv" - "strings" - "time" -) - -const ( - NBR_CLIENTS = 10 - NBR_WORKERS = 5 - WORKER_READY = "**READY**" // Signals worker is ready -) - -var ( - // Our own name; in practice this would be configured per node - self string -) - -// This is the client task. It issues a burst of requests and then -// sleeps for a few seconds. This simulates sporadic activity; when -// a number of clients are active at once, the local workers should -// be overloaded. The client uses a REQ socket for requests and also -// pushes statistics to the monitor socket: - -func client_task(i int) { - client, _ := zmq.NewSocket(zmq.REQ) - defer client.Close() - client.Connect("ipc://" + self + "-localfe.ipc") - monitor, _ := zmq.NewSocket(zmq.PUSH) - defer monitor.Close() - monitor.Connect("ipc://" + self + "-monitor.ipc") - - poller := zmq.NewPoller() - poller.Add(client, zmq.POLLIN) - for { - time.Sleep(time.Duration(rand.Intn(5000)) * time.Millisecond) - for burst := rand.Intn(15); burst > 0; burst-- { - task_id := fmt.Sprintf("%04X-%s-%d", rand.Intn(0x10000), self, i) - - // Send request with random hex ID - client.Send(task_id, 0) - - // Wait max ten seconds for a reply, then complain - sockets, err := poller.Poll(10 * time.Second) - if err != nil { - break // Interrupted - } - - if len(sockets) == 1 { - reply, err := client.Recv(0) - if err != nil { - break // Interrupted - } - // Worker is supposed to answer us with our task id - id := strings.Fields(reply)[0] - if id != task_id { - panic("id != task_id") - } - monitor.Send(reply, 0) - } else { - monitor.Send("E: CLIENT EXIT - lost task "+task_id, 0) - return - } - } - } -} - -// This is the worker task, which uses a REQ socket to plug into the -// load-balancer. It's the same stub worker task you've seen in other -// examples: - -func worker_task(i int) { - worker, _ := zmq.NewSocket(zmq.REQ) - defer worker.Close() - worker.Connect("ipc://" + self + "-localbe.ipc") - - // Tell broker we're ready for work - worker.SendMessage(WORKER_READY) - - // Process messages as they arrive - for { - msg, err := worker.RecvMessage(0) - if err != nil { - break // Interrupted - } - - // Workers are busy for 0/1 seconds - time.Sleep(time.Duration(rand.Intn(2)) * time.Second) - n := len(msg) - 1 - worker.SendMessage(msg[:n], fmt.Sprintf("%s %s-%d", msg[n], self, i)) - } -} - -// The main task begins by setting-up all its sockets. The local frontend -// talks to clients, and our local backend talks to workers. The cloud -// frontend talks to peer brokers as if they were clients, and the cloud -// backend talks to peer brokers as if they were workers. The state -// backend publishes regular state messages, and the state frontend -// subscribes to all state backends to collect these messages. Finally, -// we use a PULL monitor socket to collect printable messages from tasks: - -func main() { - // First argument is this broker's name - // Other arguments are our peers' names - // - if len(os.Args) < 2 { - fmt.Println("syntax: peering1 me {you}...") - os.Exit(1) - } - self = os.Args[1] - fmt.Printf("I: preparing broker at %s...\n", self) - rand.Seed(time.Now().UnixNano()) - - // Prepare local frontend and backend - localfe, _ := zmq.NewSocket(zmq.ROUTER) - defer localfe.Close() - localfe.Bind("ipc://" + self + "-localfe.ipc") - - localbe, _ := zmq.NewSocket(zmq.ROUTER) - defer localbe.Close() - localbe.Bind("ipc://" + self + "-localbe.ipc") - - // Bind cloud frontend to endpoint - cloudfe, _ := zmq.NewSocket(zmq.ROUTER) - defer cloudfe.Close() - cloudfe.SetIdentity(self) - cloudfe.Bind("ipc://" + self + "-cloud.ipc") - - // Connect cloud backend to all peers - cloudbe, _ := zmq.NewSocket(zmq.ROUTER) - defer cloudbe.Close() - cloudbe.SetIdentity(self) - for _, peer := range os.Args[2:] { - fmt.Printf("I: connecting to cloud frontend at '%s'\n", peer) - cloudbe.Connect("ipc://" + peer + "-cloud.ipc") - } - // Bind state backend to endpoint - statebe, _ := zmq.NewSocket(zmq.PUB) - defer statebe.Close() - statebe.Bind("ipc://" + self + "-state.ipc") - - // Connect state frontend to all peers - statefe, _ := zmq.NewSocket(zmq.SUB) - defer statefe.Close() - statefe.SetSubscribe("") - for _, peer := range os.Args[2:] { - fmt.Printf("I: connecting to state backend at '%s'\n", peer) - statefe.Connect("ipc://" + peer + "-state.ipc") - } - // Prepare monitor socket - monitor, _ := zmq.NewSocket(zmq.PULL) - defer monitor.Close() - monitor.Bind("ipc://" + self + "-monitor.ipc") - - // After binding and connecting all our sockets, we start our child - // tasks - workers and clients: - - for worker_nbr := 0; worker_nbr < NBR_WORKERS; worker_nbr++ { - go worker_task(worker_nbr) - } - - // Start local clients - for client_nbr := 0; client_nbr < NBR_CLIENTS; client_nbr++ { - go client_task(client_nbr) - } - - // Queue of available workers - local_capacity := 0 - cloud_capacity := 0 - workers := make([]string, 0) - - primary := zmq.NewPoller() - primary.Add(localbe, zmq.POLLIN) - primary.Add(cloudbe, zmq.POLLIN) - primary.Add(statefe, zmq.POLLIN) - primary.Add(monitor, zmq.POLLIN) - - secondary1 := zmq.NewPoller() - secondary1.Add(localfe, zmq.POLLIN) - secondary2 := zmq.NewPoller() - secondary2.Add(localfe, zmq.POLLIN) - secondary2.Add(cloudfe, zmq.POLLIN) - - msg := make([]string, 0) - for { - - // If we have no workers ready, wait indefinitely - timeout := time.Duration(time.Second) - if local_capacity == 0 { - timeout = -1 - } - sockets, err := primary.PollAll(timeout) - if err != nil { - break // Interrupted - } - - // Track if capacity changes during this iteration - previous := local_capacity - - // Handle reply from local worker - msg = msg[0:0] - - if sockets[0].Events&zmq.POLLIN != 0 { // 0 == localbe - msg, err = localbe.RecvMessage(0) - if err != nil { - break // Interrupted - } - var identity string - identity, msg = unwrap(msg) - workers = append(workers, identity) - local_capacity++ - - // If it's READY, don't route the message any further - if msg[0] == WORKER_READY { - msg = msg[0:0] - } - } else if sockets[1].Events&zmq.POLLIN != 0 { // 1 == cloudbe - // Or handle reply from peer broker - msg, err = cloudbe.RecvMessage(0) - if err != nil { - break // Interrupted - } - // We don't use peer broker identity for anything - _, msg = unwrap(msg) - } - - if len(msg) > 0 { - - // Route reply to cloud if it's addressed to a broker - to_broker := false - for _, peer := range os.Args[2:] { - if peer == msg[0] { - to_broker = true - break - } - } - if to_broker { - cloudfe.SendMessage(msg) - } else { - localfe.SendMessage(msg) - } - } - - // If we have input messages on our statefe or monitor sockets we - // can process these immediately: - - if sockets[2].Events&zmq.POLLIN != 0 { // 2 == statefe - var status string - m, _ := statefe.RecvMessage(0) - _, m = unwrap(m) // peer - status, _ = unwrap(m) - cloud_capacity, _ = strconv.Atoi(status) - } - if sockets[3].Events&zmq.POLLIN != 0 { // 3 == monitor - status, _ := monitor.Recv(0) - fmt.Println(status) - } - // Now route as many clients requests as we can handle. If we have - // local capacity we poll both localfe and cloudfe. If we have cloud - // capacity only, we poll just localfe. We route any request locally - // if we can, else we route to the cloud. - - for local_capacity+cloud_capacity > 0 { - var sockets []zmq.Polled - var err error - if local_capacity > 0 { - sockets, err = secondary2.PollAll(0) - } else { - sockets, err = secondary1.PollAll(0) - } - if err != nil { - panic(err) - } - - if sockets[0].Events&zmq.POLLIN != 0 { // 0 == localfe - msg, _ = localfe.RecvMessage(0) - } else if len(sockets) > 1 && sockets[1].Events&zmq.POLLIN != 0 { // 1 == cloudfe - msg, _ = cloudfe.RecvMessage(0) - } else { - break // No work, go back to primary - } - - if local_capacity > 0 { - localbe.SendMessage(workers[0], "", msg) - workers = workers[1:] - local_capacity-- - } else { - // Route to random broker peer - random_peer := rand.Intn(len(os.Args)-2) + 2 - cloudbe.SendMessage(os.Args[random_peer], "", msg) - } - } - // We broadcast capacity messages to other peers; to reduce chatter - // we do this only if our capacity changed. - - if local_capacity != previous { - // We stick our own identity onto the envelope - // Broadcast new capacity - statebe.SendMessage(self, "", local_capacity) - } - } -} - -// Pops frame off front of message and returns it as 'head' -// If next frame is empty, pops that empty frame. -// Return remaining frames of message as 'tail' -func unwrap(msg []string) (head string, tail []string) { - head = msg[0] - if len(msg) > 1 && msg[1] == "" { - tail = msg[2:] - } else { - tail = msg[1:] - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ppqueue.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ppqueue.go deleted file mode 100644 index f21cd89..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ppqueue.go +++ /dev/null @@ -1,166 +0,0 @@ -// -// Paranoid Pirate queue. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "time" -) - -const ( - HEARTBEAT_LIVENESS = 3 // 3-5 is reasonable - HEARTBEAT_INTERVAL = 1000 * time.Millisecond // msecs - - PPP_READY = "\001" // Signals worker is ready - PPP_HEARTBEAT = "\002" // Signals worker heartbeat -) - -// Here we define the worker class; a structure and a set of functions that -// as constructor, destructor, and methods on worker objects: - -type worker_t struct { - identity string // Identity of worker - id_string string // Printable identity - expire time.Time // Expires at this time -} - -// Construct new worker -func s_worker_new(identity string) worker_t { - return worker_t{ - identity: identity, - id_string: identity, - expire: time.Now().Add(HEARTBEAT_INTERVAL * HEARTBEAT_LIVENESS), - } -} - -// The ready method puts a worker to the end of the ready list: - -func s_worker_ready(self worker_t, workers []worker_t) []worker_t { - for i, worker := range workers { - if self.id_string == worker.id_string { - if i == 0 { - workers = workers[1:] - } else if i == len(workers)-1 { - workers = workers[:i-1] - } else { - workers = append(workers[:i-1], workers[i:]...) - } - break - } - } - return append(workers, self) -} - -// The purge method looks for and kills expired workers. We hold workers -// from oldest to most recent, so we stop at the first alive worker: - -func s_workers_purge(workers []worker_t) []worker_t { - now := time.Now() - for i, worker := range workers { - if now.Before(worker.expire) { - return workers[i:] // Worker is alive, we're done here - } - } - return workers[0:0] -} - -// The main task is a load-balancer with heartbeating on workers so we -// can detect crashed or blocked worker tasks: - -func main() { - frontend, _ := zmq.NewSocket(zmq.ROUTER) - backend, _ := zmq.NewSocket(zmq.ROUTER) - defer frontend.Close() - defer backend.Close() - frontend.Bind("tcp://*:5555") // For clients - backend.Bind("tcp://*:5556") // For workers - - // List of available workers - workers := make([]worker_t, 0) - - // Send out heartbeats at regular intervals - heartbeat_at := time.Tick(HEARTBEAT_INTERVAL) - - poller1 := zmq.NewPoller() - poller1.Add(backend, zmq.POLLIN) - poller2 := zmq.NewPoller() - poller2.Add(backend, zmq.POLLIN) - poller2.Add(frontend, zmq.POLLIN) - - for { - // Poll frontend only if we have available workers - var sockets []zmq.Polled - var err error - if len(workers) > 0 { - sockets, err = poller2.Poll(HEARTBEAT_INTERVAL) - } else { - sockets, err = poller1.Poll(HEARTBEAT_INTERVAL) - } - if err != nil { - break // Interrupted - } - - for _, socket := range sockets { - switch socket.Socket { - case backend: - // Handle worker activity on backend - // Use worker identity for load-balancing - msg, err := backend.RecvMessage(0) - if err != nil { - break // Interrupted - } - - // Any sign of life from worker means it's ready - identity, msg := unwrap(msg) - workers = s_worker_ready(s_worker_new(identity), workers) - - // Validate control message, or return reply to client - if len(msg) == 1 { - if msg[0] != PPP_READY && msg[0] != PPP_HEARTBEAT { - fmt.Println("E: invalid message from worker", msg) - } - } else { - frontend.SendMessage(msg) - } - case frontend: - // Now get next client request, route to next worker - msg, err := frontend.RecvMessage(0) - if err != nil { - break // Interrupted - } - backend.SendMessage(workers[0].identity, msg) - workers = workers[1:] - } - } - - // We handle heartbeating after any socket activity. First we send - // heartbeats to any idle workers if it's time. Then we purge any - // dead workers: - - select { - case <-heartbeat_at: - for _, worker := range workers { - backend.SendMessage(worker.identity, PPP_HEARTBEAT) - } - default: - } - workers = s_workers_purge(workers) - } -} - -// Pops frame off front of message and returns it as 'head' -// If next frame is empty, pops that empty frame. -// Return remaining frames of message as 'tail' -func unwrap(msg []string) (head string, tail []string) { - head = msg[0] - if len(msg) > 1 && msg[1] == "" { - tail = msg[2:] - } else { - tail = msg[1:] - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ppworker.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ppworker.go deleted file mode 100644 index 6f0d630..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ppworker.go +++ /dev/null @@ -1,130 +0,0 @@ -// -// Paranoid Pirate worker. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "time" -) - -const ( - HEARTBEAT_LIVENESS = 3 // 3-5 is reasonable - HEARTBEAT_INTERVAL = 1000 * time.Millisecond // msecs - INTERVAL_INIT = 1000 * time.Millisecond // Initial reconnect - INTERVAL_MAX = 32000 * time.Millisecond // After exponential backoff - - // Paranoid Pirate Protocol constants - PPP_READY = "\001" // Signals worker is ready - PPP_HEARTBEAT = "\002" // Signals worker heartbeat -) - -// Helper function that returns a new configured socket -// connected to the Paranoid Pirate queue - -func s_worker_socket() (*zmq.Socket, *zmq.Poller) { - worker, _ := zmq.NewSocket(zmq.DEALER) - worker.Connect("tcp://localhost:5556") - - // Tell queue we're ready for work - fmt.Println("I: worker ready") - worker.Send(PPP_READY, 0) - - poller := zmq.NewPoller() - poller.Add(worker, zmq.POLLIN) - - return worker, poller -} - -// We have a single task, which implements the worker side of the -// Paranoid Pirate Protocol (PPP). The interesting parts here are -// the heartbeating, which lets the worker detect if the queue has -// died, and vice-versa: - -func main() { - worker, poller := s_worker_socket() - - // If liveness hits zero, queue is considered disconnected - liveness := HEARTBEAT_LIVENESS - interval := INTERVAL_INIT - - // Send out heartbeats at regular intervals - heartbeat_at := time.Tick(HEARTBEAT_INTERVAL) - - rand.Seed(time.Now().UnixNano()) - for cycles := 0; true; { - sockets, err := poller.Poll(HEARTBEAT_INTERVAL) - if err != nil { - break // Interrupted - } - - if len(sockets) == 1 { - // Get message - // - 3-part envelope + content -> request - // - 1-part HEARTBEAT -> heartbeat - msg, err := worker.RecvMessage(0) - if err != nil { - break // Interrupted - } - - // To test the robustness of the queue implementation we // - // simulate various typical problems, such as the worker - // crashing, or running very slowly. We do this after a few - // cycles so that the architecture can get up and running - // first: - if len(msg) == 3 { - cycles++ - if cycles > 3 && rand.Intn(5) == 0 { - fmt.Println("I: simulating a crash") - break - } else if cycles > 3 && rand.Intn(5) == 0 { - fmt.Println("I: simulating CPU overload") - time.Sleep(3 * time.Second) - } - fmt.Println("I: normal reply") - worker.SendMessage(msg) - liveness = HEARTBEAT_LIVENESS - time.Sleep(time.Second) // Do some heavy work - } else if len(msg) == 1 { - // When we get a heartbeat message from the queue, it means the - // queue was (recently) alive, so reset our liveness indicator: - if msg[0] == PPP_HEARTBEAT { - liveness = HEARTBEAT_LIVENESS - } else { - fmt.Printf("E: invalid message: %q\n", msg) - } - } else { - fmt.Printf("E: invalid message: %q\n", msg) - } - interval = INTERVAL_INIT - } else { - // If the queue hasn't sent us heartbeats in a while, destroy the - // socket and reconnect. This is the simplest most brutal way of - // discarding any messages we might have sent in the meantime:// - liveness-- - if liveness == 0 { - fmt.Println("W: heartbeat failure, can't reach queue") - fmt.Println("W: reconnecting in", interval) - time.Sleep(interval) - - if interval < INTERVAL_MAX { - interval = 2 * interval - } - worker, poller = s_worker_socket() - liveness = HEARTBEAT_LIVENESS - } - } - - // Send heartbeat to queue if it's time - select { - case <-heartbeat_at: - fmt.Println("I: worker heartbeat") - worker.Send(PPP_HEARTBEAT, 0) - default: - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/psenvpub.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/psenvpub.go deleted file mode 100644 index e09cdc4..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/psenvpub.go +++ /dev/null @@ -1,27 +0,0 @@ -// -// Pubsub envelope publisher. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "time" -) - -func main() { - // Prepare our publisher - publisher, _ := zmq.NewSocket(zmq.PUB) - defer publisher.Close() - publisher.Bind("tcp://*:5563") - - for { - // Write two messages, each with an envelope and content - publisher.Send("A", zmq.SNDMORE) - publisher.Send("We don't want to see this", 0) - publisher.Send("B", zmq.SNDMORE) - publisher.Send("We would like to see this", 0) - time.Sleep(time.Second) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/psenvsub.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/psenvsub.go deleted file mode 100644 index a869e0d..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/psenvsub.go +++ /dev/null @@ -1,27 +0,0 @@ -// -// Pubsub envelope subscriber. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" -) - -func main() { - // Prepare our subscriber - subscriber, _ := zmq.NewSocket(zmq.SUB) - defer subscriber.Close() - subscriber.Connect("tcp://localhost:5563") - subscriber.SetSubscribe("B") - - for { - // Read envelope with address - address, _ := subscriber.Recv(0) - // Read message contents - contents, _ := subscriber.Recv(0) - fmt.Printf("[%s] %s\n", address, contents) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrbroker.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrbroker.go deleted file mode 100644 index 1956dfb..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrbroker.go +++ /dev/null @@ -1,53 +0,0 @@ -// -// Simple request-reply broker. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" -) - -func main() { - // Prepare our sockets - frontend, _ := zmq.NewSocket(zmq.ROUTER) - defer frontend.Close() - backend, _ := zmq.NewSocket(zmq.DEALER) - defer backend.Close() - frontend.Bind("tcp://*:5559") - backend.Bind("tcp://*:5560") - - // Initialize poll set - poller := zmq.NewPoller() - poller.Add(frontend, zmq.POLLIN) - poller.Add(backend, zmq.POLLIN) - - // Switch messages between sockets - for { - sockets, _ := poller.Poll(-1) - for _, socket := range sockets { - switch s := socket.Socket; s { - case frontend: - for { - msg, _ := s.Recv(0) - if more, _ := s.GetRcvmore(); more { - backend.Send(msg, zmq.SNDMORE) - } else { - backend.Send(msg, 0) - break - } - } - case backend: - for { - msg, _ := s.Recv(0) - if more, _ := s.GetRcvmore(); more { - frontend.Send(msg, zmq.SNDMORE) - } else { - frontend.Send(msg, 0) - break - } - } - } - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrclient.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrclient.go deleted file mode 100644 index 050f089..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrclient.go +++ /dev/null @@ -1,25 +0,0 @@ -// -// Request-reply client. -// Connects REQ socket to tcp://localhost:5559 -// Sends "Hello" to server, expects "World" back -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" -) - -func main() { - requester, _ := zmq.NewSocket(zmq.REQ) - defer requester.Close() - requester.Connect("tcp://localhost:5559") - - for request := 0; request < 10; request++ { - requester.Send("Hello", 0) - reply, _ := requester.Recv(0) - fmt.Printf("Received reply %d [%s]\n", request, reply) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrworker.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrworker.go deleted file mode 100644 index 7c3174e..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rrworker.go +++ /dev/null @@ -1,33 +0,0 @@ -// -// Hello World worker. -// Connects REP socket to tcp://*:5560 -// Expects "Hello" from client, replies with "World" -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "time" -) - -func main() { - // Socket to talk to clients - responder, _ := zmq.NewSocket(zmq.REP) - defer responder.Close() - responder.Connect("tcp://localhost:5560") - - for { - // Wait for next request from client - request, _ := responder.Recv(0) - fmt.Printf("Received request: [%s]\n", request) - - // Do some 'work' - time.Sleep(time.Second) - - // Send reply back to client - responder.Send("World", 0) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rtdealer.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rtdealer.go deleted file mode 100644 index 490ec42..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rtdealer.go +++ /dev/null @@ -1,84 +0,0 @@ -// -// ROUTER-to-DEALER example. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "time" -) - -const ( - NBR_WORKERS = 10 -) - -func worker_task() { - worker, _ := zmq.NewSocket(zmq.DEALER) - defer worker.Close() - set_id(worker) // Set a printable identity - worker.Connect("tcp://localhost:5671") - - total := 0 - for { - // Tell the broker we're ready for work - worker.Send("", zmq.SNDMORE) - worker.Send("Hi Boss", 0) - - // Get workload from broker, until finished - worker.Recv(0) // Envelope delimiter - workload, _ := worker.Recv(0) - if workload == "Fired!" { - fmt.Printf("Completed: %d tasks\n", total) - break - } - total++ - - // Do some random work - time.Sleep(time.Duration(rand.Intn(500)+1) * time.Millisecond) - } -} - -func main() { - broker, _ := zmq.NewSocket(zmq.ROUTER) - defer broker.Close() - - broker.Bind("tcp://*:5671") - rand.Seed(time.Now().UnixNano()) - - for worker_nbr := 0; worker_nbr < NBR_WORKERS; worker_nbr++ { - go worker_task() - } - // Run for five seconds and then tell workers to end - start_time := time.Now() - workers_fired := 0 - for { - // Next message gives us least recently used worker - identity, _ := broker.Recv(0) - broker.Send(identity, zmq.SNDMORE) - broker.Recv(0) // Envelope delimiter - broker.Recv(0) // Response from worker - broker.Send("", zmq.SNDMORE) - - // Encourage workers until it's time to fire them - if time.Since(start_time) < 5*time.Second { - broker.Send("Work harder", 0) - } else { - broker.Send("Fired!", 0) - workers_fired++ - if workers_fired == NBR_WORKERS { - break - } - } - } - - time.Sleep(time.Second) -} - -func set_id(soc *zmq.Socket) { - identity := fmt.Sprintf("%04X-%04X", rand.Intn(0x10000), rand.Intn(0x10000)) - soc.SetIdentity(identity) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rtreq.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rtreq.go deleted file mode 100644 index b3aeafe..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/rtreq.go +++ /dev/null @@ -1,82 +0,0 @@ -// -// ROUTER-to-REQ example. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "time" -) - -const ( - NBR_WORKERS = 10 -) - -func worker_task() { - worker, _ := zmq.NewSocket(zmq.REQ) - defer worker.Close() - set_id(worker) - worker.Connect("tcp://localhost:5671") - - total := 0 - for { - // Tell the broker we're ready for work - worker.Send("Hi Boss", 0) - - // Get workload from broker, until finished - workload, _ := worker.Recv(0) - if workload == "Fired!" { - fmt.Printf("Completed: %d tasks\n", total) - break - } - total++ - - // Do some random work - time.Sleep(time.Duration(rand.Intn(500)+1) * time.Millisecond) - } -} - -func main() { - broker, _ := zmq.NewSocket(zmq.ROUTER) - defer broker.Close() - - broker.Bind("tcp://*:5671") - rand.Seed(time.Now().UnixNano()) - - for worker_nbr := 0; worker_nbr < NBR_WORKERS; worker_nbr++ { - go worker_task() - } - // Run for five seconds and then tell workers to end - start_time := time.Now() - workers_fired := 0 - for { - // Next message gives us least recently used worker - identity, _ := broker.Recv(0) - broker.Send(identity, zmq.SNDMORE) - broker.Recv(0) // Envelope delimiter - broker.Recv(0) // Response from worker - broker.Send("", zmq.SNDMORE) - - // Encourage workers until it's time to fire them - if time.Since(start_time) < 5*time.Second { - broker.Send("Work harder", 0) - } else { - broker.Send("Fired!", 0) - workers_fired++ - if workers_fired == NBR_WORKERS { - break - } - } - } - - time.Sleep(time.Second) -} - -func set_id(soc *zmq.Socket) { - identity := fmt.Sprintf("%04X-%04X", rand.Intn(0x10000), rand.Intn(0x10000)) - soc.SetIdentity(identity) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/spqueue.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/spqueue.go deleted file mode 100644 index 71575ed..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/spqueue.go +++ /dev/null @@ -1,88 +0,0 @@ -// -// Simple Pirate broker. -// This is identical to load-balancing pattern, with no reliability -// mechanisms. It depends on the client for recovery. Runs forever. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" -) - -const ( - WORKER_READY = "\001" // Signals worker is ready -) - -func main() { - frontend, _ := zmq.NewSocket(zmq.ROUTER) - backend, _ := zmq.NewSocket(zmq.ROUTER) - defer frontend.Close() - defer backend.Close() - frontend.Bind("tcp://*:5555") // For clients - backend.Bind("tcp://*:5556") // For workers - - // Queue of available workers - workers := make([]string, 0) - - poller1 := zmq.NewPoller() - poller1.Add(backend, zmq.POLLIN) - poller2 := zmq.NewPoller() - poller2.Add(backend, zmq.POLLIN) - poller2.Add(frontend, zmq.POLLIN) - - // The body of this example is exactly the same as lbbroker2. -LOOP: - for { - // Poll frontend only if we have available workers - var sockets []zmq.Polled - var err error - if len(workers) > 0 { - sockets, err = poller2.Poll(-1) - } else { - sockets, err = poller1.Poll(-1) - } - if err != nil { - break // Interrupted - } - for _, socket := range sockets { - switch s := socket.Socket; s { - case backend: // Handle worker activity on backend - // Use worker identity for load-balancing - msg, err := s.RecvMessage(0) - if err != nil { - break LOOP // Interrupted - } - var identity string - identity, msg = unwrap(msg) - workers = append(workers, identity) - - // Forward message to client if it's not a READY - if msg[0] != WORKER_READY { - frontend.SendMessage(msg) - } - - case frontend: - // Get client request, route to first available worker - msg, err := s.RecvMessage(0) - if err == nil { - backend.SendMessage(workers[0], "", msg) - workers = workers[1:] - } - } - } - } -} - -// Pops frame off front of message and returns it as 'head' -// If next frame is empty, pops that empty frame. -// Return remaining frames of message as 'tail' -func unwrap(msg []string) (head string, tail []string) { - head = msg[0] - if len(msg) > 1 && msg[1] == "" { - tail = msg[2:] - } else { - tail = msg[1:] - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/spworker.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/spworker.go deleted file mode 100644 index 96992c8..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/spworker.go +++ /dev/null @@ -1,55 +0,0 @@ -// -// Simple Pirate worker. -// Connects REQ socket to tcp://*:5556 -// Implements worker part of load-balancing -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "time" -) - -const ( - WORKER_READY = "\001" // Signals worker is ready -) - -func main() { - worker, _ := zmq.NewSocket(zmq.REQ) - defer worker.Close() - - // Set random identity to make tracing easier - rand.Seed(time.Now().UnixNano()) - identity := fmt.Sprintf("%04X-%04X", rand.Intn(0x10000), rand.Intn(0x10000)) - worker.SetIdentity(identity) - worker.Connect("tcp://localhost:5556") - - // Tell broker we're ready for work - fmt.Printf("I: (%s) worker ready\n", identity) - worker.Send(WORKER_READY, 0) - - for cycles := 0; true; { - msg, err := worker.RecvMessage(0) - if err != nil { - break // Interrupted - } - - // Simulate various problems, after a few cycles - cycles++ - if cycles > 3 && rand.Intn(5) == 0 { - fmt.Printf("I: (%s) simulating a crash\n", identity) - break - } else if cycles > 3 && rand.Intn(5) == 0 { - fmt.Printf("I: (%s) simulating CPU overload\n", identity) - time.Sleep(3 * time.Second) - } - - fmt.Printf("I: (%s) normal reply\n", identity) - time.Sleep(time.Second) // Do some heavy work - worker.SendMessage(msg) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/suisnail.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/suisnail.go deleted file mode 100644 index c37a9b1..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/suisnail.go +++ /dev/null @@ -1,83 +0,0 @@ -// -// Suicidal Snail -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" - "math/rand" - "strconv" - "time" -) - -// This is our subscriber. It connects to the publisher and subscribes to -// everything. It sleeps for a short time between messages to simulate doing -// too much work. If a message is more than 1 second late, it croaks: - -const ( - MAX_ALLOWED_DELAY = 1000 * time.Millisecond -) - -func subscriber(pipe chan<- string) { - // Subscribe to everything - subscriber, _ := zmq.NewSocket(zmq.SUB) - subscriber.SetSubscribe("") - subscriber.Connect("tcp://localhost:5556") - defer subscriber.Close() - - // Get and process messages - for { - msg, _ := subscriber.RecvMessage(0) - i, _ := strconv.Atoi(msg[0]) - clock := time.Unix(int64(i), 0) - fmt.Println(clock) - - // Suicide snail logic - if time.Now().After(clock.Add(MAX_ALLOWED_DELAY)) { - log.Println("E: subscriber cannot keep up, aborting") - break - } - // Work for 1 msec plus some random additional time - time.Sleep(time.Duration(1 + rand.Intn(2))) - } - pipe <- "gone and died" -} - -// This is our publisher task. It publishes a time-stamped message to its -// PUB socket every 1 msec: - -func publisher(pipe <-chan string) { - // Prepare publisher - publisher, _ := zmq.NewSocket(zmq.PUB) - publisher.Bind("tcp://*:5556") - defer publisher.Close() - -LOOP: - for { - // Send current clock (msecs) to subscribers - publisher.SendMessage(time.Now().Unix()) - select { - case <-pipe: - break LOOP - default: - } - time.Sleep(time.Millisecond) - } -} - -// The main task simply starts a client, and a server, and then -// waits for the client to signal that it has died: - -func main() { - pubpipe := make(chan string) - subpipe := make(chan string) - go publisher(pubpipe) - go subscriber(subpipe) - <-subpipe - pubpipe <- "break" - time.Sleep(100 * time.Millisecond) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/sync.sh b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/sync.sh deleted file mode 100644 index 2ac6135..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/sync.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -echo "Starting subscribers..." -for i in 1 2 3 4 5 6 7 8 9 10 -do - ./syncsub & -done -echo "Starting publisher..." -./syncpub -# have all subscribers finished? -sleep 1 -echo Still running instances of syncsub: -ps | grep syncsub diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/syncpub.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/syncpub.go deleted file mode 100644 index 77f57d0..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/syncpub.go +++ /dev/null @@ -1,57 +0,0 @@ -// -// Synchronized publisher. -// -// This diverts from the C example by introducing time delays. -// Without these delays, the subscribers won't catch the END message. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "time" -) - -const ( - // We wait for 10 subscribers - SUBSCRIBERS_EXPECTED = 10 -) - -func main() { - - // Socket to talk to clients - publisher, _ := zmq.NewSocket(zmq.PUB) - defer publisher.Close() - publisher.Bind("tcp://*:5561") - - // Socket to receive signals - syncservice, _ := zmq.NewSocket(zmq.REP) - defer syncservice.Close() - syncservice.Bind("tcp://*:5562") - - // Get synchronization from subscribers - fmt.Println("Waiting for subscribers") - for subscribers := 0; subscribers < SUBSCRIBERS_EXPECTED; subscribers++ { - // - wait for synchronization request - syncservice.Recv(0) - // - send synchronization reply - syncservice.Send("", 0) - } - // Now broadcast exactly 1M updates followed by END - fmt.Println("Broadcasting messages") - for update_nbr := 0; update_nbr < 1000000; update_nbr++ { - publisher.Send("Rhubarb", 0) - // subscribers don't get all messages if publisher is too fast - // a one microsecond pause may still be too short - time.Sleep(time.Microsecond) - } - - // a longer pause ensures subscribers are ready to receive this - time.Sleep(time.Second) - publisher.Send("END", 0) - - // what's another second? - time.Sleep(time.Second) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/syncsub.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/syncsub.go deleted file mode 100644 index b7d3b54..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/syncsub.go +++ /dev/null @@ -1,51 +0,0 @@ -// -// Synchronized subscriber -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" - "time" -) - -func main() { - - // First, connect our subscriber socket - subscriber, _ := zmq.NewSocket(zmq.SUB) - defer subscriber.Close() - subscriber.Connect("tcp://localhost:5561") - subscriber.SetSubscribe("") - - // 0MQ is so fast, we need to wait a while... - time.Sleep(time.Second) - - // Second, synchronize with publisher - syncclient, _ := zmq.NewSocket(zmq.REQ) - defer syncclient.Close() - syncclient.Connect("tcp://localhost:5562") - - // - send a synchronization request - syncclient.Send("", 0) - - // - wait for synchronization reply - syncclient.Recv(0) - - // Third, get our updates and report how many we got - update_nbr := 0 - for { - msg, e := subscriber.Recv(0) - if e != nil { - log.Println(e) - break - } - if msg == "END" { - break - } - update_nbr++ - } - fmt.Printf("Received %d updates\n", update_nbr) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tasksink.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tasksink.go deleted file mode 100644 index 1005d83..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tasksink.go +++ /dev/null @@ -1,40 +0,0 @@ -// -// Task sink. -// Binds PULL socket to tcp://localhost:5558 -// Collects results from workers via that socket -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "time" -) - -func main() { - // Prepare our socket - receiver, _ := zmq.NewSocket(zmq.PULL) - defer receiver.Close() - receiver.Bind("tcp://*:5558") - - // Wait for start of batch - receiver.Recv(0) - - // Start our clock now - start_time := time.Now() - - // Process 100 confirmations - for task_nbr := 0; task_nbr < 100; task_nbr++ { - receiver.Recv(0) - if task_nbr%10 == 0 { - fmt.Print(":") - } else { - fmt.Print(".") - } - } - - // Calculate and report duration of batch - fmt.Println("\nTotal elapsed time:", time.Since(start_time)) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tasksink2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tasksink2.go deleted file mode 100644 index 0d64e62..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tasksink2.go +++ /dev/null @@ -1,48 +0,0 @@ -// -// Task sink - design 2. -// Adds pub-sub flow to send kill signal to workers -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "time" -) - -func main() { - // Socket to receive messages on - receiver, _ := zmq.NewSocket(zmq.PULL) - defer receiver.Close() - receiver.Bind("tcp://*:5558") - - // Socket for worker control - controller, _ := zmq.NewSocket(zmq.PUB) - defer controller.Close() - controller.Bind("tcp://*:5559") - - // Wait for start of batch - receiver.Recv(0) - - // Start our clock now - start_time := time.Now() - - // Process 100 confirmations - for task_nbr := 0; task_nbr < 100; task_nbr++ { - receiver.Recv(0) - if task_nbr%10 == 0 { - fmt.Print(":") - } else { - fmt.Print(".") - } - } - fmt.Println("\nTotal elapsed time:", time.Since(start_time)) - - // Send kill signal to workers - controller.Send("KILL", 0) - - // Finished - time.Sleep(time.Second) // Give 0MQ time to deliver -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskvent.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskvent.go deleted file mode 100644 index e14e475..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskvent.go +++ /dev/null @@ -1,51 +0,0 @@ -// -// Task ventilator. -// Binds PUSH socket to tcp://localhost:5557 -// Sends batch of tasks to workers via that socket -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "time" -) - -func main() { - // Socket to send messages on - sender, _ := zmq.NewSocket(zmq.PUSH) - defer sender.Close() - sender.Bind("tcp://*:5557") - - // Socket to send start of batch message on - sink, _ := zmq.NewSocket(zmq.PUSH) - defer sink.Close() - sink.Connect("tcp://localhost:5558") - - fmt.Print("Press Enter when the workers are ready: ") - var line string - fmt.Scanln(&line) - fmt.Println("Sending tasks to workers...") - - // The first message is "0" and signals start of batch - sink.Send("0", 0) - - // Initialize random number generator - rand.Seed(time.Now().UnixNano()) - - // Send 100 tasks - total_msec := 0 - for task_nbr := 0; task_nbr < 100; task_nbr++ { - // Random workload from 1 to 100msecs - workload := rand.Intn(100) + 1 - total_msec += workload - s := fmt.Sprintf("%d", workload) - sender.Send(s, 0) - } - fmt.Println("Total expected cost:", time.Duration(total_msec)*time.Millisecond) - time.Sleep(time.Second) // Give 0MQ time to deliver - -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskwork.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskwork.go deleted file mode 100644 index fef491b..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskwork.go +++ /dev/null @@ -1,44 +0,0 @@ -// -// Task worker. -// Connects PULL socket to tcp://localhost:5557 -// Collects workloads from ventilator via that socket -// Connects PUSH socket to tcp://localhost:5558 -// Sends results to sink via that socket -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "strconv" - "time" -) - -func main() { - // Socket to receive messages on - receiver, _ := zmq.NewSocket(zmq.PULL) - defer receiver.Close() - receiver.Connect("tcp://localhost:5557") - - // Socket to send messages to - sender, _ := zmq.NewSocket(zmq.PUSH) - defer sender.Close() - sender.Connect("tcp://localhost:5558") - - // Process tasks forever - for { - s, _ := receiver.Recv(0) - - // Simple progress indicator for the viewer - fmt.Print(s + ".") - - // Do the work - msec, _ := strconv.Atoi(s) - time.Sleep(time.Duration(msec) * time.Millisecond) - - // Send results to sink - sender.Send("", 0) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskwork2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskwork2.go deleted file mode 100644 index 34b0ee9..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/taskwork2.go +++ /dev/null @@ -1,62 +0,0 @@ -// -// Task worker - design 2. -// Adds pub-sub flow to receive and respond to kill signal -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "strconv" - "time" -) - -func main() { - // Socket to receive messages on - receiver, _ := zmq.NewSocket(zmq.PULL) - defer receiver.Close() - receiver.Connect("tcp://localhost:5557") - - // Socket to send messages to - sender, _ := zmq.NewSocket(zmq.PUSH) - defer sender.Close() - sender.Connect("tcp://localhost:5558") - - // Socket for control input - controller, _ := zmq.NewSocket(zmq.SUB) - defer controller.Close() - controller.Connect("tcp://localhost:5559") - controller.SetSubscribe("") - - // Process messages from receiver and controller - poller := zmq.NewPoller() - poller.Add(receiver, zmq.POLLIN) - poller.Add(controller, zmq.POLLIN) - // Process messages from both sockets -LOOP: - for { - sockets, _ := poller.Poll(-1) - for _, socket := range sockets { - switch s := socket.Socket; s { - case receiver: - msg, _ := s.Recv(0) - - // Do the work - t, _ := strconv.Atoi(msg) - time.Sleep(time.Duration(t) * time.Millisecond) - - // Send results to sink - sender.Send(msg, 0) - - // Simple progress indicator for the viewer - fmt.Printf(".") - case controller: - // Any controller command acts as 'KILL' - break LOOP // Exit loop - } - } - } - fmt.Println() -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ticlient.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ticlient.go deleted file mode 100644 index bb18324..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/ticlient.go +++ /dev/null @@ -1,81 +0,0 @@ -// -// Titanic client example. -// Implements client side of http://rfc.zeromq.org/spec:9 - -package main - -import ( - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi" - - "errors" - "fmt" - "os" - "time" -) - -// Calls a TSP service -// Returns response if successful (status code 200 OK), else NULL -// -func ServiceCall(session *mdapi.Mdcli, service string, request ...string) (reply []string, err error) { - reply = []string{} - msg, err := session.Send(service, request...) - if err == nil { - switch status := msg[0]; status { - case "200": - reply = msg[1:] - return - case "400": - fmt.Println("E: client fatal error, aborting") - os.Exit(1) - case "500": - fmt.Println("E: server fatal error, aborting") - os.Exit(1) - } - } else { - fmt.Println("E: " + err.Error()) - os.Exit(0) - } - - err = errors.New("Didn't succeed") - return // Didn't succeed, don't care why not -} - -// The main task tests our service call by sending an echo request: - -func main() { - var verbose bool - if len(os.Args) > 1 && os.Args[1] == "-v" { - verbose = true - } - session, _ := mdapi.NewMdcli("tcp://localhost:5555", verbose) - - // 1. Send 'echo' request to Titanic - reply, err := ServiceCall(session, "titanic.request", "echo", "Hello world") - if err != nil { - fmt.Println(err) - return - } - - var uuid string - if err == nil { - uuid = reply[0] - fmt.Println("I: request UUID", uuid) - } - - time.Sleep(100 * time.Millisecond) - - // 2. Wait until we get a reply - for { - reply, err := ServiceCall(session, "titanic.reply", uuid) - if err == nil { - fmt.Println("Reply:", reply[0]) - - // 3. Close request - ServiceCall(session, "titanic.close", uuid) - break - } else { - fmt.Println("I: no reply yet, trying again...") - time.Sleep(5 * time.Second) // Try again in 5 seconds - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/titanic.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/titanic.go deleted file mode 100644 index fc6ea0f..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/titanic.go +++ /dev/null @@ -1,235 +0,0 @@ -// -// Titanic service. -// -// Implements server side of http://rfc.zeromq.org/spec:9 - -package main - -import ( - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/mdapi" - - "code.google.com/p/go-uuid/uuid" - - "fmt" - "io/ioutil" - "os" - "strings" - "time" -) - -// Returns freshly allocated request filename for given UUID - -const ( - TITANIC_DIR = ".titanic" -) - -func RequestFilename(uuid string) string { - return TITANIC_DIR + "/" + uuid + "req" -} - -// Returns freshly allocated reply filename for given UUID - -func ReplyFilename(uuid string) string { - return TITANIC_DIR + "/" + uuid + "rep" -} - -// The "titanic.request" task waits for requests to this service. It writes -// each request to disk and returns a UUID to the client. The client picks -// up the reply asynchronously using the "titanic.reply" service: - -func TitanicRequest(chRequest chan<- string) { - worker, _ := mdapi.NewMdwrk("tcp://localhost:5555", "titanic.request", false) - - reply := []string{} - for { - // Send reply if it's not null - // And then get next request from broker - request, err := worker.Recv(reply) - if err != nil { - break // Interrupted, exit - } - - // Ensure message directory exists - os.MkdirAll(TITANIC_DIR, 0700) - - // Generate UUID and save message to disk - uuid := uuid.New() - file, err := os.Create(RequestFilename(uuid)) - fmt.Fprint(file, strings.Join(request, "\n")) - file.Close() - - // Send UUID through to message queue - chRequest <- uuid - - // Now send UUID back to client - // Done by the mdwrk_recv() at the top of the loop - reply = []string{"200", uuid} - } -} - -// The "titanic.reply" task checks if there's a reply for the specified -// request (by UUID), and returns a 200 OK, 300 Pending, or 400 Unknown -// accordingly: - -func TitanicReply() { - worker, _ := mdapi.NewMdwrk("tcp://localhost:5555", "titanic.reply", false) - - pending := []string{"300"} - unknown := []string{"400"} - reply := []string{} - for { - request, err := worker.Recv(reply) - if err != nil { - break // Interrupted, exit - } - - uuid := request[0] - req_filename := RequestFilename(uuid) - rep_filename := ReplyFilename(uuid) - data, err := ioutil.ReadFile(rep_filename) - if err == nil { - reply = strings.Split("200\n"+string(data), "\n") - } else { - _, err := os.Stat(req_filename) - if err == nil { - reply = pending - } else { - reply = unknown - } - } - } -} - -// The "titanic.close" task removes any waiting replies for the request -// (specified by UUID). It's idempotent, so safe to call more than once -// in a row: - -func TitanicClose() { - worker, _ := mdapi.NewMdwrk("tcp://localhost:5555", "titanic.close", false) - - ok := []string{"200"} - reply := []string{} - for { - request, err := worker.Recv(reply) - if err != nil { - break // Interrupted, exit - } - - uuid := request[0] - os.Remove(RequestFilename(uuid)) - os.Remove(ReplyFilename(uuid)) - - reply = ok - } - -} - -// This is the main thread for the Titanic worker. It starts three child -// threads; for the request, reply, and close services. It then dispatches -// requests to workers using a simple brute-force disk queue. It receives -// request UUIDs from the titanic.request service, saves these to a disk -// file, and then throws each request at MDP workers until it gets a -// response: - -func main() { - var verbose bool - if len(os.Args) > 1 && os.Args[1] == "-v" { - verbose = true - } - - chRequest := make(chan string) - go TitanicRequest(chRequest) - go TitanicReply() - go TitanicClose() - - // Ensure message directory exists - os.MkdirAll(TITANIC_DIR, 0700) - - // Fill the queue - queue := make([]string, 0) - files, err := ioutil.ReadDir(TITANIC_DIR) - if err == nil { - for _, file := range files { - name := file.Name() - if strings.HasSuffix(name, "req") { - uuid := name[:len(name)-3] - _, err := os.Stat(ReplyFilename(uuid)) - if err != nil { - queue = append(queue, uuid) - } - } - } - } - - // Main dispatcher loop - for { - // We'll dispatch once per second, if there's no activity - select { - case <-time.After(time.Second): - case uuid := <-chRequest: - // Append UUID to queue - queue = append(queue, uuid) - } - - // Brute-force dispatcher - queue2 := make([]string, 0, len(queue)) - for _, entry := range queue { - if verbose { - fmt.Println("I: processing request", entry) - } - if !ServiceSuccess(entry) { - queue2 = append(queue2, entry) - } - } - queue = queue2 - } -} - -// Here we first check if the requested MDP service is defined or not, -// using a MMI lookup to the Majordomo broker. If the service exists -// we send a request and wait for a reply using the conventional MDP -// client API. This is not meant to be fast, just very simple: - -func ServiceSuccess(uuid string) bool { - // If reply already exists, treat as successful - _, err := os.Stat(ReplyFilename(uuid)) - if err == nil { - return true - } - - // Load request message, service will be first frame - data, err := ioutil.ReadFile(RequestFilename(uuid)) - - // If the client already closed request, treat as successful - if err != nil { - return true - } - - request := strings.Split(string(data), "\n") - - service_name := request[0] - request = request[1:] - - // Create MDP client session with short timeout - client, err := mdapi.NewMdcli("tcp://localhost:5555", false) - client.SetTimeout(time.Second) // 1 sec - client.SetRetries(1) // only 1 retry - - // Use MMI protocol to check if service is available - mmi_reply, err := client.Send("mmi.service", service_name) - if err != nil || mmi_reply[0] != "200" { - return false - } - - reply, err := client.Send(service_name, request...) - if err != nil { - return false - } - - file, err := os.Create(ReplyFilename(uuid)) - fmt.Fprint(file, strings.Join(reply, "\n")) - file.Close() - - return true - -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tripping.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tripping.go deleted file mode 100644 index ada41ee..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/tripping.go +++ /dev/null @@ -1,82 +0,0 @@ -// -// Round-trip demonstrator. -// -// While this example runs in a single process, that is just to make -// it easier to start and stop the example. The client task signals to -// main when it's ready. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "time" -) - -func ClientTask(pipe chan<- bool) { - client, _ := zmq.NewSocket(zmq.DEALER) - client.Connect("tcp://localhost:5555") - fmt.Println("Setting up test...") - time.Sleep(100 * time.Millisecond) - - fmt.Println("Synchronous round-trip test...") - start := time.Now() - var requests int - for requests = 0; requests < 10000; requests++ { - client.Send("hello", 0) - client.Recv(0) - } - fmt.Println(requests, "calls in", time.Since(start)) - - fmt.Println("Asynchronous round-trip test...") - start = time.Now() - for requests = 0; requests < 100000; requests++ { - client.Send("hello", 0) - } - for requests = 0; requests < 100000; requests++ { - client.Recv(0) - } - fmt.Println(requests, "calls in", time.Since(start)) - pipe <- true -} - -// Here is the worker task. All it does is receive a message, and -// bounce it back the way it came: - -func WorkerTask() { - worker, _ := zmq.NewSocket(zmq.DEALER) - worker.Connect("tcp://localhost:5556") - - for { - msg, _ := worker.RecvMessage(0) - worker.SendMessage(msg) - } -} - -// Here is the broker task. It uses the zmq_proxy function to switch -// messages between frontend and backend: - -func BrokerTask() { - // Prepare our sockets - frontend, _ := zmq.NewSocket(zmq.DEALER) - frontend.Bind("tcp://*:5555") - backend, _ := zmq.NewSocket(zmq.DEALER) - backend.Bind("tcp://*:5556") - zmq.Proxy(frontend, backend, nil) -} - -// Finally, here's the main task, which starts the client, worker, and -// broker, and then runs until the client signals it to stop: - -func main() { - // Create threads - pipe := make(chan bool) - go ClientTask(pipe) - go WorkerTask() - go BrokerTask() - - // Wait for signal on client pipe - <-pipe -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping1.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping1.go deleted file mode 100644 index 7264fc7..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping1.go +++ /dev/null @@ -1,103 +0,0 @@ -// -// UDP ping command -// Model 1, does UDP work inline -// - -// this doesn't use ZeroMQ at all - -package main - -import ( - "fmt" - "log" - "syscall" - "time" -) - -const ( - PING_PORT_NUMBER = 9999 - PING_MSG_SIZE = 1 - PING_INTERVAL = 1000 * time.Millisecond // Once per second -) - -func main() { - - log.SetFlags(log.Lshortfile) - - // Create UDP socket - fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) - if err != nil { - log.Fatalln(err) - } - - // Ask operating system to let us do broadcasts from socket - if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1); err != nil { - log.Fatalln(err) - } - - // Bind UDP socket to local port so we can receive pings - if err := syscall.Bind(fd, &syscall.SockaddrInet4{Port: PING_PORT_NUMBER, Addr: [4]byte{0, 0, 0, 0}}); err != nil { - log.Fatalln(err) - } - - buffer := make([]byte, PING_MSG_SIZE) - - // We use syscall.Select to wait for activity on the UDP socket. - // We send a beacon once a second, and we collect and report - // beacons that come in from other nodes: - - rfds := &syscall.FdSet{} - timeout := &syscall.Timeval{} - - // Send first ping right away - ping_at := time.Now() - - bcast := &syscall.SockaddrInet4{Port: PING_PORT_NUMBER, Addr: [4]byte{255, 255, 255, 255}} - for { - dur := int64(ping_at.Sub(time.Now()) / time.Microsecond) - if dur < 0 { - dur = 0 - } - timeout.Sec, timeout.Usec = dur/1000000, dur%1000000 - FD_ZERO(rfds) - FD_SET(rfds, fd) - _, err := syscall.Select(fd+1, rfds, nil, nil, timeout) - if err != nil { - log.Fatalln(err) - } - - // Someone answered our ping - if FD_ISSET(rfds, fd) { - _, addr, err := syscall.Recvfrom(fd, buffer, 0) - if err != nil { - log.Fatalln(err) - } - a := addr.(*syscall.SockaddrInet4) - fmt.Printf("Found peer %v.%v.%v.%v:%v\n", a.Addr[0], a.Addr[1], a.Addr[2], a.Addr[3], a.Port) - } - if time.Now().After(ping_at) { - // Broadcast our beacon - fmt.Println("Pinging peers...") - buffer[0] = '!' - if err := syscall.Sendto(fd, buffer, 0, bcast); err != nil { - log.Fatalln(err) - } - ping_at = time.Now().Add(PING_INTERVAL) - } - } - -} - -func FD_SET(p *syscall.FdSet, i int) { - p.Bits[i/64] |= 1 << uint(i) % 64 -} - -func FD_ISSET(p *syscall.FdSet, i int) bool { - return (p.Bits[i/64] & (1 << uint(i) % 64)) != 0 -} - -func FD_ZERO(p *syscall.FdSet) { - for i := range p.Bits { - p.Bits[i] = 0 - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping2.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping2.go deleted file mode 100644 index d51fb8e..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping2.go +++ /dev/null @@ -1,62 +0,0 @@ -// -// UDP ping command -// Model 2, uses the GO net library -// - -// this doesn't use ZeroMQ at all - -package main - -import ( - "fmt" - "log" - "net" - "time" -) - -const ( - PING_PORT_NUMBER = 9999 - PING_MSG_SIZE = 1 - PING_INTERVAL = 1000 * time.Millisecond // Once per second -) - -func main() { - - log.SetFlags(log.Lshortfile) - - // Create UDP socket - bcast := &net.UDPAddr{Port: PING_PORT_NUMBER, IP: net.IPv4bcast} - conn, err := net.ListenUDP("udp", bcast) - if err != nil { - log.Fatalln(err) - } - - buffer := make([]byte, PING_MSG_SIZE) - - // We send a beacon once a second, and we collect and report - // beacons that come in from other nodes: - - // Send first ping right away - ping_at := time.Now() - - for { - if err := conn.SetReadDeadline(ping_at); err != nil { - log.Fatalln(err) - } - - if _, addr, err := conn.ReadFrom(buffer); err == nil { - // Someone answered our ping - fmt.Println("Found peer", addr) - } - - if time.Now().After(ping_at) { - // Broadcast our beacon - fmt.Println("Pinging peers...") - buffer[0] = '!' - if _, err := conn.WriteTo(buffer, bcast); err != nil { - log.Fatalln(err) - } - ping_at = time.Now().Add(PING_INTERVAL) - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping3.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping3.go deleted file mode 100644 index 809d52e..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/udpping3.go +++ /dev/null @@ -1,25 +0,0 @@ -// -// UDP ping command -// Model 3, uses abstract network interface -// - -package main - -import ( - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/intface" - - "fmt" - "log" -) - -func main() { - log.SetFlags(log.Lshortfile) - iface := intface.New() - for { - msg, err := iface.Recv() - if err != nil { - log.Fatalln(err) - } - fmt.Printf("%q\n", msg) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/version.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/version.go deleted file mode 100644 index 2c8f25d..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/version.go +++ /dev/null @@ -1,16 +0,0 @@ -// -// Report 0MQ version. -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" -) - -func main() { - major, minor, patch := zmq.Version() - fmt.Printf("Current 0MQ version is %d.%d.%d\n", major, minor, patch) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuclient.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuclient.go deleted file mode 100644 index b0d921c..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuclient.go +++ /dev/null @@ -1,46 +0,0 @@ -// -// Weather update client. -// Connects SUB socket to tcp://localhost:5556 -// Collects weather updates and finds avg temp in zipcode -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "os" - "strconv" - "strings" -) - -func main() { - // Socket to talk to server - fmt.Println("Collecting updates from weather server...") - subscriber, _ := zmq.NewSocket(zmq.SUB) - defer subscriber.Close() - subscriber.Connect("tcp://localhost:5556") - - // Subscribe to zipcode, default is NYC, 10001 - filter := "10001 " - if len(os.Args) > 1 { - filter = os.Args[1] + " " - } - subscriber.SetSubscribe(filter) - - // Process 100 updates - total_temp := 0 - update_nbr := 0 - for update_nbr < 100 { - msg, _ := subscriber.Recv(0) - - if msgs := strings.Fields(msg); len(msgs) > 1 { - if temperature, err := strconv.Atoi(msgs[1]); err == nil { - total_temp += temperature - update_nbr++ - } - } - } - fmt.Printf("Average temperature for zipcode '%s' was %dF \n\n", strings.TrimSpace(filter), total_temp/update_nbr) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuproxy.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuproxy.go deleted file mode 100644 index 084c824..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuproxy.go +++ /dev/null @@ -1,29 +0,0 @@ -// -// Weather proxy device. -// -// NOT TESTED -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "log" -) - -func main() { - // This is where the weather server sits - frontend, _ := zmq.NewSocket(zmq.XSUB) - defer frontend.Close() - frontend.Connect("tcp://192.168.55.210:5556") - - // This is our public endpoint for subscribers - backend, _ := zmq.NewSocket(zmq.XPUB) - defer backend.Close() - backend.Bind("tcp://10.1.1.0:8100") - - // Run the proxy until the user interrupts us - err := zmq.Proxy(frontend, backend, nil) - log.Fatalln("Proxy interrupted:", err) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuserver.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuserver.go deleted file mode 100644 index 834d0a5..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples/wuserver.go +++ /dev/null @@ -1,40 +0,0 @@ -// -// Weather update server. -// Binds PUB socket to tcp://*:5556 -// Publishes random weather updates -// - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "math/rand" - "time" -) - -func main() { - - // Prepare our publisher - publisher, _ := zmq.NewSocket(zmq.PUB) - defer publisher.Close() - publisher.Bind("tcp://*:5556") - publisher.Bind("ipc://weather.ipc") - - // Initialize random number generator - rand.Seed(time.Now().UnixNano()) - - // loop for a while aparently - for { - - // Get values that will fool the boss - zipcode := rand.Intn(100000) - temperature := rand.Intn(215) - 80 - relhumidity := rand.Intn(50) + 10 - - // Send message to all subscribers - msg := fmt.Sprintf("%05d %d %d", zipcode, temperature, relhumidity) - publisher.Send(msg, 0) - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/Makefile b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/Makefile deleted file mode 100644 index 2ec2eee..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/Makefile +++ /dev/null @@ -1,5 +0,0 @@ - -% : %.go - go build $< - -all: grasslands strawhouse woodhouse stonehouse ironhouse diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/README.md b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/README.md deleted file mode 100644 index 701377c..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/README.md +++ /dev/null @@ -1,10 +0,0 @@ -These are Go versions of the C examples described in -[Using ZeroMQ Security (part 2)](http://hintjens.com/blog:49) by Pieter Hintjens. -Those C examples use the [zauth module](http://czmq.zeromq.org/manual:zauth) -in the [czmq library](http://czmq.zeromq.org). - -There are some differences: - - * The zauth module doesn't handle domains. The Go version does. - * The zauth module handles files with usernames/passwords and directories with certificates. - The Go version just uses maps of usernames/passwords and lists of public user keys. diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/grasslands.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/grasslands.go deleted file mode 100644 index b9acc93..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/grasslands.go +++ /dev/null @@ -1,49 +0,0 @@ -// The Grasslands Pattern -// -// The Classic ZeroMQ model, plain text with no protection at all. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" - "runtime" -) - -func main() { - - // Create and bind server socket - server, err := zmq.NewSocket(zmq.PUSH) - checkErr(err) - checkErr(server.Bind("tcp://*:9000")) - - // Create and connect client socket - client, err := zmq.NewSocket(zmq.PULL) - checkErr(err) - checkErr(client.Connect("tcp://127.0.0.1:9000")) - - // Send a single message from server to client - _, err = server.Send("Hello", 0) - checkErr(err) - message, err := client.Recv(0) - checkErr(err) - if message != "Hello" { - log.Fatalln(message, "!= Hello") - } - - fmt.Println("Grasslands test OK") -} - -func checkErr(err error) { - if err != nil { - log.SetFlags(0) - _, filename, lineno, ok := runtime.Caller(1) - if ok { - log.Fatalf("%v:%v: %v", filename, lineno, err) - } else { - log.Fatalln(err) - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/ironhouse.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/ironhouse.go deleted file mode 100644 index 816c340..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/ironhouse.go +++ /dev/null @@ -1,69 +0,0 @@ -// The Ironhouse Pattern -// -// Security doesn't get any stronger than this. An attacker is going to -// have to break into your systems to see data before/after encryption. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" - "runtime" -) - -func main() { - - // Start authentication engine - zmq.AuthSetVerbose(true) - zmq.AuthStart() - zmq.AuthAllow("domain1", "127.0.0.1/8") - - // We need two certificates, one for the client and one for - // the server. The client must know the server's public key - // to make a CURVE connection. - client_public, client_secret, err := zmq.NewCurveKeypair() - checkErr(err) - server_public, server_secret, err := zmq.NewCurveKeypair() - checkErr(err) - - // Tell authenticator to use this public client key - zmq.AuthCurveAdd("domain1", client_public) - - // Create and bind server socket - server, _ := zmq.NewSocket(zmq.PUSH) - server.ServerAuthCurve("domain1", server_secret) - server.Bind("tcp://*:9000") - - // Create and connect client socket - client, _ := zmq.NewSocket(zmq.PULL) - client.ClientAuthCurve(server_public, client_public, client_secret) - client.Connect("tcp://127.0.0.1:9000") - - // Send a single message from server to client - _, err = server.Send("Hello", 0) - checkErr(err) - message, err := client.Recv(0) - checkErr(err) - if message != "Hello" { - log.Fatalln(message, "!= Hello") - } - - zmq.AuthStop() - - fmt.Println("Ironhouse test OK") - -} - -func checkErr(err error) { - if err != nil { - log.SetFlags(0) - _, filename, lineno, ok := runtime.Caller(1) - if ok { - log.Fatalf("%v:%v: %v", filename, lineno, err) - } else { - log.Fatalln(err) - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/stonehouse.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/stonehouse.go deleted file mode 100644 index 989cf94..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/stonehouse.go +++ /dev/null @@ -1,70 +0,0 @@ -// The Stonehouse Pattern -// -// Where we allow any clients to connect, but we promise clients -// that we are who we claim to be, and our conversations won't be -// tampered with or modified, or spied on. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" - "runtime" -) - -func main() { - - // Start authentication engine - zmq.AuthSetVerbose(true) - zmq.AuthStart() - zmq.AuthAllow("domain1", "127.0.0.1") - - // Tell the authenticator to allow any CURVE requests for this domain - zmq.AuthCurveAdd("domain1", zmq.CURVE_ALLOW_ANY) - - // We need two certificates, one for the client and one for - // the server. The client must know the server's public key - // to make a CURVE connection. - client_public, client_secret, err := zmq.NewCurveKeypair() - checkErr(err) - server_public, server_secret, err := zmq.NewCurveKeypair() - checkErr(err) - - // Create and bind server socket - server, _ := zmq.NewSocket(zmq.PUSH) - server.ServerAuthCurve("domain1", server_secret) - server.Bind("tcp://*:9000") - - // Create and connect client socket - client, _ := zmq.NewSocket(zmq.PULL) - client.ClientAuthCurve(server_public, client_public, client_secret) - client.Connect("tcp://127.0.0.1:9000") - - // Send a single message from server to client - _, err = server.Send("Hello", 0) - checkErr(err) - message, err := client.Recv(0) - checkErr(err) - if message != "Hello" { - log.Fatalln(message, "!= Hello") - } - - zmq.AuthStop() - - fmt.Println("Stonehouse test OK") - -} - -func checkErr(err error) { - if err != nil { - log.SetFlags(0) - _, filename, lineno, ok := runtime.Caller(1) - if ok { - log.Fatalf("%v:%v: %v", filename, lineno, err) - } else { - log.Fatalln(err) - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/strawhouse.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/strawhouse.go deleted file mode 100644 index f460480..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/strawhouse.go +++ /dev/null @@ -1,65 +0,0 @@ -// The Strawhouse Pattern -// -// We allow or deny clients according to their IP address. It may keep -// spammers and idiots away, but won't stop a real attacker for more -// than a heartbeat. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" - "runtime" -) - -func main() { - - // Get some indication of what the authenticator is deciding - zmq.AuthSetVerbose(true) - - // Start the authentication engine. This engine - // allows or denies incoming connections (talking to the libzmq - // core over a protocol called ZAP). - zmq.AuthStart() - - // Whitelist our address; any other address will be rejected - zmq.AuthAllow("domain1", "127.0.0.1") - - // Create and bind server socket - server, err := zmq.NewSocket(zmq.PUSH) - checkErr(err) - server.ServerAuthNull("domain1") - server.Bind("tcp://*:9000") - - // Create and connect client socket - client, err := zmq.NewSocket(zmq.PULL) - checkErr(err) - checkErr(client.Connect("tcp://127.0.0.1:9000")) - - // Send a single message from server to client - _, err = server.Send("Hello", 0) - checkErr(err) - message, err := client.Recv(0) - checkErr(err) - if message != "Hello" { - log.Fatalln(message, "!= Hello") - } - - zmq.AuthStop() - - fmt.Println("Strawhouse test OK") -} - -func checkErr(err error) { - if err != nil { - log.SetFlags(0) - _, filename, lineno, ok := runtime.Caller(1) - if ok { - log.Fatalf("%v:%v: %v", filename, lineno, err) - } else { - log.Fatalln(err) - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/woodhouse.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/woodhouse.go deleted file mode 100644 index 868bb3d..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/examples_security/woodhouse.go +++ /dev/null @@ -1,62 +0,0 @@ -// The Woodhouse Pattern -// -// It may keep some malicious people out but all it takes is a bit -// of network sniffing, and they'll be able to fake their way in. - -package main - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "fmt" - "log" - "runtime" -) - -func main() { - - // Start authentication engine - zmq.AuthSetVerbose(true) - zmq.AuthStart() - zmq.AuthAllow("domain1", "127.0.0.1") - - // Tell the authenticator how to handle PLAIN requests - zmq.AuthPlainAdd("domain1", "admin", "secret") - - // Create and bind server socket - server, _ := zmq.NewSocket(zmq.PUSH) - server.ServerAuthPlain("domain1") - server.Bind("tcp://*:9000") - - // Create and connect client socket - client, _ := zmq.NewSocket(zmq.PULL) - client.SetPlainUsername("admin") - client.SetPlainPassword("secret") - client.Connect("tcp://127.0.0.1:9000") - - // Send a single message from server to client - _, err := server.Send("Hello", 0) - checkErr(err) - message, err := client.Recv(0) - checkErr(err) - if message != "Hello" { - log.Fatalln(message, "!= Hello") - } - - zmq.AuthStop() - - fmt.Println("Woodhouse test OK") - -} - -func checkErr(err error) { - if err != nil { - log.SetFlags(0) - _, filename, lineno, ok := runtime.Caller(1) - if ok { - log.Fatalf("%v:%v: %v", filename, lineno, err) - } else { - log.Fatalln(err) - } - } -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/polling.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/polling.go deleted file mode 100644 index eefd0ff..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/polling.go +++ /dev/null @@ -1,119 +0,0 @@ -package zmq4 - -/* -#include -*/ -import "C" - -import ( - "fmt" - "time" -) - -// Return type for (*Poller)Poll -type Polled struct { - Socket *Socket // socket with matched event(s) - Events State // actual matched event(s) -} - -type Poller struct { - items []C.zmq_pollitem_t - socks []*Socket - size int -} - -// Create a new Poller -func NewPoller() *Poller { - return &Poller{ - items: make([]C.zmq_pollitem_t, 0), - socks: make([]*Socket, 0), - size: 0} -} - -// Add items to the poller -// -// Events is a bitwise OR of zmq.POLLIN and zmq.POLLOUT -func (p *Poller) Add(soc *Socket, events State) { - var item C.zmq_pollitem_t - item.socket = soc.soc - item.fd = 0 - item.events = C.short(events) - p.items = append(p.items, item) - p.socks = append(p.socks, soc) - p.size += 1 -} - -/* -Input/output multiplexing - -If timeout < 0, wait forever until a matching event is detected - -Only sockets with matching socket events are returned in the list. - -Example: - - poller := zmq.NewPoller() - poller.Add(socket0, zmq.POLLIN) - poller.Add(socket1, zmq.POLLIN) - // Process messages from both sockets - for { - sockets, _ := poller.Poll(-1) - for _, socket := range sockets { - switch s := socket.Socket; s { - case socket0: - msg, _ := s.Recv(0) - // Process msg - case socket1: - msg, _ := s.Recv(0) - // Process msg - } - } - } -*/ -func (p *Poller) Poll(timeout time.Duration) ([]Polled, error) { - return p.poll(timeout, false) -} - -/* -This is like (*Poller)Poll, but it returns a list of all sockets, -in the same order as they were added to the poller, -not just those sockets that had an event. - -For each socket in the list, you have to check the Events field -to see if there was actually an event. - -When error is not nil, the return list contains no sockets. -*/ -func (p *Poller) PollAll(timeout time.Duration) ([]Polled, error) { - return p.poll(timeout, true) -} - -func (p *Poller) poll(timeout time.Duration, all bool) ([]Polled, error) { - lst := make([]Polled, 0, p.size) - t := timeout - if t > 0 { - t = t / time.Millisecond - } - if t < 0 { - t = -1 - } - rv, err := C.zmq_poll(&p.items[0], C.int(len(p.items)), C.long(t)) - if rv < 0 { - return lst, errget(err) - } - for i, it := range p.items { - if all || it.events&it.revents != 0 { - lst = append(lst, Polled{p.socks[i], State(it.revents)}) - } - } - return lst, nil -} - -// Poller as string. -func (p *Poller) String() string { - str := make([]string, 0) - for i, poll := range p.items { - str = append(str, fmt.Sprintf("%v%v", p.socks[i], State(poll.events))) - } - return fmt.Sprint("Poller", str) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/reactor.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/reactor.go deleted file mode 100644 index 11a617c..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/reactor.go +++ /dev/null @@ -1,194 +0,0 @@ -package zmq4 - -import ( - "errors" - "fmt" - "time" -) - -type reactor_socket struct { - e State - f func(State) error -} - -type reactor_channel struct { - ch <-chan interface{} - f func(interface{}) error - limit int -} - -type Reactor struct { - sockets map[*Socket]*reactor_socket - channels map[uint64]*reactor_channel - p *Poller - idx uint64 - remove []uint64 - verbose bool -} - -/* -Create a reactor to mix the handling of sockets and channels (timers or other channels). - -Example: - - reactor := zmq.NewReactor() - reactor.AddSocket(socket1, zmq.POLLIN, socket1_handler) - reactor.AddSocket(socket2, zmq.POLLIN, socket2_handler) - reactor.AddChannelTime(time.Tick(time.Second), 1, ticker_handler) - reactor.Run(time.Second) -*/ -func NewReactor() *Reactor { - r := &Reactor{ - sockets: make(map[*Socket]*reactor_socket), - channels: make(map[uint64]*reactor_channel), - p: NewPoller(), - remove: make([]uint64, 0), - } - return r -} - -// Add socket handler to the reactor. -// -// You can have only one handler per socket. Adding a second one will remove the first. -// -// The handler receives the socket state as an argument: POLLIN, POLLOUT, or both. -func (r *Reactor) AddSocket(soc *Socket, events State, handler func(State) error) { - r.RemoveSocket(soc) - r.sockets[soc] = &reactor_socket{e: events, f: handler} - r.p.Add(soc, events) -} - -// Remove a socket handler from the reactor. -func (r *Reactor) RemoveSocket(soc *Socket) { - if _, ok := r.sockets[soc]; ok { - delete(r.sockets, soc) - // rebuild poller - r.p = NewPoller() - for s, props := range r.sockets { - r.p.Add(s, props.e) - } - } -} - -// Add channel handler to the reactor. -// -// Returns id of added handler, that can be used later to remove it. -// -// If limit is positive, at most this many items will be handled in each run through the main loop, -// otherwise it will process as many items as possible. -// -// The handler function receives the value received from the channel. -func (r *Reactor) AddChannel(ch <-chan interface{}, limit int, handler func(interface{}) error) (id uint64) { - r.idx++ - id = r.idx - r.channels[id] = &reactor_channel{ch: ch, f: handler, limit: limit} - return -} - -// This function wraps AddChannel, using a channel of type time.Time instead of type interface{}. -func (r *Reactor) AddChannelTime(ch <-chan time.Time, limit int, handler func(interface{}) error) (id uint64) { - ch2 := make(chan interface{}) - go func() { - for { - a, ok := <-ch - if !ok { - close(ch2) - break - } - ch2 <- a - } - }() - return r.AddChannel(ch2, limit, handler) -} - -// Remove a channel from the reactor. -// -// Closed channels are removed automaticly. -func (r *Reactor) RemoveChannel(id uint64) { - r.remove = append(r.remove, id) -} - -func (r *Reactor) SetVerbose(verbose bool) { - r.verbose = verbose -} - -// Run the reactor. -// -// The interval determines the time-out on the polling of sockets. -// Interval must be positive if there are channels. -// If there are no channels, you can set interval to -1. -// -// The run alternates between polling/handling sockets (using the interval as timeout), -// and reading/handling channels. The reading of channels is without time-out: if there -// is no activity on any channel, the run continues to poll sockets immediately. -// -// The run exits when any handler returns an error, returning that same error. -func (r *Reactor) Run(interval time.Duration) (err error) { - for { - - // process requests to remove channels - for _, id := range r.remove { - delete(r.channels, id) - } - r.remove = r.remove[0:0] - - CHANNELS: - for id, ch := range r.channels { - limit := ch.limit - for { - select { - case val, ok := <-ch.ch: - if !ok { - if r.verbose { - fmt.Printf("Reactor(%p) removing closed channel %d\n", r, id) - } - r.RemoveChannel(id) - continue CHANNELS - } - if r.verbose { - fmt.Printf("Reactor(%p) channel %d: %q\n", r, id, val) - } - err = ch.f(val) - if err != nil { - return - } - if ch.limit > 0 { - limit-- - if limit == 0 { - continue CHANNELS - } - } - default: - continue CHANNELS - } - } - } - - if len(r.channels) > 0 && interval < 0 { - return errors.New("There are channels, but polling time-out is infinite") - } - - if len(r.sockets) == 0 { - if len(r.channels) == 0 { - return errors.New("No sockets to poll, no channels to read") - } - time.Sleep(interval) - continue - } - - polled, e := r.p.Poll(interval) - if e != nil { - return e - } - for _, item := range polled { - if r.verbose { - fmt.Printf("Reactor(%p) %v\n", r, item) - } - err = r.sockets[item.Socket].f(item.Events) - if err != nil { - return - } - } - } - return -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/socketget.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/socketget.go deleted file mode 100644 index 23933b8..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/socketget.go +++ /dev/null @@ -1,360 +0,0 @@ -package zmq4 - -/* -#include -#include -*/ -import "C" - -import ( - "strings" - "time" - "unsafe" -) - -func (soc *Socket) getString(opt C.int, bufsize int) (string, error) { - value := make([]byte, bufsize) - size := C.size_t(bufsize) - if i, err := C.zmq_getsockopt(soc.soc, opt, unsafe.Pointer(&value[0]), &size); i != 0 { - return "", errget(err) - } - return strings.TrimRight(string(value[:int(size)]), "\x00"), nil -} - -func (soc *Socket) getStringRaw(opt C.int, bufsize int) (string, error) { - value := make([]byte, bufsize) - size := C.size_t(bufsize) - if i, err := C.zmq_getsockopt(soc.soc, opt, unsafe.Pointer(&value[0]), &size); i != 0 { - return "", errget(err) - } - return string(value[:int(size)]), nil -} - -func (soc *Socket) getInt(opt C.int) (int, error) { - value := C.int(0) - size := C.size_t(unsafe.Sizeof(value)) - if i, err := C.zmq_getsockopt(soc.soc, opt, unsafe.Pointer(&value), &size); i != 0 { - return 0, errget(err) - } - return int(value), nil -} - -func (soc *Socket) getInt64(opt C.int) (int64, error) { - value := C.int64_t(0) - size := C.size_t(unsafe.Sizeof(value)) - if i, err := C.zmq_getsockopt(soc.soc, opt, unsafe.Pointer(&value), &size); i != 0 { - return 0, errget(err) - } - return int64(value), nil -} - -func (soc *Socket) getUInt64(opt C.int) (uint64, error) { - value := C.uint64_t(0) - size := C.size_t(unsafe.Sizeof(value)) - if i, err := C.zmq_getsockopt(soc.soc, opt, unsafe.Pointer(&value), &size); i != 0 { - return 0, errget(err) - } - return uint64(value), nil -} - -// ZMQ_TYPE: Retrieve socket type -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc3 -func (soc *Socket) GetType() (Type, error) { - v, err := soc.getInt(C.ZMQ_TYPE) - return Type(v), err -} - -// ZMQ_RCVMORE: More message data parts to follow -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc4 -func (soc *Socket) GetRcvmore() (bool, error) { - v, err := soc.getInt(C.ZMQ_RCVMORE) - return v != 0, err -} - -// ZMQ_SNDHWM: Retrieves high water mark for outbound messages -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc5 -func (soc *Socket) GetSndhwm() (int, error) { - return soc.getInt(C.ZMQ_SNDHWM) -} - -// ZMQ_RCVHWM: Retrieve high water mark for inbound messages -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc6 -func (soc *Socket) GetRcvhwm() (int, error) { - return soc.getInt(C.ZMQ_RCVHWM) -} - -// ZMQ_AFFINITY: Retrieve I/O thread affinity -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc7 -func (soc *Socket) GetAffinity() (uint64, error) { - return soc.getUInt64(C.ZMQ_AFFINITY) -} - -// ZMQ_IDENTITY: Retrieve socket identity -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc8 -func (soc *Socket) GetIdentity() (string, error) { - return soc.getString(C.ZMQ_IDENTITY, 256) -} - -// ZMQ_RATE: Retrieve multicast data rate -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc9 -func (soc *Socket) GetRate() (int, error) { - return soc.getInt(C.ZMQ_RATE) -} - -// ZMQ_RECOVERY_IVL: Get multicast recovery interval -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc10 -func (soc *Socket) GetRecoveryIvl() (time.Duration, error) { - v, err := soc.getInt(C.ZMQ_RECOVERY_IVL) - return time.Duration(v) * time.Millisecond, err -} - -// ZMQ_SNDBUF: Retrieve kernel transmit buffer size -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc11 -func (soc *Socket) GetSndbuf() (int, error) { - return soc.getInt(C.ZMQ_SNDBUF) -} - -// ZMQ_RCVBUF: Retrieve kernel receive buffer size -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc12 -func (soc *Socket) GetRcvbuf() (int, error) { - return soc.getInt(C.ZMQ_RCVBUF) -} - -// ZMQ_LINGER: Retrieve linger period for socket shutdown -// -// Returns time.Duration(-1) for infinite -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc13 -func (soc *Socket) GetLinger() (time.Duration, error) { - v, err := soc.getInt(C.ZMQ_LINGER) - if v < 0 { - return time.Duration(-1), err - } - return time.Duration(v) * time.Millisecond, err -} - -// ZMQ_RECONNECT_IVL: Retrieve reconnection interval -// -// Returns time.Duration(-1) for no reconnection -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc14 -func (soc *Socket) GetReconnectIvl() (time.Duration, error) { - v, err := soc.getInt(C.ZMQ_RECONNECT_IVL) - if v < 0 { - return time.Duration(-1), err - } - return time.Duration(v) * time.Millisecond, err -} - -// ZMQ_RECONNECT_IVL_MAX: Retrieve maximum reconnection interval -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc15 -func (soc *Socket) GetReconnectIvlMax() (time.Duration, error) { - v, err := soc.getInt(C.ZMQ_RECONNECT_IVL_MAX) - return time.Duration(v) * time.Millisecond, err -} - -// ZMQ_BACKLOG: Retrieve maximum length of the queue of outstanding connections -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc16 -func (soc *Socket) GetBacklog() (int, error) { - return soc.getInt(C.ZMQ_BACKLOG) -} - -// ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc17 -func (soc *Socket) GetMaxmsgsize() (int64, error) { - return soc.getInt64(C.ZMQ_MAXMSGSIZE) -} - -// ZMQ_MULTICAST_HOPS: Maximum network hops for multicast packets -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc18 -func (soc *Socket) GetMulticastHops() (int, error) { - return soc.getInt(C.ZMQ_MULTICAST_HOPS) -} - -// ZMQ_RCVTIMEO: Maximum time before a socket operation returns with EAGAIN -// -// Returns time.Duration(-1) for infinite -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc19 -func (soc *Socket) GetRcvtimeo() (time.Duration, error) { - v, err := soc.getInt(C.ZMQ_RCVTIMEO) - if v < 0 { - return time.Duration(-1), err - } - return time.Duration(v) * time.Millisecond, err -} - -// ZMQ_SNDTIMEO: Maximum time before a socket operation returns with EAGAIN -// -// Returns time.Duration(-1) for infinite -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc20 -func (soc *Socket) GetSndtimeo() (time.Duration, error) { - v, err := soc.getInt(C.ZMQ_SNDTIMEO) - if v < 0 { - return time.Duration(-1), err - } - return time.Duration(v) * time.Millisecond, err -} - -// ZMQ_IPV6: Retrieve IPv6 socket status -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc21 -func (soc *Socket) GetIpv6() (bool, error) { - v, err := soc.getInt(C.ZMQ_IPV6) - return v != 0, err -} - -// ZMQ_IMMEDIATE: Retrieve attach-on-connect value -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc23 -func (soc *Socket) GetImmediate() (bool, error) { - v, err := soc.getInt(C.ZMQ_IMMEDIATE) - return v != 0, err -} - -// ZMQ_FD: Retrieve file descriptor associated with the socket -// see socketget_unix.go and socketget_windows.go - -// ZMQ_EVENTS: Retrieve socket event state -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc25 -func (soc *Socket) GetEvents() (State, error) { - v, err := soc.getInt(C.ZMQ_EVENTS) - return State(v), err -} - -// ZMQ_LAST_ENDPOINT: Retrieve the last endpoint set -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc26 -func (soc *Socket) GetLastEndpoint() (string, error) { - return soc.getString(C.ZMQ_LAST_ENDPOINT, 1024) -} - -// ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc27 -func (soc *Socket) GetTcpKeepalive() (int, error) { - return soc.getInt(C.ZMQ_TCP_KEEPALIVE) -} - -// ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS) -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc28 -func (soc *Socket) GetTcpKeepaliveIdle() (int, error) { - return soc.getInt(C.ZMQ_TCP_KEEPALIVE_IDLE) -} - -// ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc29 -func (soc *Socket) GetTcpKeepaliveCnt() (int, error) { - return soc.getInt(C.ZMQ_TCP_KEEPALIVE_CNT) -} - -// ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc30 -func (soc *Socket) GetTcpKeepaliveIntvl() (int, error) { - return soc.getInt(C.ZMQ_TCP_KEEPALIVE_INTVL) -} - -// ZMQ_MECHANISM: Retrieve current security mechanism -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc31 -func (soc *Socket) GetMechanism() (Mechanism, error) { - v, err := soc.getInt(C.ZMQ_MECHANISM) - return Mechanism(v), err -} - -// ZMQ_PLAIN_SERVER: Retrieve current PLAIN server role -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc32 -func (soc *Socket) GetPlainServer() (int, error) { - return soc.getInt(C.ZMQ_PLAIN_SERVER) -} - -// ZMQ_PLAIN_USERNAME: Retrieve current PLAIN username -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc33 -func (soc *Socket) GetPlainUsername() (string, error) { - s, err := soc.getString(C.ZMQ_PLAIN_USERNAME, 1024) - if n := len(s); n > 0 && s[n - 1] == 0 { - s = s[:n - 1] - } - return s, err -} - -// ZMQ_PLAIN_PASSWORD: Retrieve current password -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc34 -func (soc *Socket) GetPlainPassword() (string, error) { - s, err := soc.getString(C.ZMQ_PLAIN_PASSWORD, 1024) - if n := len(s); n > 0 && s[n - 1] == 0 { - s = s[:n - 1] - } - return s, err -} - -// ZMQ_CURVE_PUBLICKEY: Retrieve current CURVE public key -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc35 -func (soc *Socket) GetCurvePublickeyRaw() (string, error) { - return soc.getStringRaw(C.ZMQ_CURVE_PUBLICKEY, 32) -} - -// ZMQ_CURVE_PUBLICKEY: Retrieve current CURVE public key -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc35 -func (soc *Socket) GetCurvePublickeykeyZ85() (string, error) { - return soc.getString(C.ZMQ_CURVE_PUBLICKEY, 41) -} - -// ZMQ_CURVE_SECRETKEY: Retrieve current CURVE secret key -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc36 -func (soc *Socket) GetCurveSecretkeyRaw() (string, error) { - return soc.getStringRaw(C.ZMQ_CURVE_SECRETKEY, 32) -} - -// ZMQ_CURVE_SECRETKEY: Retrieve current CURVE secret key -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc36 -func (soc *Socket) GetCurveSecretkeyZ85() (string, error) { - return soc.getString(C.ZMQ_CURVE_SECRETKEY, 41) -} - -// ZMQ_CURVE_SERVERKEY: Retrieve current CURVE server key -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc37 -func (soc *Socket) GetCurveServerkeyRaw() (string, error) { - return soc.getStringRaw(C.ZMQ_CURVE_SERVERKEY, 32) -} - -// ZMQ_CURVE_SERVERKEY: Retrieve current CURVE server key -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc37 -func (soc *Socket) GetCurveServerkeyZ85() (string, error) { - return soc.getString(C.ZMQ_CURVE_SERVERKEY, 41) -} - -// ZMQ_ZAP_DOMAIN: Retrieve RFC 27 authentication domain -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc38 -func (soc *Socket) GetZapDomain() (string, error) { - return soc.getString(C.ZMQ_ZAP_DOMAIN, 1024) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/socketget_unix.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/socketget_unix.go deleted file mode 100644 index 2d75320..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/socketget_unix.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build !windows - -package zmq4 - -/* -#include -*/ -import "C" - -// ZMQ_FD: Retrieve file descriptor associated with the socket -// -// See: http://api.zeromq.org/4-0:zmq-getsockopt#toc24 -func (soc *Socket) GetFd() (int, error) { - return soc.getInt(C.ZMQ_FD) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/socketget_windows.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/socketget_windows.go deleted file mode 100644 index c16bb09..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/socketget_windows.go +++ /dev/null @@ -1,26 +0,0 @@ -// +build windows - -package zmq4 - -/* -#include -*/ -import "C" - -import ( - "unsafe" -) - -/* -ZMQ_FD: Retrieve file descriptor associated with the socket - -See: http://api.zeromq.org/4-0:zmq-getsockopt#toc24 -*/ -func (soc *Socket) GetFd() (uintptr, error) { - value := C.SOCKET(0) - size := C.size_t(unsafe.Sizeof(value)) - if i, err := C.zmq_getsockopt(soc.soc, C.ZMQ_FD, unsafe.Pointer(&value), &size); i != 0 { - return uintptr(0), errget(err) - } - return uintptr(value), nil -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/socketset.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/socketset.go deleted file mode 100644 index fd25af4..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/socketset.go +++ /dev/null @@ -1,380 +0,0 @@ -package zmq4 - -/* -#include -#include -#include -*/ -import "C" - -import ( - "time" - "unsafe" -) - -func (soc *Socket) setString(opt C.int, s string) error { - cs := C.CString(s) - defer C.free(unsafe.Pointer(cs)) - if i, err := C.zmq_setsockopt(soc.soc, opt, unsafe.Pointer(cs), C.size_t(len(s))); i != 0 { - return errget(err) - } - return nil -} - -func (soc *Socket) setNullString(opt C.int) error { - if i, err := C.zmq_setsockopt(soc.soc, opt, nil, 0); i != 0 { - return errget(err) - } - return nil -} - -func (soc *Socket) setInt(opt C.int, value int) error { - val := C.int(value) - if i, err := C.zmq_setsockopt(soc.soc, opt, unsafe.Pointer(&val), C.size_t(unsafe.Sizeof(val))); i != 0 { - return errget(err) - } - return nil -} - -func (soc *Socket) setInt64(opt C.int, value int64) error { - val := C.int64_t(value) - if i, err := C.zmq_setsockopt(soc.soc, opt, unsafe.Pointer(&val), C.size_t(unsafe.Sizeof(val))); i != 0 { - return errget(err) - } - return nil -} - -func (soc *Socket) setUInt64(opt C.int, value uint64) error { - val := C.uint64_t(value) - if i, err := C.zmq_setsockopt(soc.soc, opt, unsafe.Pointer(&val), C.size_t(unsafe.Sizeof(val))); i != 0 { - return errget(err) - } - return nil -} - -// ZMQ_SNDHWM: Set high water mark for outbound messages -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc3 -func (soc *Socket) SetSndhwm(value int) error { - return soc.setInt(C.ZMQ_SNDHWM, value) -} - -// ZMQ_RCVHWM: Set high water mark for inbound messages -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc4 -func (soc *Socket) SetRcvhwm(value int) error { - return soc.setInt(C.ZMQ_RCVHWM, value) -} - -// ZMQ_AFFINITY: Set I/O thread affinity -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc5 -func (soc *Socket) SetAffinity(value uint64) error { - return soc.setUInt64(C.ZMQ_AFFINITY, value) -} - -// ZMQ_SUBSCRIBE: Establish message filter -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc6 -func (soc *Socket) SetSubscribe(filter string) error { - return soc.setString(C.ZMQ_SUBSCRIBE, filter) -} - -// ZMQ_UNSUBSCRIBE: Remove message filter -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc7 -func (soc *Socket) SetUnsubscribe(filter string) error { - return soc.setString(C.ZMQ_UNSUBSCRIBE, filter) -} - -// ZMQ_IDENTITY: Set socket identity -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc8 -func (soc *Socket) SetIdentity(value string) error { - return soc.setString(C.ZMQ_IDENTITY, value) -} - -// ZMQ_RATE: Set multicast data rate -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc9 -func (soc *Socket) SetRate(value int) error { - return soc.setInt(C.ZMQ_RATE, value) -} - -// ZMQ_RECOVERY_IVL: Set multicast recovery interval -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc10 -func (soc *Socket) SetRecoveryIvl(value time.Duration) error { - val := int(value / time.Millisecond) - return soc.setInt(C.ZMQ_RECOVERY_IVL, val) -} - -// ZMQ_SNDBUF: Set kernel transmit buffer size -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc11 -func (soc *Socket) SetSndbuf(value int) error { - return soc.setInt(C.ZMQ_SNDBUF, value) -} - -// ZMQ_RCVBUF: Set kernel receive buffer size -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc12 -func (soc *Socket) SetRcvbuf(value int) error { - return soc.setInt(C.ZMQ_RCVBUF, value) -} - -// ZMQ_LINGER: Set linger period for socket shutdown -// -// Use -1 for infinite -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc13 -func (soc *Socket) SetLinger(value time.Duration) error { - val := int(value / time.Millisecond) - if value == -1 { - val = -1 - } - return soc.setInt(C.ZMQ_LINGER, val) -} - -// ZMQ_RECONNECT_IVL: Set reconnection interval -// -// Use -1 for no reconnection -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc14 -func (soc *Socket) SetReconnectIvl(value time.Duration) error { - val := int(value / time.Millisecond) - if value == -1 { - val = -1 - } - return soc.setInt(C.ZMQ_RECONNECT_IVL, val) -} - -// ZMQ_RECONNECT_IVL_MAX: Set maximum reconnection interval -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc15 -func (soc *Socket) SetReconnectIvlMax(value time.Duration) error { - val := int(value / time.Millisecond) - return soc.setInt(C.ZMQ_RECONNECT_IVL_MAX, val) -} - -// ZMQ_BACKLOG: Set maximum length of the queue of outstanding connections -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc16 -func (soc *Socket) SetBacklog(value int) error { - return soc.setInt(C.ZMQ_BACKLOG, value) -} - -// ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc17 -func (soc *Socket) SetMaxmsgsize(value int64) error { - return soc.setInt64(C.ZMQ_MAXMSGSIZE, value) -} - -// ZMQ_MULTICAST_HOPS: Maximum network hops for multicast packets -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc18 -func (soc *Socket) SetMulticastHops(value int) error { - return soc.setInt(C.ZMQ_MULTICAST_HOPS, value) -} - -// ZMQ_RCVTIMEO: Maximum time before a recv operation returns with EAGAIN -// -// Use -1 for infinite -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc19 -func (soc *Socket) SetRcvtimeo(value time.Duration) error { - val := int(value / time.Millisecond) - if value == -1 { - val = -1 - } - return soc.setInt(C.ZMQ_RCVTIMEO, val) -} - -// ZMQ_SNDTIMEO: Maximum time before a send operation returns with EAGAIN -// -// Use -1 for infinite -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc20 -func (soc *Socket) SetSndtimeo(value time.Duration) error { - val := int(value / time.Millisecond) - if value == -1 { - val = -1 - } - return soc.setInt(C.ZMQ_SNDTIMEO, val) -} - -// ZMQ_IPV6: Enable IPv6 on socket -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc21 -func (soc *Socket) SetIpv6(value bool) error { - val := 0 - if value { - val = 1 - } - return soc.setInt(C.ZMQ_IPV6, val) -} - -// ZMQ_IMMEDIATE: Queue messages only to completed connections -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc23 -func (soc *Socket) SetImmediate(value bool) error { - val := 0 - if value { - val = 1 - } - return soc.setInt(C.ZMQ_IMMEDIATE, val) -} - -// ZMQ_ROUTER_MANDATORY: accept only routable messages on ROUTER sockets -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc24 -func (soc *Socket) SetRouterMandatory(value int) error { - return soc.setInt(C.ZMQ_ROUTER_MANDATORY, value) -} - -// ZMQ_ROUTER_RAW: switch ROUTER socket to raw mode -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc25 -func (soc *Socket) SetRouterRaw(value int) error { - return soc.setInt(C.ZMQ_ROUTER_RAW, value) -} - -// ZMQ_PROBE_ROUTER: bootstrap connections to ROUTER sockets -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc26 -func (soc *Socket) SetProbeRouter(value int) error { - return soc.setInt(C.ZMQ_PROBE_ROUTER, value) -} - -// ZMQ_XPUB_VERBOSE: provide all subscription messages on XPUB sockets -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc27 -func (soc *Socket) SetXpubVerbose(value int) error { - return soc.setInt(C.ZMQ_XPUB_VERBOSE, value) -} - -// ZMQ_REQ_CORRELATE: match replies with requests -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc28 -func (soc *Socket) SetReqCorrelate(value int) error { - return soc.setInt(C.ZMQ_REQ_CORRELATE, value) -} - -// ZMQ_REQ_RELAXED: relax strict alternation between request and reply -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc29 -func (soc *Socket) SetReqRelaxed(value int) error { - return soc.setInt(C.ZMQ_REQ_RELAXED, value) -} - -// ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc30 -func (soc *Socket) SetTcpKeepalive(value int) error { - return soc.setInt(C.ZMQ_TCP_KEEPALIVE, value) -} - -// ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS) -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc31 -func (soc *Socket) SetTcpKeepaliveIdle(value int) error { - return soc.setInt(C.ZMQ_TCP_KEEPALIVE_IDLE, value) -} - -// ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc32 -func (soc *Socket) SetTcpKeepaliveCnt(value int) error { - return soc.setInt(C.ZMQ_TCP_KEEPALIVE_CNT, value) -} - -// ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc33 -func (soc *Socket) SetTcpKeepaliveIntvl(value int) error { - return soc.setInt(C.ZMQ_TCP_KEEPALIVE_INTVL, value) -} - -// ZMQ_TCP_ACCEPT_FILTER: Assign filters to allow new TCP connections -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc34 -func (soc *Socket) SetTcpAcceptFilter(filter string) error { - if len(filter) == 0 { - return soc.setNullString(C.ZMQ_TCP_ACCEPT_FILTER) - } - return soc.setString(C.ZMQ_TCP_ACCEPT_FILTER, filter) -} - -// ZMQ_PLAIN_SERVER: Set PLAIN server role -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc35 -func (soc *Socket) SetPlainServer(value int) error { - return soc.setInt(C.ZMQ_PLAIN_SERVER, value) -} - -// ZMQ_PLAIN_USERNAME: Set PLAIN security username -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc36 -func (soc *Socket) SetPlainUsername(username string) error { - if len(username) == 0 { - return soc.setNullString(C.ZMQ_PLAIN_USERNAME) - } - return soc.setString(C.ZMQ_PLAIN_USERNAME, username) -} - -// ZMQ_PLAIN_PASSWORD: Set PLAIN security password -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc37 -func (soc *Socket) SetPlainPassword(password string) error { - if len(password) == 0 { - return soc.setNullString(C.ZMQ_PLAIN_PASSWORD) - } - return soc.setString(C.ZMQ_PLAIN_PASSWORD, password) -} - -// ZMQ_CURVE_SERVER: Set CURVE server role -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc38 -func (soc *Socket) SetCurveServer(value int) error { - return soc.setInt(C.ZMQ_CURVE_SERVER, value) -} - -// ZMQ_CURVE_PUBLICKEY: Set CURVE public key -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc39 -func (soc *Socket) SetCurvePublickey(key string) error { - return soc.setString(C.ZMQ_CURVE_PUBLICKEY, key) -} - -// ZMQ_CURVE_SECRETKEY: Set CURVE secret key -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc40 -func (soc *Socket) SetCurveSecretkey(key string) error { - return soc.setString(C.ZMQ_CURVE_SECRETKEY, key) -} - -// ZMQ_CURVE_SERVERKEY: Set CURVE server key -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc41 -func (soc *Socket) SetCurveServerkey(key string) error { - return soc.setString(C.ZMQ_CURVE_SERVERKEY, key) -} - -// ZMQ_ZAP_DOMAIN: Set RFC 27 authentication domain -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc42 -func (soc *Socket) SetZapDomain(domain string) error { - return soc.setString(C.ZMQ_ZAP_DOMAIN, domain) -} - -// ZMQ_CONFLATE: Keep only last message -// -// See: http://api.zeromq.org/4-0:zmq-setsockopt#toc43 -func (soc *Socket) SetConflate(value bool) error { - val := 0 - if value { - val = 1 - } - return soc.setInt(C.ZMQ_CONFLATE, val) -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/utils.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/utils.go deleted file mode 100644 index fed761d..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/utils.go +++ /dev/null @@ -1,183 +0,0 @@ -package zmq4 - -import ( - "fmt" -) - -/* -Send multi-part message on socket. - -Any `[]string' or `[][]byte' is split into separate `string's or `[]byte's - -Any other part that isn't a `string' or `[]byte' is converted -to `string' with `fmt.Sprintf("%v", part)'. - -Returns total bytes sent. -*/ -func (soc *Socket) SendMessage(parts ...interface{}) (total int, err error) { - return soc.sendMessage(0, parts...) -} - -/* -Like SendMessage(), but adding the DONTWAIT flag. -*/ -func (soc *Socket) SendMessageDontwait(parts ...interface{}) (total int, err error) { - return soc.sendMessage(DONTWAIT, parts...) -} - -func (soc *Socket) sendMessage(dontwait Flag, parts ...interface{}) (total int, err error) { - // TODO: make this faster - - // flatten first, just in case the last part may be an empty []string or [][]byte - pp := make([]interface{}, 0) - for _, p := range parts { - switch t := p.(type) { - case []string: - for _, s := range t { - pp = append(pp, s) - } - case [][]byte: - for _, b := range t { - pp = append(pp, b) - } - default: - pp = append(pp, t) - } - } - - n := len(pp) - if n == 0 { - return - } - opt := SNDMORE | dontwait - for i, p := range pp { - if i == n-1 { - opt = dontwait - } - switch t := p.(type) { - case string: - j, e := soc.Send(t, opt) - if e == nil { - total += j - } else { - return -1, e - } - case []byte: - j, e := soc.SendBytes(t, opt) - if e == nil { - total += j - } else { - return -1, e - } - default: - j, e := soc.Send(fmt.Sprintf("%v", t), opt) - if e == nil { - total += j - } else { - return -1, e - } - } - } - return -} - -/* -Receive parts as message from socket. - -Returns last non-nil error code. -*/ -func (soc *Socket) RecvMessage(flags Flag) (msg []string, err error) { - msg = make([]string, 0) - for { - s, e := soc.Recv(flags) - if e == nil { - msg = append(msg, s) - } else { - return msg[0:0], e - } - more, e := soc.GetRcvmore() - if e == nil { - if !more { - break - } - } else { - return msg[0:0], e - } - } - return -} - -/* -Receive parts as message from socket. - -Returns last non-nil error code. -*/ -func (soc *Socket) RecvMessageBytes(flags Flag) (msg [][]byte, err error) { - msg = make([][]byte, 0) - for { - b, e := soc.RecvBytes(flags) - if e == nil { - msg = append(msg, b) - } else { - return msg[0:0], e - } - more, e := soc.GetRcvmore() - if e == nil { - if !more { - break - } - } else { - return msg[0:0], e - } - } - return -} - -/* -Receive parts as message from socket, including metadata. - -Metadata is picked from the first message part. - -For details about metadata, see RecvWithMetadata(). - -Returns last non-nil error code. -*/ -func (soc *Socket) RecvMessageWithMetadata(flags Flag, properties ...string) (msg []string, metadata map[string]string, err error) { - b, p, err := soc.RecvMessageBytesWithMetadata(flags, properties...) - m := make([]string, len(b)) - for i, bt := range b { - m[i] = string(bt) - } - return m, p, err -} - -/* -Receive parts as message from socket, including metadata. - -Metadata is picked from the first message part. - -For details about metadata, see RecvBytesWithMetadata(). - -Returns last non-nil error code. -*/ -func (soc *Socket) RecvMessageBytesWithMetadata(flags Flag, properties ...string) (msg [][]byte, metadata map[string]string, err error) { - bb := make([][]byte, 0) - b, p, err := soc.RecvBytesWithMetadata(flags, properties...) - if err != nil { - return bb, p, err - } - for { - bb = append(bb, b) - - var more bool - more, err = soc.GetRcvmore() - if err != nil || !more { - break - } - b, err = soc.RecvBytes(flags) - if err != nil { - break - } - } - return bb, p, err -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/zmq4.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/zmq4.go deleted file mode 100644 index 781d322..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/zmq4.go +++ /dev/null @@ -1,896 +0,0 @@ -package zmq4 - -/* -#cgo !windows pkg-config: libzmq -#cgo windows CFLAGS: -I/usr/local/include -#cgo windows LDFLAGS: -L/usr/local/lib -lzmq -#include -#include -#include -#include - -#if ZMQ_VERSION_MINOR > 0 -typedef struct { - uint16_t event; // id of the event as bitfield - int32_t value ; // value is either error code, fd or reconnect interval -} zmq_event_t; -#else -const char *zmq_msg_gets (zmq_msg_t *msg, const char *property) { - return NULL; -} -#endif - -void get_event40(zmq_msg_t *msg, int *ev, int *val) { - zmq_event_t event; - const char* data = (char*)zmq_msg_data(msg); - memcpy(&(event.event), data, sizeof(event.event)); - memcpy(&(event.value), data+sizeof(event.event), sizeof(event.value)); - *ev = (int)(event.event); - *val = (int)(event.value); -} -void get_event41(zmq_msg_t *msg, int *ev, int *val) { - uint8_t *data = (uint8_t *) zmq_msg_data (msg); - uint16_t event = *(uint16_t *) (data); - *ev = (int)event; - *val = (int)(*(uint32_t *) (data + 2)); -} -void *my_memcpy(void *dest, const void *src, size_t n) { - return memcpy(dest, src, n); -} -*/ -import "C" - -import ( - "errors" - "fmt" - "runtime" - "strings" - "unsafe" -) - -var ( - defaultCtx *Context -) - -func init() { - var err error - defaultCtx = &Context{} - defaultCtx.ctx, err = C.zmq_ctx_new() - defaultCtx.opened = true - if defaultCtx.ctx == nil { - panic("Init of ZeroMQ context failed: " + errget(err).Error()) - } -} - -//. Util - -// Report 0MQ library version. -func Version() (major, minor, patch int) { - var maj, min, pat C.int - C.zmq_version(&maj, &min, &pat) - return int(maj), int(min), int(pat) -} - -// Get 0MQ error message string. -func Error(e int) string { - return C.GoString(C.zmq_strerror(C.int(e))) -} - -//. Context - -const ( - MaxSocketsDflt = int(C.ZMQ_MAX_SOCKETS_DFLT) - IoThreadsDflt = int(C.ZMQ_IO_THREADS_DFLT) -) - -/* -A context that is not the default context. -*/ -type Context struct { - ctx unsafe.Pointer - opened bool - err error -} - -// Create a new context. -func NewContext() (ctx *Context, err error) { - ctx = &Context{} - c, e := C.zmq_ctx_new() - if c == nil { - err = errget(e) - ctx.err = err - } else { - ctx.ctx = c - ctx.opened = true - runtime.SetFinalizer(ctx, (*Context).Term) - } - return -} - -/* -Terminates the default context. - -For linger behavior, see: http://api.zeromq.org/4-0:zmq-ctx-term -*/ -func Term() error { - return defaultCtx.Term() -} - -/* -Terminates the context. - -For linger behavior, see: http://api.zeromq.org/4-0:zmq-ctx-term -*/ -func (ctx *Context) Term() error { - if ctx.opened { - ctx.opened = false - n, err := C.zmq_ctx_term(ctx.ctx) - if n != 0 { - ctx.err = errget(err) - } - } - return ctx.err -} - -func getOption(ctx *Context, o C.int) (int, error) { - nc, err := C.zmq_ctx_get(ctx.ctx, o) - n := int(nc) - if n < 0 { - return n, errget(err) - } - return n, nil -} - -// Returns the size of the 0MQ thread pool in the default context. -func GetIoThreads() (int, error) { - return defaultCtx.GetIoThreads() -} - -// Returns the size of the 0MQ thread pool. -func (ctx *Context) GetIoThreads() (int, error) { - return getOption(ctx, C.ZMQ_IO_THREADS) -} - -// Returns the maximum number of sockets allowed in the default context. -func GetMaxSockets() (int, error) { - return defaultCtx.GetMaxSockets() -} - -// Returns the maximum number of sockets allowed. -func (ctx *Context) GetMaxSockets() (int, error) { - return getOption(ctx, C.ZMQ_MAX_SOCKETS) -} - -// Returns the IPv6 option in the default context. -func GetIpv6() (bool, error) { - return defaultCtx.GetIpv6() -} - -// Returns the IPv6 option. -func (ctx *Context) GetIpv6() (bool, error) { - i, e := getOption(ctx, C.ZMQ_IPV6) - if i == 0 { - return false, e - } - return true, e -} - -func setOption(ctx *Context, o C.int, n int) error { - i, err := C.zmq_ctx_set(ctx.ctx, o, C.int(n)) - if int(i) != 0 { - return errget(err) - } - return nil -} - -/* -Specifies the size of the 0MQ thread pool to handle I/O operations in -the default context. If your application is using only the inproc -transport for messaging you may set this to zero, otherwise set it to at -least one. This option only applies before creating any sockets. - -Default value 1 -*/ -func SetIoThreads(n int) error { - return defaultCtx.SetIoThreads(n) -} - -/* -Specifies the size of the 0MQ thread pool to handle I/O operations. If -your application is using only the inproc transport for messaging you -may set this to zero, otherwise set it to at least one. This option only -applies before creating any sockets. - -Default value 1 -*/ -func (ctx *Context) SetIoThreads(n int) error { - return setOption(ctx, C.ZMQ_IO_THREADS, n) -} - -/* -Sets the maximum number of sockets allowed in the default context. - -Default value 1024 -*/ -func SetMaxSockets(n int) error { - return defaultCtx.SetMaxSockets(n) -} - -/* -Sets the maximum number of sockets allowed. - -Default value 1024 -*/ -func (ctx *Context) SetMaxSockets(n int) error { - return setOption(ctx, C.ZMQ_MAX_SOCKETS, n) -} - -/* -Sets the IPv6 value for all sockets created in the default context from this point onwards. -A value of true means IPv6 is enabled, while false means the socket will use only IPv4. -When IPv6 is enabled, a socket will connect to, or accept connections from, both IPv4 and IPv6 hosts. - -Default value false -*/ -func SetIpv6(i bool) error { - return defaultCtx.SetIpv6(i) -} - -/* -Sets the IPv6 value for all sockets created in the context from this point onwards. -A value of true means IPv6 is enabled, while false means the socket will use only IPv4. -When IPv6 is enabled, a socket will connect to, or accept connections from, both IPv4 and IPv6 hosts. - -Default value false -*/ -func (ctx *Context) SetIpv6(i bool) error { - n := 0 - if i { - n = 1 - } - return setOption(ctx, C.ZMQ_IPV6, n) -} - -//. Sockets - -// Specifies the type of a socket, used by NewSocket() -type Type int - -const ( - // Constants for NewSocket() - // See: http://api.zeromq.org/4-0:zmq-socket#toc3 - REQ = Type(C.ZMQ_REQ) - REP = Type(C.ZMQ_REP) - DEALER = Type(C.ZMQ_DEALER) - ROUTER = Type(C.ZMQ_ROUTER) - PUB = Type(C.ZMQ_PUB) - SUB = Type(C.ZMQ_SUB) - XPUB = Type(C.ZMQ_XPUB) - XSUB = Type(C.ZMQ_XSUB) - PUSH = Type(C.ZMQ_PUSH) - PULL = Type(C.ZMQ_PULL) - PAIR = Type(C.ZMQ_PAIR) - STREAM = Type(C.ZMQ_STREAM) -) - -/* -Socket type as string. -*/ -func (t Type) String() string { - switch t { - case REQ: - return "REQ" - case REP: - return "REP" - case DEALER: - return "DEALER" - case ROUTER: - return "ROUTER" - case PUB: - return "PUB" - case SUB: - return "SUB" - case XPUB: - return "XPUB" - case XSUB: - return "XSUB" - case PUSH: - return "PUSH" - case PULL: - return "PULL" - case PAIR: - return "PAIR" - case STREAM: - return "STREAM" - } - return "" -} - -// Used by (*Socket)Send() and (*Socket)Recv() -type Flag int - -const ( - // Flags for (*Socket)Send(), (*Socket)Recv() - // For Send, see: http://api.zeromq.org/4-0:zmq-send#toc2 - // For Recv, see: http://api.zeromq.org/4-0:zmq-msg-recv#toc2 - DONTWAIT = Flag(C.ZMQ_DONTWAIT) - SNDMORE = Flag(C.ZMQ_SNDMORE) -) - -/* -Socket flag as string. -*/ -func (f Flag) String() string { - ff := make([]string, 0) - if f&DONTWAIT != 0 { - ff = append(ff, "DONTWAIT") - } - if f&SNDMORE != 0 { - ff = append(ff, "SNDMORE") - } - if len(ff) == 0 { - return "" - } - return strings.Join(ff, "|") -} - -// Used by (*Socket)Monitor() and (*Socket)RecvEvent() -type Event int - -const ( - // Flags for (*Socket)Monitor() and (*Socket)RecvEvent() - // See: http://api.zeromq.org/4-0:zmq-socket-monitor#toc3 - EVENT_ALL = Event(C.ZMQ_EVENT_ALL) - EVENT_CONNECTED = Event(C.ZMQ_EVENT_CONNECTED) - EVENT_CONNECT_DELAYED = Event(C.ZMQ_EVENT_CONNECT_DELAYED) - EVENT_CONNECT_RETRIED = Event(C.ZMQ_EVENT_CONNECT_RETRIED) - EVENT_LISTENING = Event(C.ZMQ_EVENT_LISTENING) - EVENT_BIND_FAILED = Event(C.ZMQ_EVENT_BIND_FAILED) - EVENT_ACCEPTED = Event(C.ZMQ_EVENT_ACCEPTED) - EVENT_ACCEPT_FAILED = Event(C.ZMQ_EVENT_ACCEPT_FAILED) - EVENT_CLOSED = Event(C.ZMQ_EVENT_CLOSED) - EVENT_CLOSE_FAILED = Event(C.ZMQ_EVENT_CLOSE_FAILED) - EVENT_DISCONNECTED = Event(C.ZMQ_EVENT_DISCONNECTED) - EVENT_MONITOR_STOPPED = Event(C.ZMQ_EVENT_MONITOR_STOPPED) -) - -/* -Socket event as string. -*/ -func (e Event) String() string { - if e == EVENT_ALL { - return "EVENT_ALL" - } - ee := make([]string, 0) - if e&EVENT_CONNECTED != 0 { - ee = append(ee, "EVENT_CONNECTED") - } - if e&EVENT_CONNECT_DELAYED != 0 { - ee = append(ee, "EVENT_CONNECT_DELAYED") - } - if e&EVENT_CONNECT_RETRIED != 0 { - ee = append(ee, "EVENT_CONNECT_RETRIED") - } - if e&EVENT_LISTENING != 0 { - ee = append(ee, "EVENT_LISTENING") - } - if e&EVENT_BIND_FAILED != 0 { - ee = append(ee, "EVENT_BIND_FAILED") - } - if e&EVENT_ACCEPTED != 0 { - ee = append(ee, "EVENT_ACCEPTED") - } - if e&EVENT_ACCEPT_FAILED != 0 { - ee = append(ee, "EVENT_ACCEPT_FAILED") - } - if e&EVENT_CLOSED != 0 { - ee = append(ee, "EVENT_CLOSED") - } - if e&EVENT_CLOSE_FAILED != 0 { - ee = append(ee, "EVENT_CLOSE_FAILED") - } - if e&EVENT_DISCONNECTED != 0 { - ee = append(ee, "EVENT_DISCONNECTED") - } - if len(ee) == 0 { - return "" - } - return strings.Join(ee, "|") -} - -// Used by (soc *Socket)GetEvents() -type State int - -const ( - // Flags for (*Socket)GetEvents() - // See: http://api.zeromq.org/4-0:zmq-getsockopt#toc25 - POLLIN = State(C.ZMQ_POLLIN) - POLLOUT = State(C.ZMQ_POLLOUT) -) - -/* -Socket state as string. -*/ -func (s State) String() string { - ss := make([]string, 0) - if s&POLLIN != 0 { - ss = append(ss, "POLLIN") - } - if s&POLLOUT != 0 { - ss = append(ss, "POLLOUT") - } - if len(ss) == 0 { - return "" - } - return strings.Join(ss, "|") -} - -// Specifies the security mechanism, used by (*Socket)GetMechanism() -type Mechanism int - -const ( - // Constants for (*Socket)GetMechanism() - // See: http://api.zeromq.org/4-0:zmq-getsockopt#toc31 - NULL = Mechanism(C.ZMQ_NULL) - PLAIN = Mechanism(C.ZMQ_PLAIN) - CURVE = Mechanism(C.ZMQ_CURVE) -) - -/* -Security mechanism as string. -*/ -func (m Mechanism) String() string { - switch m { - case NULL: - return "NULL" - case PLAIN: - return "PLAIN" - case CURVE: - return "CURVE" - } - return "" -} - -/* -Socket functions starting with `Set` or `Get` are used for setting and -getting socket options. -*/ -type Socket struct { - soc unsafe.Pointer - ctx *Context - opened bool - err error -} - -/* -Socket as string. -*/ -func (soc Socket) String() string { - t, _ := soc.GetType() - i, err := soc.GetIdentity() - if err == nil && i != "" { - return fmt.Sprintf("Socket(%v,%q)", t, i) - } - return fmt.Sprintf("Socket(%v,%p)", t, soc.soc) -} - -/* -Create 0MQ socket in the default context. - -WARNING: -The Socket is not thread safe. This means that you cannot access the same Socket -from different goroutines without using something like a mutex. - -For a description of socket types, see: http://api.zeromq.org/4-0:zmq-socket#toc3 -*/ -func NewSocket(t Type) (soc *Socket, err error) { - return defaultCtx.NewSocket(t) -} - -/* -Create 0MQ socket in the given context. - -WARNING: -The Socket is not thread safe. This means that you cannot access the same Socket -from different goroutines without using something like a mutex. - -For a description of socket types, see: http://api.zeromq.org/4-0:zmq-socket#toc3 -*/ -func (ctx *Context) NewSocket(t Type) (soc *Socket, err error) { - soc = &Socket{} - s, e := C.zmq_socket(ctx.ctx, C.int(t)) - if s == nil { - err = errget(e) - soc.err = err - } else { - soc.soc = s - soc.ctx = ctx - soc.opened = true - runtime.SetFinalizer(soc, (*Socket).Close) - } - return -} - -// If not called explicitly, the socket will be closed on garbage collection -func (soc *Socket) Close() error { - if soc.opened { - soc.opened = false - if i, err := C.zmq_close(soc.soc); int(i) != 0 { - soc.err = errget(err) - } - soc.soc = unsafe.Pointer(nil) - soc.ctx = nil - } - return soc.err -} - -/* -Accept incoming connections on a socket. - -For a description of endpoint, see: http://api.zeromq.org/4-0:zmq-bind#toc2 -*/ -func (soc *Socket) Bind(endpoint string) error { - s := C.CString(endpoint) - defer C.free(unsafe.Pointer(s)) - if i, err := C.zmq_bind(soc.soc, s); int(i) != 0 { - return errget(err) - } - return nil -} - -/* -Stop accepting connections on a socket. - -For a description of endpoint, see: http://api.zeromq.org/4-0:zmq-bind#toc2 -*/ -func (soc *Socket) Unbind(endpoint string) error { - s := C.CString(endpoint) - defer C.free(unsafe.Pointer(s)) - if i, err := C.zmq_unbind(soc.soc, s); int(i) != 0 { - return errget(err) - } - return nil -} - -/* -Create outgoing connection from socket. - -For a description of endpoint, see: http://api.zeromq.org/4-0:zmq-connect#toc2 -*/ -func (soc *Socket) Connect(endpoint string) error { - s := C.CString(endpoint) - defer C.free(unsafe.Pointer(s)) - if i, err := C.zmq_connect(soc.soc, s); int(i) != 0 { - return errget(err) - } - return nil -} - -/* -Disconnect a socket. - -For a description of endpoint, see: http://api.zeromq.org/4-0:zmq-connect#toc2 -*/ -func (soc *Socket) Disconnect(endpoint string) error { - s := C.CString(endpoint) - defer C.free(unsafe.Pointer(s)) - if i, err := C.zmq_disconnect(soc.soc, s); int(i) != 0 { - return errget(err) - } - return nil -} - -/* -Receive a message part from a socket. - -For a description of flags, see: http://api.zeromq.org/4-0:zmq-msg-recv#toc2 -*/ -func (soc *Socket) Recv(flags Flag) (string, error) { - b, err := soc.RecvBytes(flags) - return string(b), err -} - -/* -Receive a message part from a socket. - -For a description of flags, see: http://api.zeromq.org/4-0:zmq-msg-recv#toc2 -*/ -func (soc *Socket) RecvBytes(flags Flag) ([]byte, error) { - var msg C.zmq_msg_t - if i, err := C.zmq_msg_init(&msg); i != 0 { - return []byte{}, errget(err) - } - defer C.zmq_msg_close(&msg) - - size, err := C.zmq_msg_recv(&msg, soc.soc, C.int(flags)) - if size < 0 { - return []byte{}, errget(err) - } - if size == 0 { - return []byte{}, nil - } - data := make([]byte, int(size)) - C.my_memcpy(unsafe.Pointer(&data[0]), C.zmq_msg_data(&msg), C.size_t(size)) - return data, nil -} - -/* -Send a message part on a socket. - -For a description of flags, see: http://api.zeromq.org/4-0:zmq-send#toc2 -*/ -func (soc *Socket) Send(data string, flags Flag) (int, error) { - return soc.SendBytes([]byte(data), flags) -} - -/* -Send a message part on a socket. - -For a description of flags, see: http://api.zeromq.org/4-0:zmq-send#toc2 -*/ -func (soc *Socket) SendBytes(data []byte, flags Flag) (int, error) { - d := data - if len(data) == 0 { - d = []byte{0} - } - size, err := C.zmq_send(soc.soc, unsafe.Pointer(&d[0]), C.size_t(len(data)), C.int(flags)) - if size < 0 { - return int(size), errget(err) - } - return int(size), nil -} - -/* -Register a monitoring callback. - -See: http://api.zeromq.org/4-0:zmq-socket-monitor#toc2 - -Example: - - package main - - import ( - zmq "github.com/pebbe/zmq4" - "log" - "time" - ) - - func rep_socket_monitor(addr string) { - s, err := zmq.NewSocket(zmq.PAIR) - if err != nil { - log.Fatalln(err) - } - err = s.Connect(addr) - if err != nil { - log.Fatalln(err) - } - for { - a, b, c, err := s.RecvEvent(0) - if err != nil { - log.Println(err) - break - } - log.Println(a, b, c) - } - s.Close() - } - - func main() { - - // REP socket - rep, err := zmq.NewSocket(zmq.REP) - if err != nil { - log.Fatalln(err) - } - - // REP socket monitor, all events - err = rep.Monitor("inproc://monitor.rep", zmq.EVENT_ALL) - if err != nil { - log.Fatalln(err) - } - go rep_socket_monitor("inproc://monitor.rep") - - // Generate an event - rep.Bind("tcp://*:5555") - if err != nil { - log.Fatalln(err) - } - - // Allow some time for event detection - time.Sleep(time.Second) - - rep.Close() - zmq.Term() - } -*/ -func (soc *Socket) Monitor(addr string, events Event) error { - s := C.CString(addr) - defer C.free(unsafe.Pointer(s)) - if i, err := C.zmq_socket_monitor(soc.soc, s, C.int(events)); i != 0 { - return errget(err) - } - return nil -} - -/* -Receive a message part from a socket interpreted as an event. - -For a description of flags, see: http://api.zeromq.org/4-0:zmq-msg-recv#toc2 - -For a description of event_type, see: http://api.zeromq.org/4-0:zmq-socket-monitor#toc3 - -For an example, see: func (*Socket) Monitor -*/ -func (soc *Socket) RecvEvent(flags Flag) (event_type Event, addr string, value int, err error) { - - var msg C.zmq_msg_t - if i, e := C.zmq_msg_init(&msg); i != 0 { - err = errget(e) - return - } - defer C.zmq_msg_close(&msg) - size, e := C.zmq_msg_recv(&msg, soc.soc, C.int(flags)) - if size < 0 { - err = errget(e) - return - } - et := C.int(0) - val := C.int(0) - - if _, minor, _ := Version(); minor == 0 { - C.get_event40(&msg, &et, &val) - } else { - C.get_event41(&msg, &et, &val) - } - more, e := soc.GetRcvmore() - if e != nil { - err = errget(e) - return - } - if !more { - err = errors.New("More expected") - return - } - addr, e = soc.Recv(flags) - if e != nil { - err = errget(e) - return - } - - event_type = Event(et) - value = int(val) - - return -} - -/* -Start built-in ØMQ proxy - -See: http://api.zeromq.org/4-0:zmq-proxy#toc2 -*/ -func Proxy(frontend, backend, capture *Socket) error { - var capt unsafe.Pointer - if capture != nil { - capt = capture.soc - } - _, err := C.zmq_proxy(frontend.soc, backend.soc, capt) - return errget(err) -} - -//. CURVE - -/* -Encode a binary key as Z85 printable text - -See: http://api.zeromq.org/4-0:zmq-z85-encode -*/ -func Z85encode(data string) string { - l1 := len(data) - if l1%4 != 0 { - panic("Z85encode: Length of data not a multiple of 4") - } - d := []byte(data) - - l2 := 5 * l1 / 4 - dest := make([]byte, l2+1) - - C.zmq_z85_encode((*C.char)(unsafe.Pointer(&dest[0])), (*C.uint8_t)(&d[0]), C.size_t(l1)) - - return string(dest[:l2]) -} - -/* -Decode a binary key from Z85 printable text - -See: http://api.zeromq.org/4-0:zmq-z85-decode -*/ -func Z85decode(s string) string { - l1 := len(s) - if l1%5 != 0 { - panic("Z85decode: Length of Z85 string not a multiple of 5") - } - l2 := 4 * l1 / 5 - dest := make([]byte, l2) - cs := C.CString(s) - defer C.free(unsafe.Pointer(cs)) - C.zmq_z85_decode((*C.uint8_t)(&dest[0]), cs) - return string(dest) -} - -/* -Generate a new CURVE keypair - -See: http://api.zeromq.org/4-0:zmq-curve-keypair -*/ -func NewCurveKeypair() (z85_public_key, z85_secret_key string, err error) { - var pubkey, seckey [41]byte - if i, err := C.zmq_curve_keypair((*C.char)(unsafe.Pointer(&pubkey[0])), (*C.char)(unsafe.Pointer(&seckey[0]))); i != 0 { - return "", "", errget(err) - } - return string(pubkey[:40]), string(seckey[:40]), nil -} - -/* -Receive a message part with metadata. - -Metadata is added to messages that go through the 0MQ security mechanism. -Standard metadata properties are: Identity, Socket-Type, User-Id. - -This requires ZeroMQ version 4.1.0. Lower versions will return the message part without metadata. - -The returned metadata map contains only those properties that exist on the message. - -For a description of flags, see: http://api.zeromq.org/4-0:zmq-msg-recv#toc2 - -For a description of metadata, see: http://api.zeromq.org/4-1:zmq-msg-gets#toc3 -*/ -func (soc *Socket) RecvWithMetadata(flags Flag, properties ...string) (msg string, metadata map[string]string, err error) { - b, p, err := soc.RecvBytesWithMetadata(flags, properties...) - return string(b), p, err -} - -/* -Receive a message part with metadata. - -Metadata is added to messages that go through the 0MQ security mechanism. -Standard metadata properties are: Identity, Socket-Type, User-Id. - -This requires ZeroMQ version 4.1.0. Lower versions will return the message part without metadata. - -The returned metadata map contains only those properties that exist on the message. - -For a description of flags, see: http://api.zeromq.org/4-0:zmq-msg-recv#toc2 - -For a description of metadata, see: http://api.zeromq.org/4-1:zmq-msg-gets#toc3 -*/ -func (soc *Socket) RecvBytesWithMetadata(flags Flag, properties ...string) (msg []byte, metadata map[string]string, err error) { - metadata = make(map[string]string) - - var m C.zmq_msg_t - if i, err := C.zmq_msg_init(&m); i != 0 { - return []byte{}, metadata, errget(err) - } - defer C.zmq_msg_close(&m) - - size, err := C.zmq_msg_recv(&m, soc.soc, C.int(flags)) - if size < 0 { - return []byte{}, metadata, errget(err) - } - - data := make([]byte, int(size)) - if size > 0 { - C.my_memcpy(unsafe.Pointer(&data[0]), C.zmq_msg_data(&m), C.size_t(size)) - } - - if _, minor, _ := Version(); minor > 0 { - for _, p := range properties { - ps := C.CString(p) - s, err := C.zmq_msg_gets(&m, ps) - if err == nil { - metadata[p] = C.GoString(s) - } - C.free(unsafe.Pointer(ps)) - } - } - return data, metadata, nil -} diff --git a/Godeps/_workspace/src/github.com/pebbe/zmq4/zmq4_test.go b/Godeps/_workspace/src/github.com/pebbe/zmq4/zmq4_test.go deleted file mode 100644 index 1b805bc..0000000 --- a/Godeps/_workspace/src/github.com/pebbe/zmq4/zmq4_test.go +++ /dev/null @@ -1,1897 +0,0 @@ -package zmq4_test - -import ( - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" - - "errors" - "fmt" - "runtime" - "strconv" - "time" -) - -func Example_multiple_contexts() { - chQuit := make(chan interface{}) - chReactor := make(chan bool) - - addr1 := "tcp://127.0.0.1:9997" - addr2 := "tcp://127.0.0.1:9998" - - serv_ctx1, err := zmq.NewContext() - if checkErr(err) { - return - } - serv1, err := serv_ctx1.NewSocket(zmq.REP) - if checkErr(err) { - return - } - err = serv1.Bind(addr1) - if checkErr(err) { - return - } - defer func() { - serv1.Close() - serv_ctx1.Term() - }() - - serv_ctx2, err := zmq.NewContext() - if checkErr(err) { - return - } - serv2, err := serv_ctx2.NewSocket(zmq.REP) - if checkErr(err) { - return - } - err = serv2.Bind(addr2) - if checkErr(err) { - return - } - defer func() { - serv2.Close() - serv_ctx2.Term() - }() - - new_service := func(sock *zmq.Socket, addr string) { - socket_handler := func(state zmq.State) error { - msg, err := sock.RecvMessage(0) - if checkErr(err) { - return err - } - _, err = sock.SendMessage(addr, msg) - if checkErr(err) { - return err - } - return nil - } - quit_handler := func(interface{}) error { - return errors.New("quit") - } - - defer func() { - chReactor <- true - }() - - reactor := zmq.NewReactor() - reactor.AddSocket(sock, zmq.POLLIN, socket_handler) - reactor.AddChannel(chQuit, 1, quit_handler) - err = reactor.Run(100 * time.Millisecond) - fmt.Println(err) - } - - go new_service(serv1, addr1) - go new_service(serv2, addr2) - - time.Sleep(time.Second) - - // default context - - sock1, err := zmq.NewSocket(zmq.REQ) - if checkErr(err) { - return - } - sock2, err := zmq.NewSocket(zmq.REQ) - if checkErr(err) { - return - } - err = sock1.Connect(addr1) - if checkErr(err) { - return - } - err = sock2.Connect(addr2) - if checkErr(err) { - return - } - _, err = sock1.SendMessage(addr1) - if checkErr(err) { - return - } - _, err = sock2.SendMessage(addr2) - if checkErr(err) { - return - } - msg, err := sock1.RecvMessage(0) - fmt.Println(err, msg) - msg, err = sock2.RecvMessage(0) - fmt.Println(err, msg) - err = sock1.Close() - if checkErr(err) { - return - } - err = sock2.Close() - if checkErr(err) { - return - } - - // non-default contexts - - ctx1, err := zmq.NewContext() - if checkErr(err) { - return - } - ctx2, err := zmq.NewContext() - if checkErr(err) { - return - } - sock1, err = ctx1.NewSocket(zmq.REQ) - if checkErr(err) { - return - } - sock2, err = ctx2.NewSocket(zmq.REQ) - if checkErr(err) { - return - } - err = sock1.Connect(addr1) - if checkErr(err) { - return - } - err = sock2.Connect(addr2) - if checkErr(err) { - return - } - _, err = sock1.SendMessage(addr1) - if checkErr(err) { - return - } - _, err = sock2.SendMessage(addr2) - if checkErr(err) { - return - } - msg, err = sock1.RecvMessage(0) - fmt.Println(err, msg) - msg, err = sock2.RecvMessage(0) - fmt.Println(err, msg) - err = sock1.Close() - if checkErr(err) { - return - } - err = sock2.Close() - if checkErr(err) { - return - } - - err = ctx1.Term() - if checkErr(err) { - return - } - err = ctx2.Term() - if checkErr(err) { - return - } - - // close(chQuit) doesn't work because the reactor removes closed channels, instead of acting on them - chQuit <- true - <-chReactor - chQuit <- true - <-chReactor - - fmt.Println("Done") - // Output: - // [tcp://127.0.0.1:9997 tcp://127.0.0.1:9997] - // [tcp://127.0.0.1:9998 tcp://127.0.0.1:9998] - // [tcp://127.0.0.1:9997 tcp://127.0.0.1:9997] - // [tcp://127.0.0.1:9998 tcp://127.0.0.1:9998] - // quit - // quit - // Done -} - -func Example_test_abstract_ipc() { - sb, err := zmq.NewSocket(zmq.PAIR) - if checkErr(err) { - return - } - - err = sb.Bind("ipc://@/tmp/tester") - if checkErr(err) { - return - } - - endpoint, err := sb.GetLastEndpoint() - if checkErr(err) { - return - } - fmt.Printf("%q\n", endpoint) - - sc, err := zmq.NewSocket(zmq.PAIR) - if checkErr(err) { - return - } - err = sc.Connect("ipc://@/tmp/tester") - if checkErr(err) { - return - } - - bounce(sb, sc) - - err = sc.Close() - if checkErr(err) { - return - } - - err = sb.Close() - if checkErr(err) { - return - } - - fmt.Println("Done") - // Output: - // "ipc://@/tmp/tester" - // Done -} - -func Example_test_conflate() { - - bind_to := "tcp://127.0.0.1:5555" - - err := zmq.SetIoThreads(1) - if checkErr(err) { - return - } - - s_in, err := zmq.NewSocket(zmq.PULL) - if checkErr(err) { - return - } - - err = s_in.SetConflate(true) - if checkErr(err) { - return - } - - err = s_in.Bind(bind_to) - if checkErr(err) { - return - } - - s_out, err := zmq.NewSocket(zmq.PUSH) - if checkErr(err) { - return - } - - err = s_out.Connect(bind_to) - if checkErr(err) { - return - } - - message_count := 20 - - for j := 0; j < message_count; j++ { - _, err = s_out.Send(fmt.Sprint(j), 0) - if checkErr(err) { - return - } - } - - time.Sleep(time.Second) - - payload_recved, err := s_in.Recv(0) - if checkErr(err) { - return - } - i, err := strconv.Atoi(payload_recved) - if checkErr(err) { - return - } - if i != message_count-1 { - checkErr(errors.New("payload_recved != message_count - 1")) - return - } - - err = s_in.Close() - if checkErr(err) { - return - } - - err = s_out.Close() - if checkErr(err) { - return - } - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_connect_resolve() { - - sock, err := zmq.NewSocket(zmq.PUB) - if checkErr(err) { - return - } - - err = sock.Connect("tcp://localhost:1234") - checkErr(err) - - err = sock.Connect("tcp://localhost:invalid") - fmt.Println(err) - - err = sock.Connect("tcp://in val id:1234") - fmt.Println(err) - - err = sock.Connect("invalid://localhost:1234") - fmt.Println(err) - - err = sock.Close() - checkErr(err) - - fmt.Println("Done") - // Output: - // invalid argument - // invalid argument - // protocol not supported - // Done -} - -/* - -func Example_test_ctx_destroy() { - - fmt.Println("Done") - // Output: - // Done -} - -*/ - -func Example_test_ctx_options() { - - i, err := zmq.GetMaxSockets() - fmt.Println(i == zmq.MaxSocketsDflt, err) - i, err = zmq.GetIoThreads() - fmt.Println(i == zmq.IoThreadsDflt, err) - b, err := zmq.GetIpv6() - fmt.Println(b, err) - - zmq.SetIpv6(true) - b, err = zmq.GetIpv6() - fmt.Println(b, err) - - router, _ := zmq.NewSocket(zmq.ROUTER) - b, err = router.GetIpv6() - fmt.Println(b, err) - - fmt.Println(router.Close()) - - zmq.SetIpv6(false) - - fmt.Println("Done") - // Output: - // true - // true - // false - // true - // true - // - // Done -} - -func Example_test_disconnect_inproc() { - - publicationsReceived := 0 - isSubscribed := false - - pubSocket, err := zmq.NewSocket(zmq.XPUB) - if checkErr(err) { - return - } - subSocket, err := zmq.NewSocket(zmq.SUB) - if checkErr(err) { - return - } - err = subSocket.SetSubscribe("foo") - if checkErr(err) { - return - } - - err = pubSocket.Bind("inproc://someInProcDescriptor") - if checkErr(err) { - return - } - - iteration := 0 - - poller := zmq.NewPoller() - poller.Add(subSocket, zmq.POLLIN) // read publications - poller.Add(pubSocket, zmq.POLLIN) // read subscriptions - for { - sockets, err := poller.Poll(100 * time.Millisecond) - if checkErr(err) { - break // Interrupted - } - - for _, socket := range sockets { - if socket.Socket == pubSocket { - for { - buffer, err := pubSocket.Recv(0) - if checkErr(err) { - return - } - fmt.Printf("pubSocket: %q\n", buffer) - - if buffer[0] == 0 { - fmt.Println("pubSocket, isSubscribed == true:", isSubscribed == true) - isSubscribed = false - } else { - fmt.Println("pubSocket, isSubscribed == false:", isSubscribed == false) - isSubscribed = true - } - - more, err := pubSocket.GetRcvmore() - if checkErr(err) { - return - } - if !more { - break // Last message part - } - } - break - } - } - - for _, socket := range sockets { - if socket.Socket == subSocket { - for { - msg, err := subSocket.Recv(0) - if checkErr(err) { - return - } - fmt.Printf("subSocket: %q\n", msg) - more, err := subSocket.GetRcvmore() - if checkErr(err) { - return - } - if !more { - publicationsReceived++ - break // Last message part - } - - } - break - } - } - - if iteration == 1 { - err := subSocket.Connect("inproc://someInProcDescriptor") - checkErr(err) - } - if iteration == 4 { - err := subSocket.Disconnect("inproc://someInProcDescriptor") - checkErr(err) - } - if iteration > 4 && len(sockets) == 0 { - break - } - - _, err = pubSocket.Send("foo", zmq.SNDMORE) - checkErr(err) - _, err = pubSocket.Send("this is foo!", 0) - checkErr(err) - - iteration++ - - } - - fmt.Println("publicationsReceived == 3:", publicationsReceived == 3) - fmt.Println("!isSubscribed:", !isSubscribed) - - err = pubSocket.Close() - checkErr(err) - err = subSocket.Close() - checkErr(err) - - fmt.Println("Done") - // Output: - // pubSocket: "\x01foo" - // pubSocket, isSubscribed == false: true - // subSocket: "foo" - // subSocket: "this is foo!" - // subSocket: "foo" - // subSocket: "this is foo!" - // subSocket: "foo" - // subSocket: "this is foo!" - // pubSocket: "\x00foo" - // pubSocket, isSubscribed == true: true - // publicationsReceived == 3: true - // !isSubscribed: true - // Done -} - -func Example_test_fork() { - - address := "tcp://127.0.0.1:6571" - NUM_MESSAGES := 5 - - // Create and bind pull socket to receive messages - pull, err := zmq.NewSocket(zmq.PULL) - if checkErr(err) { - return - } - err = pull.Bind(address) - if checkErr(err) { - return - } - - done := make(chan bool) - - go func() { - defer func() { done <- true }() - - // Create new socket, connect and send some messages - - push, err := zmq.NewSocket(zmq.PUSH) - if checkErr(err) { - return - } - defer func() { - err := push.Close() - checkErr(err) - }() - - err = push.Connect(address) - if checkErr(err) { - return - } - - for count := 0; count < NUM_MESSAGES; count++ { - _, err = push.Send("Hello", 0) - if checkErr(err) { - return - } - } - - }() - - for count := 0; count < NUM_MESSAGES; count++ { - msg, err := pull.Recv(0) - fmt.Printf("%q %v\n", msg, err) - } - - err = pull.Close() - checkErr(err) - - <-done - - fmt.Println("Done") - // Output: - // "Hello" - // "Hello" - // "Hello" - // "Hello" - // "Hello" - // Done -} - -func Example_test_hwm() { - - MAX_SENDS := 10000 - BIND_FIRST := 1 - CONNECT_FIRST := 2 - - test_defaults := func() int { - - // Set up bind socket - bind_socket, err := zmq.NewSocket(zmq.PULL) - if checkErr(err) { - return 0 - } - defer func() { - err := bind_socket.Close() - checkErr(err) - }() - - err = bind_socket.Bind("inproc://a") - if checkErr(err) { - return 0 - } - - // Set up connect socket - connect_socket, err := zmq.NewSocket(zmq.PUSH) - if checkErr(err) { - return 0 - } - defer func() { - err := connect_socket.Close() - checkErr(err) - }() - - err = connect_socket.Connect("inproc://a") - if checkErr(err) { - return 0 - } - - // Send until we block - send_count := 0 - for send_count < MAX_SENDS { - _, err := connect_socket.Send("", zmq.DONTWAIT) - if err != nil { - fmt.Println("Send:", err) - break - } - send_count++ - } - - // Now receive all sent messages - recv_count := 0 - for { - _, err := bind_socket.Recv(zmq.DONTWAIT) - if err != nil { - fmt.Println("Recv:", err) - break - } - recv_count++ - } - fmt.Println("send_count == recv_count:", send_count == recv_count) - - return send_count - } - - count_msg := func(send_hwm, recv_hwm, testType int) int { - - var bind_socket, connect_socket *zmq.Socket - var err error - - if testType == BIND_FIRST { - // Set up bind socket - bind_socket, err = zmq.NewSocket(zmq.PULL) - if checkErr(err) { - return 0 - } - defer func() { - err := bind_socket.Close() - checkErr(err) - }() - - err = bind_socket.SetRcvhwm(recv_hwm) - if checkErr(err) { - return 0 - } - - err = bind_socket.Bind("inproc://a") - if checkErr(err) { - return 0 - } - - // Set up connect socket - connect_socket, err = zmq.NewSocket(zmq.PUSH) - if checkErr(err) { - return 0 - } - defer func() { - err := connect_socket.Close() - checkErr(err) - }() - - err = connect_socket.SetSndhwm(send_hwm) - if checkErr(err) { - return 0 - } - - err = connect_socket.Connect("inproc://a") - if checkErr(err) { - return 0 - } - } else { - // Set up connect socket - connect_socket, err = zmq.NewSocket(zmq.PUSH) - if checkErr(err) { - return 0 - } - defer func() { - err := connect_socket.Close() - checkErr(err) - }() - - err = connect_socket.SetSndhwm(send_hwm) - if checkErr(err) { - return 0 - } - - err = connect_socket.Connect("inproc://a") - if checkErr(err) { - return 0 - } - - // Set up bind socket - bind_socket, err = zmq.NewSocket(zmq.PULL) - if checkErr(err) { - return 0 - } - defer func() { - err := bind_socket.Close() - checkErr(err) - }() - - err = bind_socket.SetRcvhwm(recv_hwm) - if checkErr(err) { - return 0 - } - - err = bind_socket.Bind("inproc://a") - if checkErr(err) { - return 0 - } - } - - // Send until we block - send_count := 0 - for send_count < MAX_SENDS { - _, err := connect_socket.Send("", zmq.DONTWAIT) - if err != nil { - fmt.Println("Send:", err) - break - } - send_count++ - } - - // Now receive all sent messages - recv_count := 0 - for { - _, err := bind_socket.Recv(zmq.DONTWAIT) - if err != nil { - fmt.Println("Recv:", err) - break - } - recv_count++ - } - fmt.Println("send_count == recv_count:", send_count == recv_count) - - // Now it should be possible to send one more. - _, err = connect_socket.Send("", 0) - if checkErr(err) { - return 0 - } - - // Consume the remaining message. - _, err = bind_socket.Recv(0) - checkErr(err) - - return send_count - } - - test_inproc_bind_first := func(send_hwm, recv_hwm int) int { - return count_msg(send_hwm, recv_hwm, BIND_FIRST) - } - - test_inproc_connect_first := func(send_hwm, recv_hwm int) int { - return count_msg(send_hwm, recv_hwm, CONNECT_FIRST) - } - - test_inproc_connect_and_close_first := func(send_hwm, recv_hwm int) int { - - // Set up connect socket - connect_socket, err := zmq.NewSocket(zmq.PUSH) - if checkErr(err) { - return 0 - } - - err = connect_socket.SetSndhwm(send_hwm) - if checkErr(err) { - connect_socket.Close() - return 0 - } - - err = connect_socket.Connect("inproc://a") - if checkErr(err) { - connect_socket.Close() - return 0 - } - - // Send until we block - send_count := 0 - for send_count < MAX_SENDS { - _, err := connect_socket.Send("", zmq.DONTWAIT) - if err != nil { - fmt.Println("Send:", err) - break - } - send_count++ - } - - // Close connect - err = connect_socket.Close() - if checkErr(err) { - return 0 - } - - // Set up bind socket - bind_socket, err := zmq.NewSocket(zmq.PULL) - if checkErr(err) { - return 0 - } - defer func() { - err := bind_socket.Close() - checkErr(err) - }() - - err = bind_socket.SetRcvhwm(recv_hwm) - if checkErr(err) { - return 0 - } - - err = bind_socket.Bind("inproc://a") - if checkErr(err) { - return 0 - } - - // Now receive all sent messages - recv_count := 0 - for { - _, err := bind_socket.Recv(zmq.DONTWAIT) - if err != nil { - fmt.Println("Recv:", err) - break - } - recv_count++ - } - fmt.Println("send_count == recv_count:", send_count == recv_count) - - return send_count - } - - // Default values are 1000 on send and 1000 one receive, so 2000 total - fmt.Println("Default values") - count := test_defaults() - fmt.Println("count:", count) - time.Sleep(100 * time.Millisecond) - - // Infinite send and receive buffer - fmt.Println("\nInfinite send and receive") - count = test_inproc_bind_first(0, 0) - fmt.Println("count:", count) - time.Sleep(100 * time.Millisecond) - count = test_inproc_connect_first(0, 0) - fmt.Println("count:", count) - time.Sleep(100 * time.Millisecond) - - // Infinite send buffer - fmt.Println("\nInfinite send buffer") - count = test_inproc_bind_first(1, 0) - fmt.Println("count:", count) - time.Sleep(100 * time.Millisecond) - count = test_inproc_connect_first(1, 0) - fmt.Println("count:", count) - time.Sleep(100 * time.Millisecond) - - // Infinite receive buffer - fmt.Println("\nInfinite receive buffer") - count = test_inproc_bind_first(0, 1) - fmt.Println("count:", count) - time.Sleep(100 * time.Millisecond) - count = test_inproc_connect_first(0, 1) - fmt.Println("count:", count) - time.Sleep(100 * time.Millisecond) - - // Send and recv buffers hwm 1, so total that can be queued is 2 - fmt.Println("\nSend and recv buffers hwm 1") - count = test_inproc_bind_first(1, 1) - fmt.Println("count:", count) - time.Sleep(100 * time.Millisecond) - count = test_inproc_connect_first(1, 1) - fmt.Println("count:", count) - time.Sleep(100 * time.Millisecond) - - // Send hwm of 1, send before bind so total that can be queued is 1 - fmt.Println("\nSend hwm of 1, send before bind") - count = test_inproc_connect_and_close_first(1, 0) - fmt.Println("count:", count) - time.Sleep(100 * time.Millisecond) - - fmt.Println("\nDone") - // Output: - // Default values - // Send: resource temporarily unavailable - // Recv: resource temporarily unavailable - // send_count == recv_count: true - // count: 2000 - // - // Infinite send and receive - // Recv: resource temporarily unavailable - // send_count == recv_count: true - // count: 10000 - // Recv: resource temporarily unavailable - // send_count == recv_count: true - // count: 10000 - // - // Infinite send buffer - // Recv: resource temporarily unavailable - // send_count == recv_count: true - // count: 10000 - // Recv: resource temporarily unavailable - // send_count == recv_count: true - // count: 10000 - // - // Infinite receive buffer - // Recv: resource temporarily unavailable - // send_count == recv_count: true - // count: 10000 - // Recv: resource temporarily unavailable - // send_count == recv_count: true - // count: 10000 - // - // Send and recv buffers hwm 1 - // Send: resource temporarily unavailable - // Recv: resource temporarily unavailable - // send_count == recv_count: true - // count: 2 - // Send: resource temporarily unavailable - // Recv: resource temporarily unavailable - // send_count == recv_count: true - // count: 2 - // - // Send hwm of 1, send before bind - // Send: resource temporarily unavailable - // Recv: resource temporarily unavailable - // send_count == recv_count: true - // count: 1 - // - // Done -} - -/* - -func Example_test_immediate() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_inproc_connect() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_invalid_rep() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_iov() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_issue_566() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_last_endpoint() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_linger() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_monitor() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_msg_flags() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_pair_inproc() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_pair_ipc() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_pair_tcp() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_probe_router() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_req_correlate() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_req_relaxed() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_reqrep_device() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_reqrep_inproc() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_reqrep_ipc() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_reqrep_tcp() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_router_mandatory() { - - fmt.Println("Done") - // Output: - // Done -} - -*/ - -func Example_test_security_curve() { - - time.Sleep(100 * time.Millisecond) - - // Generate new keypairs for this test - client_public, client_secret, err := zmq.NewCurveKeypair() - if checkErr(err) { - return - } - server_public, server_secret, err := zmq.NewCurveKeypair() - if checkErr(err) { - return - } - - handler, err := zmq.NewSocket(zmq.REP) - if checkErr(err) { - return - } - err = handler.Bind("inproc://zeromq.zap.01") - if checkErr(err) { - return - } - - doHandler := func(state zmq.State) error { - msg, err := handler.RecvMessage(0) - if err != nil { - return err // Terminating - } - version := msg[0] - sequence := msg[1] - // domain := msg[2] - // address := msg[3] - identity := msg[4] - mechanism := msg[5] - client_key := msg[6] - client_key_text := zmq.Z85encode(client_key) - - if version != "1.0" { - return errors.New("version != 1.0") - } - if mechanism != "CURVE" { - return errors.New("mechanism != CURVE") - } - if identity != "IDENT" { - return errors.New("identity != IDENT") - } - - if client_key_text == client_public { - handler.SendMessage(version, sequence, "200", "OK", "anonymous", "") - } else { - handler.SendMessage(version, sequence, "400", "Invalid client public key", "", "") - } - return nil - } - - doQuit := func(i interface{}) error { - err := handler.Close() - checkErr(err) - fmt.Println("Handler closed") - return errors.New("Quit") - } - quit := make(chan interface{}) - - reactor := zmq.NewReactor() - reactor.AddSocket(handler, zmq.POLLIN, doHandler) - reactor.AddChannel(quit, 0, doQuit) - go func() { - reactor.Run(100 * time.Millisecond) - fmt.Println("Reactor finished") - quit <- true - }() - defer func() { - quit <- true - <-quit - close(quit) - }() - - // Server socket will accept connections - server, err := zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - err = server.SetCurveServer(1) - if checkErr(err) { - return - } - err = server.SetCurveSecretkey(server_secret) - if checkErr(err) { - return - } - err = server.SetIdentity("IDENT") - if checkErr(err) { - return - } - server.Bind("tcp://127.0.0.1:9998") - if checkErr(err) { - return - } - - err = server.SetRcvtimeo(time.Second) - if checkErr(err) { - return - } - - // Check CURVE security with valid credentials - client, err := zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - err = client.SetCurveServerkey(server_public) - if checkErr(err) { - return - } - err = client.SetCurvePublickey(client_public) - if checkErr(err) { - return - } - err = client.SetCurveSecretkey(client_secret) - if checkErr(err) { - return - } - err = client.Connect("tcp://127.0.0.1:9998") - if checkErr(err) { - return - } - bounce(server, client) - err = client.Close() - if checkErr(err) { - return - } - - time.Sleep(100 * time.Millisecond) - - // Check CURVE security with a garbage server key - // This will be caught by the curve_server class, not passed to ZAP - garbage_key := "0000111122223333444455556666777788889999" - client, err = zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - err = client.SetCurveServerkey(garbage_key) - if checkErr(err) { - return - } - err = client.SetCurvePublickey(client_public) - if checkErr(err) { - return - } - err = client.SetCurveSecretkey(client_secret) - if checkErr(err) { - return - } - err = client.Connect("tcp://127.0.0.1:9998") - if checkErr(err) { - return - } - err = client.SetRcvtimeo(time.Second) - if checkErr(err) { - return - } - bounce(server, client) - client.SetLinger(0) - err = client.Close() - if checkErr(err) { - return - } - - time.Sleep(100 * time.Millisecond) - - // Check CURVE security with a garbage client secret key - // This will be caught by the curve_server class, not passed to ZAP - client, err = zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - err = client.SetCurveServerkey(server_public) - if checkErr(err) { - return - } - err = client.SetCurvePublickey(garbage_key) - if checkErr(err) { - return - } - err = client.SetCurveSecretkey(client_secret) - if checkErr(err) { - return - } - err = client.Connect("tcp://127.0.0.1:9998") - if checkErr(err) { - return - } - err = client.SetRcvtimeo(time.Second) - if checkErr(err) { - return - } - bounce(server, client) - client.SetLinger(0) - err = client.Close() - if checkErr(err) { - return - } - - time.Sleep(100 * time.Millisecond) - - // Check CURVE security with a garbage client secret key - // This will be caught by the curve_server class, not passed to ZAP - client, err = zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - err = client.SetCurveServerkey(server_public) - if checkErr(err) { - return - } - err = client.SetCurvePublickey(client_public) - if checkErr(err) { - return - } - err = client.SetCurveSecretkey(garbage_key) - if checkErr(err) { - return - } - err = client.Connect("tcp://127.0.0.1:9998") - if checkErr(err) { - return - } - err = client.SetRcvtimeo(time.Second) - if checkErr(err) { - return - } - bounce(server, client) - client.SetLinger(0) - err = client.Close() - if checkErr(err) { - return - } - - time.Sleep(100 * time.Millisecond) - - // Check CURVE security with bogus client credentials - // This must be caught by the ZAP handler - - bogus_public, bogus_secret, _ := zmq.NewCurveKeypair() - client, err = zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - err = client.SetCurveServerkey(server_public) - if checkErr(err) { - return - } - err = client.SetCurvePublickey(bogus_public) - if checkErr(err) { - return - } - err = client.SetCurveSecretkey(bogus_secret) - if checkErr(err) { - return - } - err = client.Connect("tcp://127.0.0.1:9998") - if checkErr(err) { - return - } - err = client.SetRcvtimeo(time.Second) - if checkErr(err) { - return - } - bounce(server, client) - client.SetLinger(0) - err = client.Close() - if checkErr(err) { - return - } - - // Shutdown - err = server.Close() - checkErr(err) - - fmt.Println("Done") - // Output: - // resource temporarily unavailable - // resource temporarily unavailable - // resource temporarily unavailable - // resource temporarily unavailable - // Done - // Handler closed - // Reactor finished -} - -func Example_test_security_null() { - - time.Sleep(100 * time.Millisecond) - - handler, err := zmq.NewSocket(zmq.REP) - if checkErr(err) { - return - } - err = handler.Bind("inproc://zeromq.zap.01") - if checkErr(err) { - return - } - - doHandler := func(state zmq.State) error { - msg, err := handler.RecvMessage(0) - if err != nil { - return err // Terminating - } - version := msg[0] - sequence := msg[1] - domain := msg[2] - // address := msg[3] - // identity := msg[4] - mechanism := msg[5] - - if version != "1.0" { - return errors.New("version != 1.0") - } - if mechanism != "NULL" { - return errors.New("mechanism != NULL") - } - - if domain == "TEST" { - handler.SendMessage(version, sequence, "200", "OK", "anonymous", "") - } else { - handler.SendMessage(version, sequence, "400", "BAD DOMAIN", "", "") - } - return nil - } - - doQuit := func(i interface{}) error { - err := handler.Close() - checkErr(err) - fmt.Println("Handler closed") - return errors.New("Quit") - } - quit := make(chan interface{}) - - reactor := zmq.NewReactor() - reactor.AddSocket(handler, zmq.POLLIN, doHandler) - reactor.AddChannel(quit, 0, doQuit) - go func() { - reactor.Run(100 * time.Millisecond) - fmt.Println("Reactor finished") - quit <- true - }() - defer func() { - quit <- true - <-quit - close(quit) - }() - - // We bounce between a binding server and a connecting client - server, err := zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - client, err := zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - - // We first test client/server with no ZAP domain - // Libzmq does not call our ZAP handler, the connect must succeed - err = server.Bind("tcp://127.0.0.1:9000") - if checkErr(err) { - return - } - err = client.Connect("tcp://127.0.0.1:9000") - if checkErr(err) { - return - } - bounce(server, client) - server.Unbind("tcp://127.0.0.1:9000") - client.Disconnect("tcp://127.0.0.1:9000") - - // Now define a ZAP domain for the server; this enables - // authentication. We're using the wrong domain so this test - // must fail. - err = server.SetZapDomain("WRONG") - if checkErr(err) { - return - } - err = server.Bind("tcp://127.0.0.1:9001") - if checkErr(err) { - return - } - err = client.Connect("tcp://127.0.0.1:9001") - if checkErr(err) { - return - } - err = client.SetRcvtimeo(time.Second) - if checkErr(err) { - return - } - err = server.SetRcvtimeo(time.Second) - if checkErr(err) { - return - } - bounce(server, client) - server.Unbind("tcp://127.0.0.1:9001") - client.Disconnect("tcp://127.0.0.1:9001") - - // Now use the right domain, the test must pass - err = server.SetZapDomain("TEST") - if checkErr(err) { - return - } - err = server.Bind("tcp://127.0.0.1:9002") - if checkErr(err) { - return - } - err = client.Connect("tcp://127.0.0.1:9002") - if checkErr(err) { - return - } - bounce(server, client) - server.Unbind("tcp://127.0.0.1:9002") - client.Disconnect("tcp://127.0.0.1:9002") - - err = client.Close() - checkErr(err) - err = server.Close() - checkErr(err) - - fmt.Println("Done") - // Output: - // resource temporarily unavailable - // Done - // Handler closed - // Reactor finished -} - -func Example_test_security_plain() { - - time.Sleep(100 * time.Millisecond) - - handler, err := zmq.NewSocket(zmq.REP) - if checkErr(err) { - return - } - err = handler.Bind("inproc://zeromq.zap.01") - if checkErr(err) { - return - } - - doHandler := func(state zmq.State) error { - msg, err := handler.RecvMessage(0) - if err != nil { - return err // Terminating - } - version := msg[0] - sequence := msg[1] - // domain := msg[2] - // address := msg[3] - identity := msg[4] - mechanism := msg[5] - username := msg[6] - password := msg[7] - - if version != "1.0" { - return errors.New("version != 1.0") - } - if mechanism != "PLAIN" { - return errors.New("mechanism != PLAIN") - } - if identity != "IDENT" { - return errors.New("identity != IDENT") - } - - if username == "admin" && password == "password" { - handler.SendMessage(version, sequence, "200", "OK", "anonymous", "") - } else { - handler.SendMessage(version, sequence, "400", "Invalid username or password", "", "") - } - return nil - } - - doQuit := func(i interface{}) error { - err := handler.Close() - checkErr(err) - fmt.Println("Handler closed") - return errors.New("Quit") - } - quit := make(chan interface{}) - - reactor := zmq.NewReactor() - reactor.AddSocket(handler, zmq.POLLIN, doHandler) - reactor.AddChannel(quit, 0, doQuit) - go func() { - reactor.Run(100 * time.Millisecond) - fmt.Println("Reactor finished") - quit <- true - }() - defer func() { - quit <- true - <-quit - close(quit) - }() - - // Server socket will accept connections - server, err := zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - err = server.SetIdentity("IDENT") - if checkErr(err) { - return - } - err = server.SetPlainServer(1) - if checkErr(err) { - return - } - err = server.Bind("tcp://127.0.0.1:9998") - if checkErr(err) { - return - } - - // Check PLAIN security with correct username/password - client, err := zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - err = client.SetPlainUsername("admin") - if checkErr(err) { - return - } - err = client.SetPlainPassword("password") - if checkErr(err) { - return - } - err = client.Connect("tcp://127.0.0.1:9998") - if checkErr(err) { - return - } - bounce(server, client) - err = client.Close() - if checkErr(err) { - return - } - - // Check PLAIN security with badly configured client (as_server) - // This will be caught by the plain_server class, not passed to ZAP - client, err = zmq.NewSocket(zmq.DEALER) - if checkErr(err) { - return - } - client.SetPlainServer(1) - if checkErr(err) { - return - } - err = client.Connect("tcp://127.0.0.1:9998") - if checkErr(err) { - return - } - err = client.SetRcvtimeo(time.Second) - if checkErr(err) { - return - } - err = server.SetRcvtimeo(time.Second) - if checkErr(err) { - return - } - bounce(server, client) - client.SetLinger(0) - err = client.Close() - if checkErr(err) { - return - } - - err = server.Close() - checkErr(err) - - fmt.Println("Done") - // Output: - // resource temporarily unavailable - // Done - // Handler closed - // Reactor finished - -} - -/* - -func Example_test_shutdown_stress() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_spec_dealer() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_spec_pushpull() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_spec_rep() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_spec_req() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_spec_router() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_stream() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_sub_forward() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_system() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_term_endpoint() { - - fmt.Println("Done") - // Output: - // Done -} - -func Example_test_timeo() { - - fmt.Println("Done") - // Output: - // Done -} - -*/ - -func bounce(server, client *zmq.Socket) { - - content := "12345678ABCDEFGH12345678abcdefgh" - - // Send message from client to server - rc, err := client.Send(content, zmq.SNDMORE|zmq.DONTWAIT) - if checkErr0(err) { - return - } - if rc != 32 { - checkErr0(errors.New("rc != 32")) - } - - rc, err = client.Send(content, zmq.DONTWAIT) - if checkErr0(err) { - return - } - if rc != 32 { - checkErr0(errors.New("rc != 32")) - } - - // Receive message at server side - msg, err := server.Recv(0) - if checkErr0(err) { - return - } - - // Check that message is still the same - if msg != content { - checkErr0(errors.New(fmt.Sprintf("%q != %q", msg, content))) - } - - rcvmore, err := server.GetRcvmore() - if checkErr0(err) { - return - } - if !rcvmore { - checkErr0(errors.New(fmt.Sprint("rcvmore ==", rcvmore))) - return - } - - // Receive message at server side - msg, err = server.Recv(0) - if checkErr0(err) { - return - } - - // Check that message is still the same - if msg != content { - checkErr0(errors.New(fmt.Sprintf("%q != %q", msg, content))) - } - - rcvmore, err = server.GetRcvmore() - if checkErr0(err) { - return - } - if rcvmore { - checkErr0(errors.New(fmt.Sprint("rcvmore == ", rcvmore))) - return - } - - // The same, from server back to client - - // Send message from server to client - rc, err = server.Send(content, zmq.SNDMORE) - if checkErr0(err) { - return - } - if rc != 32 { - checkErr0(errors.New("rc != 32")) - } - - rc, err = server.Send(content, 0) - if checkErr0(err) { - return - } - if rc != 32 { - checkErr0(errors.New("rc != 32")) - } - - // Receive message at client side - msg, err = client.Recv(0) - if checkErr0(err) { - return - } - - // Check that message is still the same - if msg != content { - checkErr0(errors.New(fmt.Sprintf("%q != %q", msg, content))) - } - - rcvmore, err = client.GetRcvmore() - if checkErr0(err) { - return - } - if !rcvmore { - checkErr0(errors.New(fmt.Sprint("rcvmore ==", rcvmore))) - return - } - - // Receive message at client side - msg, err = client.Recv(0) - if checkErr0(err) { - return - } - - // Check that message is still the same - if msg != content { - checkErr0(errors.New(fmt.Sprintf("%q != %q", msg, content))) - } - - rcvmore, err = client.GetRcvmore() - if checkErr0(err) { - return - } - if rcvmore { - checkErr0(errors.New(fmt.Sprint("rcvmore == ", rcvmore))) - return - } - -} - -func checkErr0(err error) bool { - if err != nil { - fmt.Println(err) - return true - } - return false -} - -func checkErr(err error) bool { - if err != nil { - _, filename, lineno, ok := runtime.Caller(1) - if ok { - fmt.Printf("%v:%v: %v\n", filename, lineno, err) - } else { - fmt.Println(err) - } - return true - } - return false -} diff --git a/cmd/cascades/library.go b/cmd/cascades/library.go index 89bd886..82facaa 100644 --- a/cmd/cascades/library.go +++ b/cmd/cascades/library.go @@ -12,7 +12,7 @@ import ( "github.com/cascades-fbp/cascades/graph" "github.com/cascades-fbp/cascades/library" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/codegangsta/cli" + "github.com/codegangsta/cli" ) // Implements catalog updating command diff --git a/cmd/cascades/main.go b/cmd/cascades/main.go index b39a4ac..70f85cb 100644 --- a/cmd/cascades/main.go +++ b/cmd/cascades/main.go @@ -3,7 +3,7 @@ package main import ( "os" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/codegangsta/cli" + "github.com/codegangsta/cli" ) func main() { diff --git a/cmd/cascades/run.go b/cmd/cascades/run.go index 3a6101b..5853a5e 100644 --- a/cmd/cascades/run.go +++ b/cmd/cascades/run.go @@ -9,8 +9,8 @@ import ( "github.com/cascades-fbp/cascades/library" "github.com/cascades-fbp/cascades/runtime" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/codegangsta/cli" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + "github.com/codegangsta/cli" + zmq "github.com/pebbe/zmq4" ) func run(c *cli.Context) { diff --git a/cmd/cascades/serve.go b/cmd/cascades/serve.go index c82ff68..98783ad 100644 --- a/cmd/cascades/serve.go +++ b/cmd/cascades/serve.go @@ -6,7 +6,7 @@ import ( "os/signal" "github.com/cascades-fbp/cascades/server" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/codegangsta/cli" + "github.com/codegangsta/cli" ) func serve(c *cli.Context) { diff --git a/components/core/console/main.go b/components/core/console/main.go index 54ced7d..cb089cf 100644 --- a/components/core/console/main.go +++ b/components/core/console/main.go @@ -9,7 +9,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/core/delay/main.go b/components/core/delay/main.go index 65cadbf..e716be2 100644 --- a/components/core/delay/main.go +++ b/components/core/delay/main.go @@ -10,7 +10,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/core/drop/main.go b/components/core/drop/main.go index 7fd78b1..410dca4 100644 --- a/components/core/drop/main.go +++ b/components/core/drop/main.go @@ -9,7 +9,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/core/exec/main.go b/components/core/exec/main.go index b9131f1..453952e 100644 --- a/components/core/exec/main.go +++ b/components/core/exec/main.go @@ -10,7 +10,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/core/joiner/main.go b/components/core/joiner/main.go index f32e091..74bfdf3 100644 --- a/components/core/joiner/main.go +++ b/components/core/joiner/main.go @@ -10,7 +10,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/core/passthru/main.go b/components/core/passthru/main.go index d749c23..412239c 100644 --- a/components/core/passthru/main.go +++ b/components/core/passthru/main.go @@ -9,7 +9,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/core/readfile/main.go b/components/core/readfile/main.go index 1545f09..663f359 100644 --- a/components/core/readfile/main.go +++ b/components/core/readfile/main.go @@ -10,7 +10,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/core/splitter/main.go b/components/core/splitter/main.go index 0af04df..87737ae 100644 --- a/components/core/splitter/main.go +++ b/components/core/splitter/main.go @@ -10,7 +10,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/core/submatch/main.go b/components/core/submatch/main.go index d2b5c76..8175d85 100644 --- a/components/core/submatch/main.go +++ b/components/core/submatch/main.go @@ -11,7 +11,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/core/switch/main.go b/components/core/switch/main.go index e45298a..1250802 100644 --- a/components/core/switch/main.go +++ b/components/core/switch/main.go @@ -10,7 +10,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/core/template/main.go b/components/core/template/main.go index 26c5dd1..6d7f008 100644 --- a/components/core/template/main.go +++ b/components/core/template/main.go @@ -12,7 +12,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/core/ticker/main.go b/components/core/ticker/main.go index 0aa437b..a532ce5 100644 --- a/components/core/ticker/main.go +++ b/components/core/ticker/main.go @@ -10,7 +10,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/debug/crasher/main.go b/components/debug/crasher/main.go index 532b323..9a28c6b 100644 --- a/components/debug/crasher/main.go +++ b/components/debug/crasher/main.go @@ -10,7 +10,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/debug/oneshot/main.go b/components/debug/oneshot/main.go index e7e7491..c419c67 100644 --- a/components/debug/oneshot/main.go +++ b/components/debug/oneshot/main.go @@ -9,7 +9,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/fs/walk/main.go b/components/fs/walk/main.go index 0422339..b854161 100644 --- a/components/fs/walk/main.go +++ b/components/fs/walk/main.go @@ -10,7 +10,7 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/fs/watchdog/main.go b/components/fs/watchdog/main.go index 43bcee0..1f02f16 100644 --- a/components/fs/watchdog/main.go +++ b/components/fs/watchdog/main.go @@ -10,8 +10,8 @@ import ( "github.com/cascades-fbp/cascades/components/utils" "github.com/cascades-fbp/cascades/runtime" - "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/howeyc/fsnotify" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + "github.com/howeyc/fsnotify" + zmq "github.com/pebbe/zmq4" ) var ( diff --git a/components/utils/zmq.go b/components/utils/zmq.go index a57fe58..e109c82 100644 --- a/components/utils/zmq.go +++ b/components/utils/zmq.go @@ -4,7 +4,7 @@ import ( "fmt" "os" - zmq "github.com/cascades-fbp/cascades/Godeps/_workspace/src/github.com/pebbe/zmq4" + zmq "github.com/pebbe/zmq4" ) // Print the error message if err is not nil & exist with status code 1