This code takes text from the standard input, maps it to a struct (if possible), and creates a JSON string from that.

I'm using a barcode scanner for the input, and I've attempted to use goroutines to ensure that if something goes wrong with the parsing or JSON-marshalling, the program will continue to receive and process input from the scanner.

Am I doing this correctly, and am I doing it in the most effective, efficient, or idiomatic way?

Because all I care about for this post is the concurrency, I've left out all code that parses the input and creates JSON. Additionally, the only thing I do with the JSON right now is print it back out.

Thanks for taking a look at this.

package main

import (

func main() {
    var input string
    for input != "exit" {
        ch := make(chan string)
        quit := make(chan bool)
        go parseInput(input, ch, quit)
        go sendJson(ch, quit)

// Take the input and generate some JSON, then return it along a channel.
func parseInput(input string, ch chan string, quit chan bool) {
    // shoporder.Parse() uses regexp to validate the input, and returns a JSON string.
    son, ok := shoporder.Parse(input)
    if !ok {
        // If the input could not be parsed into JSON, then ignore and shut down
        // both goroutines.
        quit <- true
    ch <- son

// This will eventually send the JSON using websockets, but for now I just
// print it back out.
func sendJson(ch chan string, quit chan bool) {
    select {
    case json := <-ch:
        // For now I just print the JSON.
    case <-quit:
        // I make sure to quit the goroutine, because I'm worried about creating a 
        // bunch that never end and just hang around.  Do I need to do this?

It seems reasonable to start a goroutine for each input, but I'm not sure you need separate goroutines for parsing and sending. After all, one is just waiting for the other to finish. They might as well be the same goroutine. Then you don't need either of the channels because they were just to let these two goroutines communicate.

  • \$\begingroup\$ That's a good point. Nothing can happen in the second goroutine until it receives from the channel. Because of that, there's no reason for it to be separate from the first one. \$\endgroup\$
    – ahuth
    Feb 25 '13 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.