Repository: qpid-proton Updated Branches: refs/heads/cjansen-cpp-client 8074793b8 -> 7bca703a9
PROTON-865: Remove .go examples added in error. Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/7bca703a Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/7bca703a Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/7bca703a Branch: refs/heads/cjansen-cpp-client Commit: 7bca703a9daf4a37f93e0b748cd1bcc8b62b6f6b Parents: 8074793 Author: Alan Conway <[email protected]> Authored: Fri Jun 5 15:37:56 2015 -0400 Committer: Alan Conway <[email protected]> Committed: Fri Jun 5 15:38:30 2015 -0400 ---------------------------------------------------------------------- examples/go/CMakeLists.txt | 29 ---- examples/go/README.md | 69 --------- examples/go/event/broker.go | 255 ------------------------------- examples/go/example_test.go | 284 ----------------------------------- examples/go/receive.go | 176 ---------------------- examples/go/send.go | 158 ------------------- proton-c/bindings/cpp/README.md | 3 +- 7 files changed, 1 insertion(+), 973 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/7bca703a/examples/go/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/examples/go/CMakeLists.txt b/examples/go/CMakeLists.txt deleted file mode 100644 index 464ed7c..0000000 --- a/examples/go/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -# FIXME aconway 2015-05-20: -# - use proton build for Go includes & libs. -# - pre-build go libraries? Respect user GOPATH? - -if(BUILD_GO) - add_test( - NAME go_example_test - COMMAND ${GO_TEST} example_test.go -rpath ${CMAKE_BINARY_DIR}/proton-c - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) -endif() http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/7bca703a/examples/go/README.md ---------------------------------------------------------------------- diff --git a/examples/go/README.md b/examples/go/README.md deleted file mode 100644 index 719a3d1..0000000 --- a/examples/go/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# Go examples for proton - -The Go support for proton consists of 3 packages: - -- proton: converts AMQP messages and data types to and from Go data types. -- proton/messaging: easy-to-use, concurrent API for messaging clients and servers. -- proton/event: full low-level access to the proton engine. - -Most applications should use the proton/messaging API. proton/event is for -applications that need low-level access to the proton engine. proton/messaging -itself is implemented using proton/event. - -## proton/messaging examples - -- [receive.go](receive.go) receive from many connections concurrently. -- [send.go](send.go) send to many connections concurrently. - -## proton/event examples - -- [broker.go](event/broker.go) simple mini-broker, queues are created automatically. - -## Running the examples - -Proton needs to be installed in a standard place such as `/usr` or `/usr/local`. -(in future the examples will be able to use the local proton build) - -Set your environment: - - export GOPATH=<path-to-proton-checkout>/proton-c/bindings/go - -You can run the examples directly from source with - - go run <program>.go - -This is a little slow (a couple of seconds) as it compiles the program and runs it in one step. -You can compile the program first and then run the executable to avoid the delay: - - go build <program>.go - ./<program> - -All the examples take a `-h` flag to show usage information, see comments in the example -source for more details. - -## Example of running the examples. - -First start the broker: - - go run event/broker.go - -Send messages concurrently to queues "foo" and "bar", 10 messages to each queue: - - go run go/send.go -count 10 localhost:/foo localhost:/bar - -Receive messages concurrently from "foo" and "bar". Note -count 20 for 10 messages each on 2 queues: - - go run go/receive.go -count 20 localhost:/foo localhost:/bar - -The broker and clients use the amqp port on the local host by default, to use a -different address use the `-addr host:port` flag. - -You can mix it up by running the Go clients with the python broker: - - python ../python/broker.py - -Or use the Go broker and the python clients: - - python ../python/simple_send.py - python ../python/simple_recv.py`. - http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/7bca703a/examples/go/event/broker.go ---------------------------------------------------------------------- diff --git a/examples/go/event/broker.go b/examples/go/event/broker.go deleted file mode 100644 index 9720843..0000000 --- a/examples/go/event/broker.go +++ /dev/null @@ -1,255 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -// -// This is a simple AMQP broker implemented using the event-handler interface. -// -// It maintains a set of named in-memory queues of messages. Clients can send -// messages to queues or subscribe to receive messages from them. -// -// - -package main - -import ( - "container/list" - "flag" - "fmt" - "io" - "io/ioutil" - "log" - "net" - "os" - "path" - "qpid.apache.org/proton" - "qpid.apache.org/proton/event" - "sync" -) - -// Command-line flags -var addr = flag.String("addr", ":amqp", "Listening address") -var verbose = flag.Int("verbose", 1, "Output level, 0 means none, higher means more") -var full = flag.Bool("full", false, "Print full message not just body.") - -func main() { - flag.Usage = func() { - fmt.Fprintf(os.Stderr, ` -Usage: %s -A simple broker-like demo. Queues are created automatically for sender or receiver addrsses. -`, os.Args[0]) - flag.PrintDefaults() - } - flag.Parse() - b := newBroker() - err := b.listen(*addr) - fatalIf(err) -} - -// queue is a structure representing a queue. -type queue struct { - name string // Name of queue - messages *list.List // List of event.Message - consumers map[event.Link]bool // Set of consumer links -} - -type logLink event.Link // Wrapper to print links in format for logging - -func (ll logLink) String() string { - l := event.Link(ll) - return fmt.Sprintf("%s[%p]", l.Name(), l.Session().Connection().Pump()) -} - -func (q *queue) subscribe(link event.Link) { - debug.Printf("link %s subscribed to queue %s", logLink(link), q.name) - q.consumers[link] = true -} - -func (q *queue) unsubscribe(link event.Link) { - debug.Printf("link %s unsubscribed from queue %s", logLink(link), q.name) - delete(q.consumers, link) -} - -func (q *queue) empty() bool { - return len(q.consumers) == 0 && q.messages.Len() == 0 -} - -func (q *queue) push(context *event.Pump, message proton.Message) { - q.messages.PushBack(message) - q.pop(context) -} - -func (q *queue) popTo(context *event.Pump, link event.Link) bool { - if q.messages.Len() != 0 && link.Credit() > 0 { - message := q.messages.Remove(q.messages.Front()).(proton.Message) - debug.Printf("link %s <- queue %s: %s", logLink(link), q.name, formatMessage{message}) - // The first return parameter is an event.Delivery. - // The Deliver can be used to track message status, e.g. so we can re-delver on failure. - // This demo broker doesn't do that. - linkPump := link.Session().Connection().Pump() - if context == linkPump { - if context == nil { - log.Fatal("pop in nil context") - } - link.Send(message) // link is in the current pump, safe to call Send() direct - } else { - linkPump.Inject <- func() { // Inject to link's pump - link.Send(message) // FIXME aconway 2015-05-04: error handlig - } - } - return true - } - return false -} - -func (q *queue) pop(context *event.Pump) (popped bool) { - for c, _ := range q.consumers { - popped = popped || q.popTo(context, c) - } - return -} - -// broker implements event.MessagingHandler and reacts to events by moving messages on or off queues. -type broker struct { - queues map[string]*queue - lock sync.Mutex // FIXME aconway 2015-05-04: un-golike, better broker coming... -} - -func newBroker() *broker { - return &broker{queues: make(map[string]*queue)} -} - -func (b *broker) getQueue(name string) *queue { - q := b.queues[name] - if q == nil { - debug.Printf("Create queue %s", name) - q = &queue{name, list.New(), make(map[event.Link]bool)} - b.queues[name] = q - } - return q -} - -func (b *broker) unsubscribe(l event.Link) { - if l.IsSender() { - q := b.queues[l.RemoteSource().Address()] - if q != nil { - q.unsubscribe(l) - if q.empty() { - debug.Printf("Delete queue %s", q.name) - delete(b.queues, q.name) - } - } - } -} - -func (b *broker) HandleMessagingEvent(t event.MessagingEventType, e event.Event) error { - // FIXME aconway 2015-05-04: locking is un-golike, better example coming soon. - // Needed because the same handler is used for multiple connections concurrently - // and the queue data structures are not thread safe. - b.lock.Lock() - defer b.lock.Unlock() - - switch t { - - case event.MLinkOpening: - if e.Link().IsSender() { - q := b.getQueue(e.Link().RemoteSource().Address()) - q.subscribe(e.Link()) - } - - case event.MLinkDisconnected, event.MLinkClosing: - b.unsubscribe(e.Link()) - - case event.MSendable: - q := b.getQueue(e.Link().RemoteSource().Address()) - q.popTo(e.Connection().Pump(), e.Link()) - - case event.MMessage: - m, err := event.DecodeMessage(e) - fatalIf(err) - qname := e.Link().RemoteTarget().Address() - debug.Printf("link %s -> queue %s: %s", logLink(e.Link()), qname, formatMessage{m}) - b.getQueue(qname).push(e.Connection().Pump(), m) - } - return nil -} - -func (b *broker) listen(addr string) (err error) { - // Use the standard Go "net" package to listen for connections. - info.Printf("Listening on %s", addr) - listener, err := net.Listen("tcp", addr) - if err != nil { - return err - } - defer listener.Close() - for { - conn, err := listener.Accept() - if err != nil { - info.Printf("Accept error: %s", err) - continue - } - pump, err := event.NewPump(conn, event.NewMessagingDelegator(b)) - fatalIf(err) - info.Printf("Accepted %s[%p]", pump, pump) - pump.Server() - go func() { - pump.Run() - if pump.Error == nil { - info.Printf("Closed %s", pump) - } else { - info.Printf("Closed %s: %s", pump, pump.Error) - } - }() - } -} - -// Logging -func logger(prefix string, level int, w io.Writer) *log.Logger { - if *verbose >= level { - return log.New(w, prefix, 0) - } - return log.New(ioutil.Discard, "", 0) -} - -var info, debug *log.Logger - -func init() { - flag.Parse() - name := path.Base(os.Args[0]) - log.SetFlags(0) - log.SetPrefix(fmt.Sprintf("%s: ", name)) // Log errors on stderr. - info = logger(fmt.Sprintf("%s: ", name), 1, os.Stdout) // Log info on stdout. - debug = logger(fmt.Sprintf("%s debug: ", name), 2, os.Stderr) // Log debug on stderr. -} - -// Simple error handling for demo. -func fatalIf(err error) { - if err != nil { - log.Fatal(err) - } -} - -type formatMessage struct{ m proton.Message } - -func (fm formatMessage) String() string { - if *full { - return fmt.Sprintf("%#v", fm.m) - } else { - return fmt.Sprintf("%#v", fm.m.Body()) - } -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/7bca703a/examples/go/example_test.go ---------------------------------------------------------------------- diff --git a/examples/go/example_test.go b/examples/go/example_test.go deleted file mode 100644 index 8879c38..0000000 --- a/examples/go/example_test.go +++ /dev/null @@ -1,284 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -// Tests to verify that example code behaves as expected. -// Run in this directory with `go test example_test.go` -// -package main - -import ( - "bufio" - "bytes" - "flag" - "fmt" - "io" - "io/ioutil" - "math/rand" - "net" - "os" - "os/exec" - "path" - "path/filepath" - "reflect" - "testing" - "time" -) - -func panicIf(err error) { - if err != nil { - panic(err) - } -} - -// A demo broker process -type broker struct { - cmd *exec.Cmd - addr string - runerr chan error - err error -} - -// Try to connect to the broker to verify it is ready, give up after a timeout -func (b *broker) check() error { - dialer := net.Dialer{Deadline: time.Now().Add(time.Second * 10)} - for { - c, err := dialer.Dial("tcp", b.addr) - if err == nil { // Success - c.Close() - return nil - } - select { - case runerr := <-b.runerr: // Broker exited. - return runerr - default: - } - if neterr, ok := err.(net.Error); ok && neterr.Timeout() { // Running but timed out - b.stop() - return fmt.Errorf("timed out waiting for broker") - } - time.Sleep(time.Second / 10) - } -} - -// Start the demo broker, wait till it is listening on *addr. No-op if already started. -func (b *broker) start() error { - if b.cmd == nil { // Not already started - // FIXME aconway 2015-04-30: better way to pick/configure a broker port. - b.addr = fmt.Sprintf("127.0.0.1:%d", rand.Intn(10000)+10000) - b.cmd = exampleCommand("event_broker", "-addr", b.addr) - b.runerr = make(chan error) - b.cmd.Stderr, b.cmd.Stdout = os.Stderr, os.Stdout - go func() { - b.runerr <- b.cmd.Run() - }() - b.err = b.check() - } - return b.err -} - -func (b *broker) stop() { - if b != nil && b.cmd != nil { - b.cmd.Process.Kill() - b.cmd.Wait() - } -} - -func checkEqual(want interface{}, got interface{}) error { - if reflect.DeepEqual(want, got) { - return nil - } - return fmt.Errorf("%#v != %#v", want, got) -} - -// runCommand returns an exec.Cmd to run an example. -func exampleCommand(prog string, arg ...string) *exec.Cmd { - build(prog + ".go") - args := []string{} - if *debug { - args = append(args, "-debug=true") - } - args = append(args, arg...) - cmd := exec.Command(exepath(prog), args...) - cmd.Stderr = os.Stderr - return cmd -} - -// Run an example Go program, return the combined output as a string. -func runExample(prog string, arg ...string) (string, error) { - cmd := exampleCommand(prog, arg...) - out, err := cmd.Output() - return string(out), err -} - -func prefix(prefix string, err error) error { - if err != nil { - return fmt.Errorf("%s: %s", prefix, err) - } - return nil -} - -func runExampleWant(want string, prog string, args ...string) error { - out, err := runExample(prog, args...) - if err != nil { - return fmt.Errorf("%s failed: %s: %s", prog, err, out) - } - return prefix(prog, checkEqual(want, out)) -} - -func exampleArgs(args ...string) []string { - return append(args, testBroker.addr+"/foo", testBroker.addr+"/bar", testBroker.addr+"/baz") -} - -// Send then receive -func TestExampleSendReceive(t *testing.T) { - if testing.Short() { - t.Skip("Skip demo tests in short mode") - } - testBroker.start() - err := runExampleWant( - "Received all 15 acknowledgements\n", - "send", - exampleArgs("-count", "5")...) - if err != nil { - t.Fatal(err) - } - err = runExampleWant( - "Listening on 3 connections\nReceived 15 messages\n", - "receive", - exampleArgs("-count", "15")...) - if err != nil { - t.Fatal(err) - } -} - -var ready error - -func init() { ready = fmt.Errorf("Ready") } - -// Run receive in a goroutine. -// Send ready on errchan when it is listening. -// Send final error when it is done. -// Returns the Cmd, caller must Wait() -func goReceiveWant(errchan chan<- error, want string, arg ...string) *exec.Cmd { - cmd := exampleCommand("receive", arg...) - go func() { - pipe, err := cmd.StdoutPipe() - if err != nil { - errchan <- err - return - } - out := bufio.NewReader(pipe) - cmd.Start() - line, err := out.ReadString('\n') - if err != nil && err != io.EOF { - errchan <- err - return - } - listening := "Listening on 3 connections\n" - if line != listening { - errchan <- checkEqual(listening, line) - return - } - errchan <- ready - buf := bytes.Buffer{} - io.Copy(&buf, out) // Collect the rest of the output - errchan <- checkEqual(want, buf.String()) - close(errchan) - }() - return cmd -} - -// Start receiver first, wait till it is running, then send. -func TestExampleReceiveSend(t *testing.T) { - if testing.Short() { - t.Skip("Skip demo tests in short mode") - } - testBroker.start() - recvErr := make(chan error) - recvCmd := goReceiveWant(recvErr, - "Received 15 messages\n", - exampleArgs("-count", "15")...) - defer func() { - recvCmd.Process.Kill() - recvCmd.Wait() - }() - if err := <-recvErr; err != ready { // Wait for receiver ready - t.Fatal(err) - } - err := runExampleWant( - "Received all 15 acknowledgements\n", - "send", - exampleArgs("-count", "5")...) - if err != nil { - t.Fatal(err) - } - if err := <-recvErr; err != nil { - t.Fatal(err) - } -} - -func exepath(relative string) string { - if binDir == "" { - panic("bindir not set, cannot run example binaries") - } - return path.Join(binDir, relative) -} - -var testBroker *broker -var binDir, exampleDir string -var built map[string]bool - -func init() { - built = make(map[string]bool) -} - -func build(prog string) { - if !built[prog] { - args := []string{"build"} - if *rpath != "" { - args = append(args, "-ldflags", "-r "+*rpath) - } - args = append(args, path.Join(exampleDir, prog)) - build := exec.Command("go", args...) - build.Dir = binDir - out, err := build.CombinedOutput() - if err != nil { - panic(fmt.Errorf("%v: %s", err, out)) - } - built[prog] = true - } -} - -var rpath = flag.String("rpath", "", "Runtime path for test executables") -var debug = flag.Bool("debug", false, "Debugging output from examples") - -func TestMain(m *testing.M) { - rand.Seed(time.Now().UTC().UnixNano()) - var err error - exampleDir, err = filepath.Abs(".") - panicIf(err) - binDir, err = ioutil.TempDir("", "example_test.go") - panicIf(err) - defer os.Remove(binDir) // Clean up binaries - testBroker = &broker{} // Broker is started on-demand by tests. - testBroker.stop() - status := m.Run() - testBroker.stop() - os.Exit(status) -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/7bca703a/examples/go/receive.go ---------------------------------------------------------------------- diff --git a/examples/go/receive.go b/examples/go/receive.go deleted file mode 100644 index fc1c85a..0000000 --- a/examples/go/receive.go +++ /dev/null @@ -1,176 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -package main - -import ( - "flag" - "fmt" - "io" - "io/ioutil" - "log" - "math" - "net" - "os" - "path" - "qpid.apache.org/proton" - "qpid.apache.org/proton/messaging" - "sync" - "time" -) - -// Command-line flags -var verbose = flag.Int("verbose", 1, "Output level, 0 means none, higher means more") -var count = flag.Int64("count", 0, "Stop after receiving this many messages. 0 means unlimited.") -var timeout = flag.Int64("time", 0, "Stop after this many seconds. 0 means unlimited.") -var full = flag.Bool("full", false, "Print full message not just body.") - -func main() { - // Parse flags and arguments, print usage message on error. - flag.Usage = func() { - fmt.Fprintf(os.Stderr, ` -Usage: %s url [url ...] -Receive messages from all the listed URLs concurrently and print them. -`, os.Args[0]) - flag.PrintDefaults() - } - flag.Parse() - urls := flag.Args() // Non-flag arguments are URLs to receive from - if len(urls) == 0 { - flag.Usage() - fmt.Fprintf(os.Stderr, "No URL provided") - os.Exit(1) - } - duration := time.Duration(*timeout) * time.Second - if duration == 0 { - duration = time.Duration(math.MaxInt64) // Not forever, but 290 years is close enough. - } - if *count == 0 { - *count = math.MaxInt64 - } - - // Create a goroutine for each URL that receives messages and sends them to - // the messages channel. main() receives and prints them. - - messages := make(chan proton.Message) // Channel for messages from goroutines to main() - stop := make(chan struct{}) // Closing this channel means the program is stopping. - - var wait sync.WaitGroup // Used by main() to wait for all goroutines to end. - - wait.Add(len(urls)) // Wait for one goroutine per URL. - - // Arrange to close all connections on exit - connections := make([]*messaging.Connection, len(urls)) - defer func() { - for _, c := range connections { - if c != nil { - c.Close() - } - } - }() - - for i, urlStr := range urls { - debug.Printf("Connecting to %s", urlStr) - go func(urlStr string) { - defer wait.Done() // Notify main() that this goroutine is done. - url, err := proton.ParseURL(urlStr) // Like net/url.Parse() but with AMQP defaults. - fatalIf(err) - - // Open a standard Go net.Conn for the AMQP connection - conn, err := net.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port" - fatalIf(err) - - pc, err := messaging.Connect(conn) // This is our AMQP connection. - fatalIf(err) - connections[i] = pc - - // For convenience a proton.Connection provides a DefaultSession() - // pc.Receiver() is equivalent to pc.DefaultSession().Receiver() - r, err := pc.Receiver(url.Path) - fatalIf(err) - - for { - var m proton.Message - select { // Receive a message or stop. - case m = <-r.Receive: - case <-stop: // The program is stopping. - return - } - select { // Send m to main() or stop - case messages <- m: // Send m to main() - case <-stop: // The program is stopping. - return - } - } - }(urlStr) - } - info.Printf("Listening") - - // time.After() returns a channel that will close when the timeout is up. - timer := time.After(duration) - - // main() prints each message and checks for count or timeout being exceeded. - for i := int64(0); i < *count; i++ { - select { - case m := <-messages: - debug.Print(formatMessage{m}) - case <-timer: // Timeout has expired - i = 0 - } - } - info.Printf("Received %d messages", *count) - close(stop) // Signal all goroutines to stop. - wait.Wait() // Wait for all goroutines to finish. -} - -// Logging -func logger(prefix string, level int, w io.Writer) *log.Logger { - if *verbose >= level { - return log.New(w, prefix, 0) - } - return log.New(ioutil.Discard, "", 0) -} - -var info, debug *log.Logger - -func init() { - flag.Parse() - name := path.Base(os.Args[0]) - log.SetFlags(0) // Use default logger for errors. - log.SetPrefix(fmt.Sprintf("%s: ", name)) // Log errors on stderr. - info = logger(fmt.Sprintf("%s: ", name), 1, os.Stdout) // Log info on stdout. - debug = logger(fmt.Sprintf("%s debug: ", name), 2, os.Stderr) // Log debug on stderr. -} - -// Simple error handling for demo. -func fatalIf(err error) { - if err != nil { - log.Fatal(err) - } -} - -type formatMessage struct{ m proton.Message } - -func (fm formatMessage) String() string { - if *full { - return fmt.Sprintf("%#v", fm.m) - } else { - return fmt.Sprintf("%#v", fm.m.Body()) - } -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/7bca703a/examples/go/send.go ---------------------------------------------------------------------- diff --git a/examples/go/send.go b/examples/go/send.go deleted file mode 100644 index 46603bf..0000000 --- a/examples/go/send.go +++ /dev/null @@ -1,158 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -package main - -import ( - "flag" - "fmt" - "io" - "io/ioutil" - "log" - "math" - "net" - "os" - "path" - "qpid.apache.org/proton" - "qpid.apache.org/proton/messaging" - "sync" -) - -// Command-line flags -var verbose = flag.Int("verbose", 1, "Output level, 0 means none, higher means more") -var count = flag.Int64("count", 1, "Send this may messages per address. 0 means unlimited.") - -// Ack associates an info string with an acknowledgement -type Ack struct { - ack messaging.Acknowledgement - info string -} - -func main() { - // Parse flags and arguments, print usage message on error. - flag.Usage = func() { - fmt.Fprintf(os.Stderr, ` -Usage: %s url [url ...] -Send messages to all the listed URLs concurrently. -To each URL, send the string "path-n" where n is the message number. -`, os.Args[0]) - flag.PrintDefaults() - } - flag.Parse() - urls := flag.Args() // Non-flag arguments are URLs to receive from - if len(urls) == 0 { - flag.Usage() - fmt.Fprintf(os.Stderr, "No URL provided\n") - os.Exit(1) - } - if *count == 0 { - *count = math.MaxInt64 - } - - // Create a channel to receive all the acknowledgements - acks := make(chan Ack) - - // Create a goroutine for each URL that sends messages. - var wait sync.WaitGroup // Used by main() to wait for all goroutines to end. - wait.Add(len(urls)) // Wait for one goroutine per URL. - - // Arrange to close all connections on exit - connections := make([]*messaging.Connection, len(urls)) - defer func() { - for _, c := range connections { - c.Close() - } - }() - - for i, urlStr := range urls { - url, err := proton.ParseURL(urlStr) // Like net/url.Parse() but with AMQP defaults. - fatalIf(err) - debug.Printf("Connecting to %v", url) - - // Open a standard Go net.Conn for the AMQP connection - conn, err := net.Dial("tcp", url.Host) // Note net.URL.Host is actually "host:port" - fatalIf(err) - - pc, err := messaging.Connect(conn) // This is our AMQP connection using conn. - fatalIf(err) - connections[i] = pc - - // Start a goroutine to send to urlStr - go func(urlStr string) { - defer wait.Done() // Notify main() that this goroutine is done. - - // FIXME aconway 2015-04-29: sessions, default sessions, senders... - // Create a sender using the path of the URL as the AMQP target address - s, err := pc.Sender(url.Path) - fatalIf(err) - - for i := int64(0); i < *count; i++ { - m := proton.NewMessage() - body := fmt.Sprintf("%v-%v", url.Path, i) - m.SetBody(body) - ack, err := s.Send(m) - fatalIf(err) - acks <- Ack{ack, body} - } - }(urlStr) - } - - // Wait for all the acknowledgements - expect := int(*count) * len(urls) - debug.Printf("Started senders, expect %v acknowledgements", expect) - for i := 0; i < expect; i++ { - ack, ok := <-acks - if !ok { - info.Fatalf("acks channel closed after only %d acks\n", i) - } - d := <-ack.ack - debug.Printf("acknowledgement[%v] %v", i, ack.info) - if d != messaging.Accepted { - info.Printf("Unexpected disposition %v", d) - } - } - info.Printf("Received all %v acknowledgements", expect) - wait.Wait() // Wait for all goroutines to finish. -} - -// Logging -func logger(prefix string, level int, w io.Writer) *log.Logger { - if *verbose >= level { - return log.New(w, prefix, 0) - } - return log.New(ioutil.Discard, "", 0) -} - -var info, debug *log.Logger - -func init() { - flag.Parse() - name := path.Base(os.Args[0]) - log.SetFlags(0) // Use default logger for errors. - log.SetPrefix(fmt.Sprintf("%s: ", name)) // Log errors on stderr. - info = logger(fmt.Sprintf("%s: ", name), 1, os.Stdout) // Log info on stdout. - debug = logger(fmt.Sprintf("%s debug: ", name), 2, os.Stderr) // Log debug on stderr. -} - -// Simple error handling for demo. -func fatalIf(err error) { - if err != nil { - log.Fatal(err) - } -} http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/7bca703a/proton-c/bindings/cpp/README.md ---------------------------------------------------------------------- diff --git a/proton-c/bindings/cpp/README.md b/proton-c/bindings/cpp/README.md index cf16577..e810afe 100644 --- a/proton-c/bindings/cpp/README.md +++ b/proton-c/bindings/cpp/README.md @@ -1,7 +1,6 @@ # C++ binding for proton. -This is a C++ wrapper for the proton reactor API. -It is very similar to the python wrapper for the same API. +This is a C++ binding for the proton API. There are [examples](../../../examples/cpp/README.md) and the header files have API documentation in doxygen format. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
